From 4463ef6c980f6b3812b4c2489f7bf840ec976233 Mon Sep 17 00:00:00 2001 From: Donghun Won Date: Fri, 5 Jul 2024 14:30:10 +0900 Subject: [PATCH 001/371] =?UTF-8?q?Chore=20:=20gradle=20=EC=9C=84=EC=B9=98?= =?UTF-8?q?=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/build.gradle b/build.gradle index 964f7521..372e5d9c 100644 --- a/build.gradle +++ b/build.gradle @@ -34,6 +34,10 @@ dependencies { implementation 'org.springframework.boot:spring-boot-starter-data-jpa' implementation 'org.springframework.boot:spring-boot-starter-validation' + compileOnly 'org.projectlombok:lombok' + annotationProcessor 'org.projectlombok:lombok' + testAnnotationProcessor 'org.projectlombok:lombok' + implementation 'org.mapstruct:mapstruct:1.5.5.Final' annotationProcessor 'org.mapstruct:mapstruct-processor:1.5.5.Final' @@ -43,10 +47,6 @@ dependencies { implementation 'org.springframework.cloud:spring-cloud-starter-aws:2.2.6.RELEASE' - compileOnly 'org.projectlombok:lombok' - annotationProcessor 'org.projectlombok:lombok' - testAnnotationProcessor 'org.projectlombok:lombok' - runtimeOnly 'com.mysql:mysql-connector-j' testImplementation 'org.springframework.boot:spring-boot-starter-test' From 09de257ec3804b6e3404656ce30b99bd00e52e84 Mon Sep 17 00:00:00 2001 From: Donghun Won Date: Fri, 5 Jul 2024 14:31:09 +0900 Subject: [PATCH 002/371] =?UTF-8?q?Feat=20:=20oauth=20controller=20?= =?UTF-8?q?=EB=A1=9C=EA=B7=B8=EC=95=84=EC=9B=83,=20=ED=86=A0=ED=81=B0=20?= =?UTF-8?q?=EB=A6=AC=ED=94=84=EB=A0=88=EC=8B=9C=20,=20=EB=A1=9C=EA=B7=B8?= =?UTF-8?q?=EC=9D=B8=20=ED=83=80=EC=9E=85=20=EA=B5=AC=EB=B6=84=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../auth/controller/OauthController.java | 30 +++++++++++++++---- 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/src/main/java/solitour_backend/solitour/auth/controller/OauthController.java b/src/main/java/solitour_backend/solitour/auth/controller/OauthController.java index 3bf0bd8f..52b6da02 100644 --- a/src/main/java/solitour_backend/solitour/auth/controller/OauthController.java +++ b/src/main/java/solitour_backend/solitour/auth/controller/OauthController.java @@ -4,10 +4,14 @@ import lombok.RequiredArgsConstructor; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; +import solitour_backend.solitour.auth.config.Authenticated; +import solitour_backend.solitour.auth.config.AuthenticationPrincipal; import solitour_backend.solitour.auth.service.OauthService; +import solitour_backend.solitour.auth.service.dto.response.AccessTokenResponse; import solitour_backend.solitour.auth.service.dto.response.LoginResponse; import solitour_backend.solitour.auth.service.dto.response.OauthLinkResponse; @@ -20,15 +24,29 @@ public class OauthController { private final OauthService oauthService; - @GetMapping(value = "/login", params = {"redirectUrl"}) - public ResponseEntity access(@RequestParam String redirectUrl) { - OauthLinkResponse response = oauthService.generateAuthUrl(redirectUrl); + @GetMapping(value = "/login", params = {"type", "redirectUrl"}) + public ResponseEntity access(@RequestParam String type,@RequestParam String redirectUrl) { + OauthLinkResponse response = oauthService.generateAuthUrl(type,redirectUrl); return ResponseEntity.ok(response); } - @GetMapping(value = "/login", params = {"code", "redirectUrl"}) - public ResponseEntity login(@RequestParam String code, @RequestParam String redirectUrl) { - LoginResponse loginResponse = oauthService.requestAccessToken(code, redirectUrl); + @GetMapping(value = "/login", params = {"type", "code", "redirectUrl"}) + public ResponseEntity login(@RequestParam String type, @RequestParam String code, @RequestParam String redirectUrl) { + LoginResponse loginResponse = oauthService.requestAccessToken(type, code, redirectUrl); return ResponseEntity.ok(loginResponse); } + + @Authenticated + @PostMapping("/logout") + public ResponseEntity logout(@AuthenticationPrincipal Long memberId) { + oauthService.logout(memberId); + + return ResponseEntity.ok().build(); + } + + @PostMapping("/token/refresh") + public ResponseEntity reissueAccessToken(@AuthenticationPrincipal Long memberId) { + AccessTokenResponse response = oauthService.reissueAccessToken(memberId); + return ResponseEntity.ok(response); + } } From d87e75ede1929ff515eefd849d5bc0ce8efbe31c Mon Sep 17 00:00:00 2001 From: Donghun Won Date: Fri, 5 Jul 2024 14:32:25 +0900 Subject: [PATCH 003/371] =?UTF-8?q?Feat=20:=20oauth=20service=20=EB=A1=9C?= =?UTF-8?q?=EA=B7=B8=EC=9D=B8=20=ED=83=80=EC=9E=85=20=EA=B5=AC=EB=B6=84,?= =?UTF-8?q?=20=20=EB=A1=9C=EA=B7=B8=EC=95=84=EC=9B=83,=20=ED=86=A0?= =?UTF-8?q?=ED=81=B0=20=EB=A6=AC=ED=94=84=EB=A0=88=EC=8B=9C=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../solitour/auth/service/OauthService.java | 102 +++++++++++++----- 1 file changed, 76 insertions(+), 26 deletions(-) diff --git a/src/main/java/solitour_backend/solitour/auth/service/OauthService.java b/src/main/java/solitour_backend/solitour/auth/service/OauthService.java index 901676ed..1a9525f5 100644 --- a/src/main/java/solitour_backend/solitour/auth/service/OauthService.java +++ b/src/main/java/solitour_backend/solitour/auth/service/OauthService.java @@ -1,56 +1,106 @@ package solitour_backend.solitour.auth.service; +import jakarta.security.auth.message.AuthException; +import java.time.LocalDateTime; import java.util.Optional; import lombok.RequiredArgsConstructor; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import solitour_backend.solitour.auth.entity.Token; +import solitour_backend.solitour.auth.service.dto.response.AccessTokenResponse; import solitour_backend.solitour.auth.service.dto.response.LoginResponse; import solitour_backend.solitour.auth.service.dto.response.OauthLinkResponse; import solitour_backend.solitour.auth.support.JwtTokenProvider; +import solitour_backend.solitour.auth.support.google.GoogleProvider; +import solitour_backend.solitour.auth.support.google.dto.GoogleUserResponse; import solitour_backend.solitour.auth.support.kakao.KakaoConnector; import solitour_backend.solitour.auth.support.kakao.KakaoProvider; import solitour_backend.solitour.auth.support.kakao.dto.KakaoUserResponse; import solitour_backend.solitour.user.entity.User; import solitour_backend.solitour.user.entity.UserRepository; +import solitour_backend.solitour.user.user_status.UserStatus; @RequiredArgsConstructor @Service public class OauthService { - private final UserRepository userRepository; - private final JwtTokenProvider jwtTokenProvider; - private final KakaoConnector oauthConnector; - private final KakaoProvider oauthProvider; + private final TokenService tokenService; + private final UserRepository userRepository; + private final JwtTokenProvider jwtTokenProvider; + private final KakaoConnector kakaoConnector; + private final KakaoProvider kakaoProvider; + private final GoogleProvider googleProvider; - public OauthLinkResponse generateAuthUrl(String redirectUrl) { - String oauthLink = oauthProvider.generateAuthUrl(redirectUrl); - return new OauthLinkResponse(oauthLink); - } + public OauthLinkResponse generateAuthUrl(String type, String redirectUrl) { + String oauthLink = getAuthLink(type, redirectUrl); + return new OauthLinkResponse(oauthLink); + } - @Transactional - public LoginResponse requestAccessToken(String code, String redirectUrl) { - KakaoUserResponse response = requestUserInfo(code, redirectUrl); + @Transactional + public LoginResponse requestAccessToken(String type, String code, String redirectUrl) { + KakaoUserResponse response = requestUserInfo(type, code, redirectUrl); - User user = saveUser(response); - String token = jwtTokenProvider.createAccessToken(user.getId()); - String refreshToken = jwtTokenProvider.createRefreshToken(user.getId()); + User user = findOrSaveUser(response); + String token = jwtTokenProvider.createAccessToken(user.getId()); + String refreshToken = jwtTokenProvider.createRefreshToken(user.getId()); - return new LoginResponse(token, refreshToken); - } + tokenService.synchronizeRefreshToken(user, refreshToken); - private KakaoUserResponse requestUserInfo(String code, String redirectUrl) { - ResponseEntity responseEntity = oauthConnector.requestUserInfo(code, redirectUrl); + return new LoginResponse(token, refreshToken); + } - return Optional.ofNullable(responseEntity.getBody()) - .orElseThrow(() -> new RuntimeException("카카오 사용자 정보를 가져오는데 실패했습니다.")); - } + private KakaoUserResponse requestUserInfo(String type, String code, String redirectUrl) { + + ResponseEntity responseEntity = kakaoConnector.requestUserInfo(code, + redirectUrl); + + return Optional.ofNullable(responseEntity.getBody()) + .orElseThrow(() -> new RuntimeException("카카오 사용자 정보를 가져오는데 실패했습니다.")); + } - private User saveUser(KakaoUserResponse response) { - User user = User.builder() - .name(response.getName()) - .build(); - return userRepository.save(user); + private User findOrSaveUser(KakaoUserResponse response) { + String nickname = response.getKakaoAccount().getProfile().getNickName(); + return userRepository.findByNickname(nickname) + .orElseGet(() -> saveUser(response)); + } + + private User saveUser(KakaoUserResponse response) { + User user = User.builder() + .userStatus(UserStatus.ACTIVATE) + .oauthId(String.valueOf(response.getId())) + .provider("kakao") + .isAdmin(false) + .name(response.getKakaoAccount().getName()) + .nickname(response.getKakaoAccount().getProfile().getNickName()) + .age(Integer.valueOf(response.getKakaoAccount().getBirthYear())) + .sex(response.getKakaoAccount().getGender()) + .email(response.getKakaoAccount().getEmail()) + .createdAt(LocalDateTime.now()) + .build(); + return userRepository.save(user); + } + + private String getAuthLink(String type, String redirectUrl) { + return switch (type) { + case "kakao" -> kakaoProvider.generateAuthUrl(redirectUrl); + case "google" -> googleProvider.generateAuthUrl(redirectUrl); + default -> throw new RuntimeException("지원하지 않는 oauth 타입입니다."); + }; + } + + public AccessTokenResponse reissueAccessToken(Long userId) { + boolean isExistMember = userRepository.existsById(userId); + if (!isExistMember) { + throw new RuntimeException("유효하지 않은 토큰입니다."); } + String accessToken = jwtTokenProvider.createAccessToken(userId); + return new AccessTokenResponse(accessToken); + } + + @Transactional + public void logout(Long memberId) { + tokenService.deleteByMemberId(memberId); + } } From 438244518dff3715fb9856a94907150cb1d351ab Mon Sep 17 00:00:00 2001 From: Donghun Won Date: Fri, 5 Jul 2024 14:32:48 +0900 Subject: [PATCH 004/371] Feat : google response dto --- .../support/google/dto/GoogleTokenResponse.java | 16 ++++++++++++++++ .../support/google/dto/GoogleUserResponse.java | 14 ++++++++++++++ 2 files changed, 30 insertions(+) create mode 100644 src/main/java/solitour_backend/solitour/auth/support/google/dto/GoogleTokenResponse.java create mode 100644 src/main/java/solitour_backend/solitour/auth/support/google/dto/GoogleUserResponse.java diff --git a/src/main/java/solitour_backend/solitour/auth/support/google/dto/GoogleTokenResponse.java b/src/main/java/solitour_backend/solitour/auth/support/google/dto/GoogleTokenResponse.java new file mode 100644 index 00000000..b76dcff2 --- /dev/null +++ b/src/main/java/solitour_backend/solitour/auth/support/google/dto/GoogleTokenResponse.java @@ -0,0 +1,16 @@ +package solitour_backend.solitour.auth.support.google.dto; + +import com.fasterxml.jackson.databind.PropertyNamingStrategies; +import com.fasterxml.jackson.databind.annotation.JsonNaming; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class) +@Getter +@NoArgsConstructor +@AllArgsConstructor +public class GoogleTokenResponse { + + private String accessToken; +} diff --git a/src/main/java/solitour_backend/solitour/auth/support/google/dto/GoogleUserResponse.java b/src/main/java/solitour_backend/solitour/auth/support/google/dto/GoogleUserResponse.java new file mode 100644 index 00000000..c2517292 --- /dev/null +++ b/src/main/java/solitour_backend/solitour/auth/support/google/dto/GoogleUserResponse.java @@ -0,0 +1,14 @@ +package solitour_backend.solitour.auth.support.google.dto; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor +@AllArgsConstructor +public class GoogleUserResponse { + + private String name; + private String email; +} From 0c03c31738027d4500f8db3910bf434bd4b968ca Mon Sep 17 00:00:00 2001 From: Donghun Won Date: Fri, 5 Jul 2024 14:33:34 +0900 Subject: [PATCH 005/371] Feat : kakao response dto --- .../support/kakao/dto/KakaoUserResponse.java | 183 +++++++++++++++++- 1 file changed, 179 insertions(+), 4 deletions(-) diff --git a/src/main/java/solitour_backend/solitour/auth/support/kakao/dto/KakaoUserResponse.java b/src/main/java/solitour_backend/solitour/auth/support/kakao/dto/KakaoUserResponse.java index ce15e171..2d35ad6f 100644 --- a/src/main/java/solitour_backend/solitour/auth/support/kakao/dto/KakaoUserResponse.java +++ b/src/main/java/solitour_backend/solitour/auth/support/kakao/dto/KakaoUserResponse.java @@ -1,14 +1,189 @@ package solitour_backend.solitour.auth.support.kakao.dto; -import lombok.AllArgsConstructor; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import java.util.Date; +import java.util.HashMap; +import lombok.Data; import lombok.Getter; import lombok.NoArgsConstructor; @Getter @NoArgsConstructor -@AllArgsConstructor +@JsonIgnoreProperties(ignoreUnknown = true) public class KakaoUserResponse { - private String name; - private String email; + //회원 번호 + @JsonProperty("id") + public Long id; + + //자동 연결 설정을 비활성화한 경우만 존재. + //true : 연결 상태, false : 연결 대기 상태 + @JsonProperty("has_signed_up") + public Boolean hasSignedUp; + + //서비스에 연결 완료된 시각. UTC + @JsonProperty("connected_at") + public Date connectedAt; + + //카카오싱크 간편가입을 통해 로그인한 시각. UTC + @JsonProperty("synched_at") + public Date synchedAt; + + //사용자 프로퍼티 + @JsonProperty("properties") + public HashMap properties; + + //카카오 계정 정보 + @JsonProperty("kakao_account") + public KakaoAccount kakaoAccount; + + //uuid 등 추가 정보 + @JsonProperty("for_partner") + public Partner partner; + + @Getter + @NoArgsConstructor + @JsonIgnoreProperties(ignoreUnknown = true) + public class KakaoAccount { + + //프로필 정보 제공 동의 여부 + @JsonProperty("profile_needs_agreement") + public Boolean isProfileAgree; + + //닉네임 제공 동의 여부 + @JsonProperty("profile_nickname_needs_agreement") + public Boolean isNickNameAgree; + + //프로필 사진 제공 동의 여부 + @JsonProperty("profile_image_needs_agreement") + public Boolean isProfileImageAgree; + + //사용자 프로필 정보 + @JsonProperty("profile") + public Profile profile; + + //이름 제공 동의 여부 + @JsonProperty("name_needs_agreement") + public Boolean isNameAgree; + + //카카오계정 이름 + @JsonProperty("name") + public String name; + + //이메일 제공 동의 여부 + @JsonProperty("email_needs_agreement") + public Boolean isEmailAgree; + + //이메일이 유효 여부 + // true : 유효한 이메일, false : 이메일이 다른 카카오 계정에 사용돼 만료 + @JsonProperty("is_email_valid") + public Boolean isEmailValid; + + //이메일이 인증 여부 + //true : 인증된 이메일, false : 인증되지 않은 이메일 + @JsonProperty("is_email_verified") + public Boolean isEmailVerified; + + //카카오계정 대표 이메일 + @JsonProperty("email") + public String email; + + //연령대 제공 동의 여부 + @JsonProperty("age_range_needs_agreement") + public Boolean isAgeAgree; + + //연령대 + //참고 https://developers.kakao.com/docs/latest/ko/kakaologin/rest-api#req-user-info + @JsonProperty("age_range") + public String ageRange; + + //출생 연도 제공 동의 여부 + @JsonProperty("birthyear_needs_agreement") + public Boolean isBirthYearAgree; + + //출생 연도 (YYYY 형식) + @JsonProperty("birthyear") + public String birthYear; + + //생일 제공 동의 여부 + @JsonProperty("birthday_needs_agreement") + public Boolean isBirthDayAgree; + + //생일 (MMDD 형식) + @JsonProperty("birthday") + public String birthDay; + + //생일 타입 + // SOLAR(양력) 혹은 LUNAR(음력) + @JsonProperty("birthday_type") + public String birthDayType; + + //성별 제공 동의 여부 + @JsonProperty("gender_needs_agreement") + public Boolean isGenderAgree; + + //성별 + @JsonProperty("gender") + public String gender; + + //전화번호 제공 동의 여부 + @JsonProperty("phone_number_needs_agreement") + public Boolean isPhoneNumberAgree; + + //전화번호 + //국내 번호인 경우 +82 00-0000-0000 형식 + @JsonProperty("phone_number") + public String phoneNumber; + + //CI 동의 여부 + @JsonProperty("ci_needs_agreement") + public Boolean isCIAgree; + + //CI, 연계 정보 + @JsonProperty("ci") + public String ci; + + //CI 발급 시각, UTC + @JsonProperty("ci_authenticated_at") + public Date ciCreatedAt; + + @Getter + @NoArgsConstructor + @JsonIgnoreProperties(ignoreUnknown = true) + public class Profile { + + //닉네임 + @JsonProperty("nickname") + public String nickName; + + //프로필 미리보기 이미지 URL + @JsonProperty("thumbnail_image_url") + public String thumbnailImageUrl; + + //프로필 사진 URL + @JsonProperty("profile_image_url") + public String profileImageUrl; + + //프로필 사진 URL 기본 프로필인지 여부 + //true : 기본 프로필, false : 사용자 등록 + @JsonProperty("is_default_image") + public String isDefaultImage; + + //닉네임이 기본 닉네임인지 여부 + //true : 기본 닉네임, false : 사용자 등록 + @JsonProperty("is_default_nickname") + public Boolean isDefaultNickName; + + } + } + + @Getter + @NoArgsConstructor + @JsonIgnoreProperties(ignoreUnknown = true) + public class Partner { + //고유 ID + @JsonProperty("uuid") + public String uuid; + } } From 077e02472cf8b6a92f8c8ed1bdbb53f1a03385f2 Mon Sep 17 00:00:00 2001 From: Donghun Won Date: Fri, 5 Jul 2024 14:35:26 +0900 Subject: [PATCH 006/371] =?UTF-8?q?Refactor=20:=20=EC=9D=B8=EC=9E=90=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 --- .../java/solitour_backend/solitour/auth/entity/Token.java | 5 ++++- .../solitour/auth/entity/TokenRepository.java | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/main/java/solitour_backend/solitour/auth/entity/Token.java b/src/main/java/solitour_backend/solitour/auth/entity/Token.java index 5dd63263..a95e144c 100644 --- a/src/main/java/solitour_backend/solitour/auth/entity/Token.java +++ b/src/main/java/solitour_backend/solitour/auth/entity/Token.java @@ -8,6 +8,8 @@ import jakarta.persistence.Id; import jakarta.persistence.JoinColumn; import jakarta.persistence.OneToOne; +import jakarta.persistence.Table; +import java.time.LocalDateTime; import lombok.AccessLevel; import lombok.Getter; import lombok.NoArgsConstructor; @@ -16,6 +18,7 @@ @Getter @NoArgsConstructor() @Entity +@Table(name = "token") public class Token { @Id @@ -23,7 +26,7 @@ public class Token { private Long id; @OneToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "member_id") + @JoinColumn(name = "user_id") private User user; @Column(nullable = false) diff --git a/src/main/java/solitour_backend/solitour/auth/entity/TokenRepository.java b/src/main/java/solitour_backend/solitour/auth/entity/TokenRepository.java index 03674ed6..7129b51f 100644 --- a/src/main/java/solitour_backend/solitour/auth/entity/TokenRepository.java +++ b/src/main/java/solitour_backend/solitour/auth/entity/TokenRepository.java @@ -10,7 +10,7 @@ public interface TokenRepository extends Repository { Token save(Token token); - Optional findByUserId(Long memberId); + Optional findByUserId(Long userId); @Modifying @Query("delete from Token t where t.user.id = :userId") From ab980121d8cf89b40619cc9983606f6c744abc8a Mon Sep 17 00:00:00 2001 From: Donghun Won Date: Fri, 5 Jul 2024 14:35:58 +0900 Subject: [PATCH 007/371] =?UTF-8?q?Feat=20:=20=EA=B5=AC=EA=B8=80=20?= =?UTF-8?q?=EB=A1=9C=EA=B7=B8=EC=9D=B8=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../solitour/auth/support/OAuth2UserInfo.java | 8 ++ .../auth/support/google/GoogleConnector.java | 81 +++++++++++++++++++ .../auth/support/google/GoogleProvider.java | 53 ++++++++++++ .../auth/support/google/GoogleUserInfo.java | 33 ++++++++ 4 files changed, 175 insertions(+) create mode 100644 src/main/java/solitour_backend/solitour/auth/support/OAuth2UserInfo.java create mode 100644 src/main/java/solitour_backend/solitour/auth/support/google/GoogleConnector.java create mode 100644 src/main/java/solitour_backend/solitour/auth/support/google/GoogleProvider.java create mode 100644 src/main/java/solitour_backend/solitour/auth/support/google/GoogleUserInfo.java diff --git a/src/main/java/solitour_backend/solitour/auth/support/OAuth2UserInfo.java b/src/main/java/solitour_backend/solitour/auth/support/OAuth2UserInfo.java new file mode 100644 index 00000000..2a7fa999 --- /dev/null +++ b/src/main/java/solitour_backend/solitour/auth/support/OAuth2UserInfo.java @@ -0,0 +1,8 @@ +package solitour_backend.solitour.auth.support; + +public interface OAuth2UserInfo { + String getProviderId(); + String getProvider(); + String getEmail(); + String getName(); +} diff --git a/src/main/java/solitour_backend/solitour/auth/support/google/GoogleConnector.java b/src/main/java/solitour_backend/solitour/auth/support/google/GoogleConnector.java new file mode 100644 index 00000000..7adb27c6 --- /dev/null +++ b/src/main/java/solitour_backend/solitour/auth/support/google/GoogleConnector.java @@ -0,0 +1,81 @@ +package solitour_backend.solitour.auth.support.google; + + +import java.util.Collections; +import java.util.Optional; +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Component; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; +import org.springframework.web.client.RestTemplate; +import solitour_backend.solitour.auth.support.google.dto.GoogleTokenResponse; +import solitour_backend.solitour.auth.support.google.dto.GoogleUserResponse; + +@Getter +@RequiredArgsConstructor +@Component +public class GoogleConnector { + + private static final String BEARER_TYPE = "Bearer"; + private static final RestTemplate REST_TEMPLATE = new RestTemplate(); + + private final GoogleProvider provider; + + public ResponseEntity requestUserInfo(String code, String redirectUrl) { + String googleToken = requestAccessToken(code, redirectUrl); + + HttpHeaders headers = new HttpHeaders(); + headers.set("Authorization", String.join(" ", BEARER_TYPE, googleToken)); + HttpEntity entity = new HttpEntity<>(headers); + + return REST_TEMPLATE.exchange(provider.getUserInfoUrl(), HttpMethod.GET, entity, GoogleUserResponse.class); + } + + private String requestAccessToken(String code, String redirectUrl) { + HttpEntity> entity = new HttpEntity<>(createBody(code, redirectUrl), createHeaders()); + + ResponseEntity response = REST_TEMPLATE.postForEntity(provider.getAccessTokenUrl(), + entity, GoogleTokenResponse.class); + + return extractAccessToken(response); + } + + private HttpHeaders createHeaders() { + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED); + headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON)); + return headers; + } + + private MultiValueMap createBody(String code, String redirectUrl) { + MultiValueMap body = new LinkedMultiValueMap<>(); + body.add("code", code); + body.add("client_id", provider.getClientId()); + body.add("client_secret", provider.getClientSecret()); + body.add("redirect_uri", redirectUrl); + body.add("grant_type", provider.getGrantType()); + return body; + } + + private String extractAccessToken(ResponseEntity responseEntity) { +// validateResponseStatusOk(responseEntity.getStatusCode()); + + GoogleTokenResponse response = Optional.ofNullable(responseEntity.getBody()) + .orElseThrow(() -> new RuntimeException("구글 토큰을 가져오는데 실패했습니다.")); + + return response.getAccessToken(); + } + +// private void validateResponseStatusOk(HttpStatus status) { +// if (!status.is2xxSuccessful()) { +// throw new RuntimeException("구글 토큰을 가져오는데 실패했습니다."); +// } +// } +} diff --git a/src/main/java/solitour_backend/solitour/auth/support/google/GoogleProvider.java b/src/main/java/solitour_backend/solitour/auth/support/google/GoogleProvider.java new file mode 100644 index 00000000..a9b7a6e4 --- /dev/null +++ b/src/main/java/solitour_backend/solitour/auth/support/google/GoogleProvider.java @@ -0,0 +1,53 @@ +package solitour_backend.solitour.auth.support.google; + +import java.util.HashMap; +import java.util.Map; +import java.util.stream.Collectors; +import lombok.Getter; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +@Getter +@Component +public class GoogleProvider { + + private final String clientId; + private final String clientSecret; + private final String authUrl; + private final String accessTokenUrl; + private final String userInfoUrl; + private final String grantType; + private final String scope; + + public GoogleProvider(@Value("${oauth2.google.client.id}") String clientId, + @Value("${oauth2.google.client.secret}") String clientSecret, + @Value("${oauth2.google.url.auth}") String authUrl, + @Value("${oauth2.google.url.token}") String accessTokenUrl, + @Value("${oauth2.google.url.userinfo}") String userInfoUrl, + @Value("${oauth2.google.grant-type}") String grantType, + @Value("${oauth2.google.scope}") String scope) { + this.clientId = clientId; + this.clientSecret = clientSecret; + this.authUrl = authUrl; + this.accessTokenUrl = accessTokenUrl; + this.userInfoUrl = userInfoUrl; + this.grantType = grantType; + this.scope = scope; + } + + public String generateAuthUrl(String redirectUrl) { + Map params = new HashMap<>(); + params.put("scope", scope); + params.put("response_type", "code"); + params.put("client_id", clientId); + params.put("redirect_uri", redirectUrl); + return authUrl + "?" + concatParams(params); + } + + private String concatParams(Map params) { + return params.entrySet() + .stream() + .map(entry -> entry.getKey() + "=" + entry.getValue()) + .collect(Collectors.joining("&")); + } +} diff --git a/src/main/java/solitour_backend/solitour/auth/support/google/GoogleUserInfo.java b/src/main/java/solitour_backend/solitour/auth/support/google/GoogleUserInfo.java new file mode 100644 index 00000000..634f38af --- /dev/null +++ b/src/main/java/solitour_backend/solitour/auth/support/google/GoogleUserInfo.java @@ -0,0 +1,33 @@ +package solitour_backend.solitour.auth.support.google; + +import java.util.Map; +import solitour_backend.solitour.auth.support.OAuth2UserInfo; + +public class GoogleUserInfo implements OAuth2UserInfo { + + private Map attributes; + + public GoogleUserInfo(Map attributes) { + this.attributes = attributes; + } + + @Override + public String getProviderId() { + return (String) attributes.get("sub"); + } + + @Override + public String getProvider() { + return "google"; + } + + @Override + public String getEmail() { + return (String) attributes.get("email"); + } + + @Override + public String getName() { + return (String) attributes.get("name"); + } +} From 96bbf3d030a833484b59ff204c544cddf40966ae Mon Sep 17 00:00:00 2001 From: Donghun Won Date: Fri, 5 Jul 2024 14:36:31 +0900 Subject: [PATCH 008/371] =?UTF-8?q?Feat=20:=20=EC=9C=A0=EC=A0=80=20?= =?UTF-8?q?=ED=95=84=EB=93=9C,=20repo=20=EB=A9=94=EC=84=9C=EB=93=9C=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/solitour_backend/solitour/user/entity/User.java | 3 +++ .../solitour_backend/solitour/user/entity/UserRepository.java | 2 ++ 2 files changed, 5 insertions(+) diff --git a/src/main/java/solitour_backend/solitour/user/entity/User.java b/src/main/java/solitour_backend/solitour/user/entity/User.java index 1c907169..98c37bd0 100644 --- a/src/main/java/solitour_backend/solitour/user/entity/User.java +++ b/src/main/java/solitour_backend/solitour/user/entity/User.java @@ -28,6 +28,9 @@ public class User { @Column(name = "user_oauth_id") private String oauthId; + @Column(name = "provider") + private String provider; + @Column(name = "user_nickname") private String nickname; diff --git a/src/main/java/solitour_backend/solitour/user/entity/UserRepository.java b/src/main/java/solitour_backend/solitour/user/entity/UserRepository.java index 65d6d212..76e86c19 100644 --- a/src/main/java/solitour_backend/solitour/user/entity/UserRepository.java +++ b/src/main/java/solitour_backend/solitour/user/entity/UserRepository.java @@ -6,4 +6,6 @@ public interface UserRepository extends JpaRepository { + Optional findByNickname(String nickname); + } From f9c77806d40f00e82af400c7e38fe422d798d064 Mon Sep 17 00:00:00 2001 From: Donghun Won Date: Fri, 5 Jul 2024 14:37:06 +0900 Subject: [PATCH 009/371] =?UTF-8?q?Feat=20:=20=ED=86=A0=ED=81=B0=20?= =?UTF-8?q?=EA=B2=80=EC=A6=9D=20,=20=ED=8E=98=EC=9D=B4=EB=A1=9C=EB=93=9C,?= =?UTF-8?q?=20=ED=81=B4=EB=A0=88=EC=9E=84=20getter?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../auth/support/JwtTokenProvider.java | 27 +++++++++++++++++-- .../auth/support/kakao/KakaoConnector.java | 1 - 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/src/main/java/solitour_backend/solitour/auth/support/JwtTokenProvider.java b/src/main/java/solitour_backend/solitour/auth/support/JwtTokenProvider.java index aed14b5a..0d4a0450 100644 --- a/src/main/java/solitour_backend/solitour/auth/support/JwtTokenProvider.java +++ b/src/main/java/solitour_backend/solitour/auth/support/JwtTokenProvider.java @@ -8,6 +8,7 @@ import io.jsonwebtoken.Jwts; import io.jsonwebtoken.SignatureAlgorithm; import io.jsonwebtoken.security.Keys; +import jakarta.security.auth.message.AuthException; import java.nio.charset.StandardCharsets; import java.util.Date; import javax.crypto.SecretKey; @@ -22,8 +23,8 @@ public class JwtTokenProvider { private final long refreshTokenValidityInMilliseconds; public JwtTokenProvider(@Value("${security.jwt.token.secret-key}") final String secretKey, - @Value("${security.jwt.token.access-token-expire-length}") final long accessTokenValidityInMilliseconds, - @Value("${security.jwt.token.refresh-token-expire-length}") final long refreshTokenValidityInMilliseconds) { + @Value("${security.jwt.token.access-token-expire-length}") final long accessTokenValidityInMilliseconds, + @Value("${security.jwt.token.refresh-token-expire-length}") final long refreshTokenValidityInMilliseconds) { this.key = Keys.secretKeyFor(SignatureAlgorithm.HS256); this.accessTokenValidityInMilliseconds = accessTokenValidityInMilliseconds; this.refreshTokenValidityInMilliseconds = refreshTokenValidityInMilliseconds; @@ -48,3 +49,25 @@ private String createToken(Long payload, long validityInMilliseconds) { .signWith(key, SignatureAlgorithm.HS256) .compact(); } + + public Long getPayload(String token) { + return Long.valueOf( + getClaims(token).getBody().getSubject()); + } + + public boolean validateTokenNotUsable(String token) { + try { + Jws claims = getClaims(token); + + return claims.getBody().getExpiration().before(new Date()); + } catch (ExpiredJwtException e) { + throw new RuntimeException("토큰이 만료되었습니다."); + } catch (JwtException | IllegalArgumentException e) { + return true; + } + } + + private Jws getClaims(String token) { + return Jwts.parser().verifyWith(key).build().parseClaimsJws(token); + } +} diff --git a/src/main/java/solitour_backend/solitour/auth/support/kakao/KakaoConnector.java b/src/main/java/solitour_backend/solitour/auth/support/kakao/KakaoConnector.java index 5c5dad1d..780a14e7 100644 --- a/src/main/java/solitour_backend/solitour/auth/support/kakao/KakaoConnector.java +++ b/src/main/java/solitour_backend/solitour/auth/support/kakao/KakaoConnector.java @@ -8,7 +8,6 @@ import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; -import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Component; From 8be60e52b7e77a26388fb24dfc5f15d6fdae0a6b Mon Sep 17 00:00:00 2001 From: Donghun Won Date: Fri, 5 Jul 2024 16:37:07 +0900 Subject: [PATCH 010/371] =?UTF-8?q?Refactor=20:=20token=20id=20column=20?= =?UTF-8?q?=EC=9D=B4=EB=A6=84=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/solitour_backend/solitour/auth/entity/Token.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/solitour_backend/solitour/auth/entity/Token.java b/src/main/java/solitour_backend/solitour/auth/entity/Token.java index a95e144c..d0e09559 100644 --- a/src/main/java/solitour_backend/solitour/auth/entity/Token.java +++ b/src/main/java/solitour_backend/solitour/auth/entity/Token.java @@ -22,6 +22,7 @@ public class Token { @Id + @Column(name = "token_id") @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; From 1369467522edba8e32bcae9d3dcb2af4a5886253 Mon Sep 17 00:00:00 2001 From: Donghun Won Date: Sat, 6 Jul 2024 13:19:33 +0900 Subject: [PATCH 011/371] =?UTF-8?q?Refactor=20:=20=EB=A1=9C=EA=B7=B8?= =?UTF-8?q?=EC=9D=B8=20=EC=9C=A0=ED=98=95=EC=97=90=20=EB=94=B0=EB=9D=BC=20?= =?UTF-8?q?=EB=A9=94=EC=84=9C=EB=93=9C=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../solitour/auth/service/OauthService.java | 55 ++++++++++++------- .../auth/support/google/GoogleConnector.java | 4 +- .../auth/support/kakao/KakaoConnector.java | 2 +- 3 files changed, 38 insertions(+), 23 deletions(-) diff --git a/src/main/java/solitour_backend/solitour/auth/service/OauthService.java b/src/main/java/solitour_backend/solitour/auth/service/OauthService.java index 1a9525f5..6248f831 100644 --- a/src/main/java/solitour_backend/solitour/auth/service/OauthService.java +++ b/src/main/java/solitour_backend/solitour/auth/service/OauthService.java @@ -1,18 +1,17 @@ package solitour_backend.solitour.auth.service; -import jakarta.security.auth.message.AuthException; import java.time.LocalDateTime; -import java.util.Optional; +import java.util.Objects; import lombok.RequiredArgsConstructor; -import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import solitour_backend.solitour.auth.entity.Token; import solitour_backend.solitour.auth.service.dto.response.AccessTokenResponse; import solitour_backend.solitour.auth.service.dto.response.LoginResponse; import solitour_backend.solitour.auth.service.dto.response.OauthLinkResponse; import solitour_backend.solitour.auth.support.JwtTokenProvider; +import solitour_backend.solitour.auth.support.RandomNickName; +import solitour_backend.solitour.auth.support.google.GoogleConnector; import solitour_backend.solitour.auth.support.google.GoogleProvider; import solitour_backend.solitour.auth.support.google.dto.GoogleUserResponse; import solitour_backend.solitour.auth.support.kakao.KakaoConnector; @@ -31,6 +30,7 @@ public class OauthService { private final JwtTokenProvider jwtTokenProvider; private final KakaoConnector kakaoConnector; private final KakaoProvider kakaoProvider; + private final GoogleConnector googleConnector; private final GoogleProvider googleProvider; public OauthLinkResponse generateAuthUrl(String type, String redirectUrl) { @@ -40,9 +40,8 @@ public OauthLinkResponse generateAuthUrl(String type, String redirectUrl) { @Transactional public LoginResponse requestAccessToken(String type, String code, String redirectUrl) { - KakaoUserResponse response = requestUserInfo(type, code, redirectUrl); - - User user = findOrSaveUser(response); + User user = checkAndSaveUser(type, code, redirectUrl); + String token = jwtTokenProvider.createAccessToken(user.getId()); String refreshToken = jwtTokenProvider.createRefreshToken(user.getId()); @@ -51,22 +50,38 @@ public LoginResponse requestAccessToken(String type, String code, String redirec return new LoginResponse(token, refreshToken); } - private KakaoUserResponse requestUserInfo(String type, String code, String redirectUrl) { - - ResponseEntity responseEntity = kakaoConnector.requestUserInfo(code, - redirectUrl); - - return Optional.ofNullable(responseEntity.getBody()) - .orElseThrow(() -> new RuntimeException("카카오 사용자 정보를 가져오는데 실패했습니다.")); + private User checkAndSaveUser(String type, String code, String redirectUrl) { + if(Objects.equals(type, "kakao")){ + KakaoUserResponse response = kakaoConnector.requestKakaoUserInfo(code, redirectUrl).getBody(); + String nickname = response.getKakaoAccount().getProfile().getNickName(); + return userRepository.findByNickname(nickname) + .orElseGet(() -> saveKakaoUser(response)); + } + if(Objects.equals(type, "google")){ + GoogleUserResponse response = googleConnector.requestGoogleUserInfo(code, redirectUrl).getBody(); + String email = response.getEmail(); + return userRepository.findByEmail(email) + .orElseGet(() -> saveGoogleUser(response)); + } + else{ + throw new RuntimeException("지원하지 않는 oauth 타입입니다."); + } } - - private User findOrSaveUser(KakaoUserResponse response) { - String nickname = response.getKakaoAccount().getProfile().getNickName(); - return userRepository.findByNickname(nickname) - .orElseGet(() -> saveUser(response)); + private User saveGoogleUser(GoogleUserResponse response) { + User user = User.builder() + .userStatus(UserStatus.ACTIVATE) + .oauthId(response.getId()) + .provider("google") + .isAdmin(false) + .nickname(RandomNickName.generateRandomNickname()) + .name(response.getName()) + .email(response.getEmail()) + .createdAt(LocalDateTime.now()) + .build(); + return userRepository.save(user); } - private User saveUser(KakaoUserResponse response) { + private User saveKakaoUser(KakaoUserResponse response) { User user = User.builder() .userStatus(UserStatus.ACTIVATE) .oauthId(String.valueOf(response.getId())) diff --git a/src/main/java/solitour_backend/solitour/auth/support/google/GoogleConnector.java b/src/main/java/solitour_backend/solitour/auth/support/google/GoogleConnector.java index 7adb27c6..f9224d27 100644 --- a/src/main/java/solitour_backend/solitour/auth/support/google/GoogleConnector.java +++ b/src/main/java/solitour_backend/solitour/auth/support/google/GoogleConnector.java @@ -8,7 +8,6 @@ import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; -import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Component; @@ -17,6 +16,7 @@ import org.springframework.web.client.RestTemplate; import solitour_backend.solitour.auth.support.google.dto.GoogleTokenResponse; import solitour_backend.solitour.auth.support.google.dto.GoogleUserResponse; +import solitour_backend.solitour.auth.support.google.dto.GoogleUserResponse2; @Getter @RequiredArgsConstructor @@ -28,7 +28,7 @@ public class GoogleConnector { private final GoogleProvider provider; - public ResponseEntity requestUserInfo(String code, String redirectUrl) { + public ResponseEntity requestGoogleUserInfo(String code, String redirectUrl) { String googleToken = requestAccessToken(code, redirectUrl); HttpHeaders headers = new HttpHeaders(); diff --git a/src/main/java/solitour_backend/solitour/auth/support/kakao/KakaoConnector.java b/src/main/java/solitour_backend/solitour/auth/support/kakao/KakaoConnector.java index 780a14e7..e2a3b879 100644 --- a/src/main/java/solitour_backend/solitour/auth/support/kakao/KakaoConnector.java +++ b/src/main/java/solitour_backend/solitour/auth/support/kakao/KakaoConnector.java @@ -27,7 +27,7 @@ public class KakaoConnector { private final KakaoProvider provider; - public ResponseEntity requestUserInfo(String code, String redirectUrl) { + public ResponseEntity requestKakaoUserInfo(String code, String redirectUrl) { String kakaoToken = requestAccessToken(code, redirectUrl); HttpHeaders headers = new HttpHeaders(); From 84fafa622d5ece0b7b71388ffc02160cce7b69ac Mon Sep 17 00:00:00 2001 From: Donghun Won Date: Sat, 6 Jul 2024 13:19:50 +0900 Subject: [PATCH 012/371] =?UTF-8?q?Feat=20:=20=EB=9E=9C=EB=8D=A4=20?= =?UTF-8?q?=EB=8B=89=EB=84=A4=EC=9E=84=20=ED=81=B4=EB=9E=98=EC=8A=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../solitour/auth/support/RandomNickName.java | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 src/main/java/solitour_backend/solitour/auth/support/RandomNickName.java diff --git a/src/main/java/solitour_backend/solitour/auth/support/RandomNickName.java b/src/main/java/solitour_backend/solitour/auth/support/RandomNickName.java new file mode 100644 index 00000000..3ac3cec9 --- /dev/null +++ b/src/main/java/solitour_backend/solitour/auth/support/RandomNickName.java @@ -0,0 +1,13 @@ +package solitour_backend.solitour.auth.support; + +import java.util.UUID; + +public class RandomNickName { + + public static String generateRandomNickname(){ + UUID uuid = UUID.randomUUID(); + String nickname = uuid.toString().substring(0, 4); + return "유저"+nickname; + } + +} From de7a6bfa3b834e23014e47c031ffe2112d13528a Mon Sep 17 00:00:00 2001 From: Donghun Won Date: Sat, 6 Jul 2024 13:20:59 +0900 Subject: [PATCH 013/371] =?UTF-8?q?Refactor=20:=20=EA=B5=AC=EA=B8=80=20?= =?UTF-8?q?=EC=9C=A0=EC=A0=80=EC=A0=95=EB=B3=B4=20=EC=95=84=EC=9D=B4?= =?UTF-8?q?=EB=94=94=20=ED=95=84=EB=93=9C=20=EC=B6=94=EA=B0=80,=20=20?= =?UTF-8?q?=EC=9D=B4=EB=A9=94=EC=9D=BC=EB=A1=9C=20=EC=B0=BE=EA=B8=B0=20?= =?UTF-8?q?=EB=A9=94=EC=84=9C=EB=93=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../solitour/auth/support/google/dto/GoogleUserResponse.java | 1 + .../solitour_backend/solitour/user/entity/UserRepository.java | 2 ++ 2 files changed, 3 insertions(+) diff --git a/src/main/java/solitour_backend/solitour/auth/support/google/dto/GoogleUserResponse.java b/src/main/java/solitour_backend/solitour/auth/support/google/dto/GoogleUserResponse.java index c2517292..235fc564 100644 --- a/src/main/java/solitour_backend/solitour/auth/support/google/dto/GoogleUserResponse.java +++ b/src/main/java/solitour_backend/solitour/auth/support/google/dto/GoogleUserResponse.java @@ -9,6 +9,7 @@ @AllArgsConstructor public class GoogleUserResponse { + private String id; private String name; private String email; } diff --git a/src/main/java/solitour_backend/solitour/user/entity/UserRepository.java b/src/main/java/solitour_backend/solitour/user/entity/UserRepository.java index 76e86c19..cdc00fd9 100644 --- a/src/main/java/solitour_backend/solitour/user/entity/UserRepository.java +++ b/src/main/java/solitour_backend/solitour/user/entity/UserRepository.java @@ -8,4 +8,6 @@ public interface UserRepository extends JpaRepository { Optional findByNickname(String nickname); + Optional findByEmail(String email); + } From 48831e4101bc80d25760816f717cb7595a98c2b5 Mon Sep 17 00:00:00 2001 From: Donghun Won Date: Sat, 6 Jul 2024 13:36:24 +0900 Subject: [PATCH 014/371] =?UTF-8?q?Refactor=20:=20=EC=9D=91=EB=8B=B5=20?= =?UTF-8?q?=EA=B2=80=EC=A6=9D=EB=A1=9C=EC=A7=81=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../auth/support/google/GoogleConnector.java | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/src/main/java/solitour_backend/solitour/auth/support/google/GoogleConnector.java b/src/main/java/solitour_backend/solitour/auth/support/google/GoogleConnector.java index f9224d27..b2a653eb 100644 --- a/src/main/java/solitour_backend/solitour/auth/support/google/GoogleConnector.java +++ b/src/main/java/solitour_backend/solitour/auth/support/google/GoogleConnector.java @@ -16,7 +16,6 @@ import org.springframework.web.client.RestTemplate; import solitour_backend.solitour.auth.support.google.dto.GoogleTokenResponse; import solitour_backend.solitour.auth.support.google.dto.GoogleUserResponse; -import solitour_backend.solitour.auth.support.google.dto.GoogleUserResponse2; @Getter @RequiredArgsConstructor @@ -65,17 +64,10 @@ private MultiValueMap createBody(String code, String redirectUrl } private String extractAccessToken(ResponseEntity responseEntity) { -// validateResponseStatusOk(responseEntity.getStatusCode()); - GoogleTokenResponse response = Optional.ofNullable(responseEntity.getBody()) .orElseThrow(() -> new RuntimeException("구글 토큰을 가져오는데 실패했습니다.")); return response.getAccessToken(); } - -// private void validateResponseStatusOk(HttpStatus status) { -// if (!status.is2xxSuccessful()) { -// throw new RuntimeException("구글 토큰을 가져오는데 실패했습니다."); -// } -// } -} + +} \ No newline at end of file From f4c4d5477f80e00447278145a4a50b1029d685bc Mon Sep 17 00:00:00 2001 From: Donghun Won Date: Sat, 6 Jul 2024 13:37:39 +0900 Subject: [PATCH 015/371] =?UTF-8?q?Style=20:=20=EA=B3=B5=EB=B0=B1=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../solitour/auth/support/google/GoogleConnector.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/solitour_backend/solitour/auth/support/google/GoogleConnector.java b/src/main/java/solitour_backend/solitour/auth/support/google/GoogleConnector.java index b2a653eb..20cb5165 100644 --- a/src/main/java/solitour_backend/solitour/auth/support/google/GoogleConnector.java +++ b/src/main/java/solitour_backend/solitour/auth/support/google/GoogleConnector.java @@ -69,5 +69,5 @@ private String extractAccessToken(ResponseEntity responseEn return response.getAccessToken(); } - + } \ No newline at end of file From d8fdd9ec532649580ca2676ff8ba8c272710d4f4 Mon Sep 17 00:00:00 2001 From: Donghun Won Date: Sun, 7 Jul 2024 17:00:56 +0900 Subject: [PATCH 016/371] =?UTF-8?q?Refactor=20:=20docker=20=ED=8C=8C?= =?UTF-8?q?=EC=9D=BC=20=ED=8F=AC=ED=8A=B8=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docker/docker-compose.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml index cf054186..f6541f8f 100644 --- a/docker/docker-compose.yml +++ b/docker/docker-compose.yml @@ -5,7 +5,7 @@ services: container_name: solitour-db restart: always ports: - - "3307:3307" + - "3306:3306" environment: MYSQL_ROOT_PASSWORD: 1234 MYSQL_DATABASE: solitour From 668e71d9baf7bef7777833af4576ac4343ed3f93 Mon Sep 17 00:00:00 2001 From: Donghun Won Date: Wed, 10 Jul 2024 11:15:20 +0900 Subject: [PATCH 017/371] =?UTF-8?q?Feat:=20cors=20=EB=AC=B8=EC=A0=9C=20?= =?UTF-8?q?=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../solitour/auth/config/AuthConfiguration.java | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/main/java/solitour_backend/solitour/auth/config/AuthConfiguration.java b/src/main/java/solitour_backend/solitour/auth/config/AuthConfiguration.java index cb9d9ee1..127fb057 100644 --- a/src/main/java/solitour_backend/solitour/auth/config/AuthConfiguration.java +++ b/src/main/java/solitour_backend/solitour/auth/config/AuthConfiguration.java @@ -4,6 +4,7 @@ import lombok.RequiredArgsConstructor; import org.springframework.context.annotation.Configuration; import org.springframework.web.method.support.HandlerMethodArgumentResolver; +import org.springframework.web.servlet.config.annotation.CorsRegistry; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @@ -36,4 +37,13 @@ public void addResourceHandlers(ResourceHandlerRegistry registry) { public void addArgumentResolvers(List resolvers) { resolvers.add(new TokenResolver(jwtTokenProvider)); } + + @Override + public void addCorsMappings(CorsRegistry registry) { + registry.addMapping("/*") + .allowedOrigins("http://localhost:3000") + .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS") + .allowedHeaders("") + .allowCredentials(true); + } } From 15766d65ac230044a2f53aa16d6f58b73badd2ae Mon Sep 17 00:00:00 2001 From: Donghun Won Date: Wed, 10 Jul 2024 11:15:38 +0900 Subject: [PATCH 018/371] =?UTF-8?q?Feat=20:=20=EC=BF=A0=ED=82=A4=20?= =?UTF-8?q?=EA=B8=B0=EB=8A=A5=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../solitour/auth/controller/OauthController.java | 11 ++++++++--- .../solitour/auth/service/OauthService.java | 14 +++++++++++++- .../auth/service/dto/response/LoginResponse.java | 5 +++-- .../solitour/user_image/UserImage.java | 2 +- 4 files changed, 25 insertions(+), 7 deletions(-) diff --git a/src/main/java/solitour_backend/solitour/auth/controller/OauthController.java b/src/main/java/solitour_backend/solitour/auth/controller/OauthController.java index 52b6da02..bf77d8d2 100644 --- a/src/main/java/solitour_backend/solitour/auth/controller/OauthController.java +++ b/src/main/java/solitour_backend/solitour/auth/controller/OauthController.java @@ -1,6 +1,7 @@ package solitour_backend.solitour.auth.controller; +import jakarta.servlet.http.HttpServletResponse; import lombok.RequiredArgsConstructor; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.GetMapping; @@ -23,7 +24,6 @@ public class OauthController { private final OauthService oauthService; - @GetMapping(value = "/login", params = {"type", "redirectUrl"}) public ResponseEntity access(@RequestParam String type,@RequestParam String redirectUrl) { OauthLinkResponse response = oauthService.generateAuthUrl(type,redirectUrl); @@ -31,9 +31,13 @@ public ResponseEntity access(@RequestParam String type,@Reque } @GetMapping(value = "/login", params = {"type", "code", "redirectUrl"}) - public ResponseEntity login(@RequestParam String type, @RequestParam String code, @RequestParam String redirectUrl) { + public ResponseEntity login(HttpServletResponse response,@RequestParam String type, @RequestParam String code, @RequestParam String redirectUrl) { LoginResponse loginResponse = oauthService.requestAccessToken(type, code, redirectUrl); - return ResponseEntity.ok(loginResponse); + + response.addCookie(loginResponse.getAccessToken()); + response.addCookie(loginResponse.getRefreshToken()); + + return ResponseEntity.ok().build(); } @Authenticated @@ -47,6 +51,7 @@ public ResponseEntity logout(@AuthenticationPrincipal Long memberId) { @PostMapping("/token/refresh") public ResponseEntity reissueAccessToken(@AuthenticationPrincipal Long memberId) { AccessTokenResponse response = oauthService.reissueAccessToken(memberId); + return ResponseEntity.ok(response); } } diff --git a/src/main/java/solitour_backend/solitour/auth/service/OauthService.java b/src/main/java/solitour_backend/solitour/auth/service/OauthService.java index 6248f831..a5d58e2f 100644 --- a/src/main/java/solitour_backend/solitour/auth/service/OauthService.java +++ b/src/main/java/solitour_backend/solitour/auth/service/OauthService.java @@ -1,6 +1,7 @@ package solitour_backend.solitour.auth.service; +import jakarta.servlet.http.Cookie; import java.time.LocalDateTime; import java.util.Objects; import lombok.RequiredArgsConstructor; @@ -47,7 +48,18 @@ public LoginResponse requestAccessToken(String type, String code, String redirec tokenService.synchronizeRefreshToken(user, refreshToken); - return new LoginResponse(token, refreshToken); + Cookie accessCookie = createCookie("access_token", token,60*60*24); + Cookie refreshCookie = createCookie("refresh_token", refreshToken,60*60*24*10); + + return new LoginResponse(accessCookie, refreshCookie); + } + + private Cookie createCookie(String name, String value, int maxAge) { + Cookie cookie = new Cookie(name, value); + cookie.setHttpOnly(true); + cookie.setMaxAge(maxAge); + cookie.setPath("/"); + return cookie; } private User checkAndSaveUser(String type, String code, String redirectUrl) { diff --git a/src/main/java/solitour_backend/solitour/auth/service/dto/response/LoginResponse.java b/src/main/java/solitour_backend/solitour/auth/service/dto/response/LoginResponse.java index 65e0523b..5a7a3966 100644 --- a/src/main/java/solitour_backend/solitour/auth/service/dto/response/LoginResponse.java +++ b/src/main/java/solitour_backend/solitour/auth/service/dto/response/LoginResponse.java @@ -1,5 +1,6 @@ package solitour_backend.solitour.auth.service.dto.response; +import jakarta.servlet.http.Cookie; import lombok.AccessLevel; import lombok.AllArgsConstructor; import lombok.Getter; @@ -10,6 +11,6 @@ @AllArgsConstructor public class LoginResponse { - private String accessToken; - private String refreshToken; + private Cookie accessToken; + private Cookie refreshToken; } diff --git a/src/main/java/solitour_backend/solitour/user_image/UserImage.java b/src/main/java/solitour_backend/solitour/user_image/UserImage.java index 12bba837..e8a546ea 100644 --- a/src/main/java/solitour_backend/solitour/user_image/UserImage.java +++ b/src/main/java/solitour_backend/solitour/user_image/UserImage.java @@ -20,7 +20,7 @@ @NoArgsConstructor public class UserImage { @Id - @Column(name = "image_id") + @Column(name = "user_image_id") @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; From 2e4f2670c603b301344a4056cb706f3e5e0dca39 Mon Sep 17 00:00:00 2001 From: Donghun Won Date: Wed, 10 Jul 2024 12:08:05 +0900 Subject: [PATCH 019/371] =?UTF-8?q?Feat=20:=20User=20image=20repo=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80,=20=EC=9C=A0=EC=A0=80=20=ED=94=84=EB=A1=9C?= =?UTF-8?q?=ED=95=84=20=ED=95=84=EB=93=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../solitour/auth/service/OauthService.java | 20 +++++++++++++++++++ .../solitour/user/entity/User.java | 4 ++-- .../solitour/user_image/UserImage.java | 6 +----- .../user_image/UserImageRepository.java | 14 +++++++++++++ 4 files changed, 37 insertions(+), 7 deletions(-) create mode 100644 src/main/java/solitour_backend/solitour/user_image/UserImageRepository.java diff --git a/src/main/java/solitour_backend/solitour/auth/service/OauthService.java b/src/main/java/solitour_backend/solitour/auth/service/OauthService.java index a5d58e2f..6aaf0ae0 100644 --- a/src/main/java/solitour_backend/solitour/auth/service/OauthService.java +++ b/src/main/java/solitour_backend/solitour/auth/service/OauthService.java @@ -2,6 +2,7 @@ import jakarta.servlet.http.Cookie; +import java.time.LocalDate; import java.time.LocalDateTime; import java.util.Objects; import lombok.RequiredArgsConstructor; @@ -21,6 +22,8 @@ import solitour_backend.solitour.user.entity.User; import solitour_backend.solitour.user.entity.UserRepository; import solitour_backend.solitour.user.user_status.UserStatus; +import solitour_backend.solitour.user_image.UserImage; +import solitour_backend.solitour.user_image.UserImageRepository; @RequiredArgsConstructor @Service @@ -33,6 +36,7 @@ public class OauthService { private final KakaoProvider kakaoProvider; private final GoogleConnector googleConnector; private final GoogleProvider googleProvider; + private final UserImageRepository userImageRepository; public OauthLinkResponse generateAuthUrl(String type, String redirectUrl) { String oauthLink = getAuthLink(type, redirectUrl); @@ -94,11 +98,15 @@ private User saveGoogleUser(GoogleUserResponse response) { } private User saveKakaoUser(KakaoUserResponse response) { + String userImage = getUserImage(response); + UserImage savedUserImage = userImageRepository.save(new UserImage(userImage, LocalDate.now())); + User user = User.builder() .userStatus(UserStatus.ACTIVATE) .oauthId(String.valueOf(response.getId())) .provider("kakao") .isAdmin(false) + .userImage(savedUserImage) .name(response.getKakaoAccount().getName()) .nickname(response.getKakaoAccount().getProfile().getNickName()) .age(Integer.valueOf(response.getKakaoAccount().getBirthYear())) @@ -109,6 +117,18 @@ private User saveKakaoUser(KakaoUserResponse response) { return userRepository.save(user); } + private String getUserImage(KakaoUserResponse response) { + String gender = response.getKakaoAccount().getGender(); + String userProfile = response.getKakaoAccount().getProfile().getProfileImageUrl(); + if(Objects.equals(gender, "male")){ + return "male"; + } + if(Objects.equals(gender, "female")){ + return "female"; + } + return userProfile; + } + private String getAuthLink(String type, String redirectUrl) { return switch (type) { case "kakao" -> kakaoProvider.generateAuthUrl(redirectUrl); diff --git a/src/main/java/solitour_backend/solitour/user/entity/User.java b/src/main/java/solitour_backend/solitour/user/entity/User.java index 3eed4339..2982dc63 100644 --- a/src/main/java/solitour_backend/solitour/user/entity/User.java +++ b/src/main/java/solitour_backend/solitour/user/entity/User.java @@ -33,8 +33,8 @@ public class User { @Column(name = "provider") private String provider; - @OneToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "image_id") + @OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY) + @JoinColumn(name = "user_image_id",referencedColumnName = "user_image_id") private UserImage userImage; @Column(name = "user_nickname") diff --git a/src/main/java/solitour_backend/solitour/user_image/UserImage.java b/src/main/java/solitour_backend/solitour/user_image/UserImage.java index e8a546ea..3d260cc1 100644 --- a/src/main/java/solitour_backend/solitour/user_image/UserImage.java +++ b/src/main/java/solitour_backend/solitour/user_image/UserImage.java @@ -24,9 +24,6 @@ public class UserImage { @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; - @OneToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "user_id") - private User user; @Column(name = "image_address") private String address; @@ -34,8 +31,7 @@ public class UserImage { @Column(name = "image_created_date") private LocalDate createdDate; - public UserImage(User user, String address, LocalDate createdDate) { - this.user = user; + public UserImage(String address, LocalDate createdDate) { this.address = address; this.createdDate = createdDate; } diff --git a/src/main/java/solitour_backend/solitour/user_image/UserImageRepository.java b/src/main/java/solitour_backend/solitour/user_image/UserImageRepository.java new file mode 100644 index 00000000..16d27872 --- /dev/null +++ b/src/main/java/solitour_backend/solitour/user_image/UserImageRepository.java @@ -0,0 +1,14 @@ +package solitour_backend.solitour.user_image; + +import java.util.Optional; +import org.springframework.data.jpa.repository.Modifying; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.Repository; +import org.springframework.data.repository.query.Param; +import solitour_backend.solitour.auth.entity.Token; + +public interface UserImageRepository extends Repository { + + UserImage save(UserImage userImage); + +} From a1598d30fb65c774e8914ac7aa104caf04042775 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Tue, 30 Jul 2024 23:52:52 +0900 Subject: [PATCH 020/371] =?UTF-8?q?refactor:=20information=20=EC=83=81?= =?UTF-8?q?=EC=84=B8=20=ED=8E=98=EC=9D=B4=EC=A7=80=20=EC=9A=94=EC=B2=AD?= =?UTF-8?q?=EC=97=90=EC=84=9C=20=ED=95=98=EB=8B=A8=EC=9D=98=20=EC=B6=94?= =?UTF-8?q?=EC=B2=9C=20=EC=A0=95=EB=B3=B4=20=EB=8D=B0=EC=9D=B4=ED=84=B0=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../information/dto/response/InformationDetailResponse.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/solitour_backend/solitour/information/dto/response/InformationDetailResponse.java b/src/main/java/solitour_backend/solitour/information/dto/response/InformationDetailResponse.java index 43a4daf2..bdfc33bf 100644 --- a/src/main/java/solitour_backend/solitour/information/dto/response/InformationDetailResponse.java +++ b/src/main/java/solitour_backend/solitour/information/dto/response/InformationDetailResponse.java @@ -30,4 +30,6 @@ public class InformationDetailResponse { private List imageResponses; private int likeCount; + + private List recommendInformation; } From 5ff41e0041ee91d2d5ba110dd667196ae3b47897 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Tue, 30 Jul 2024 23:53:25 +0900 Subject: [PATCH 021/371] =?UTF-8?q?refactor:=20information=20=EC=83=81?= =?UTF-8?q?=EC=84=B8=20=ED=8E=98=EC=9D=B4=EC=A7=80=20=EC=9A=94=EC=B2=AD?= =?UTF-8?q?=EC=97=90=EC=84=9C=20=ED=95=98=EB=8B=A8=EC=9D=98=20=EC=B6=94?= =?UTF-8?q?=EC=B2=9C=20=EC=A0=95=EB=B3=B4=20=EB=8D=B0=EC=9D=B4=ED=84=B0=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80=20service=20=EC=A0=84=EC=97=90=20=EB=B6=84?= =?UTF-8?q?=EB=A6=AC=ED=95=9C=20api=20=EB=8B=A4=EC=8B=9C=20=ED=95=A9?= =?UTF-8?q?=EC=B9=98=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/InformationService.java | 19 ++++--------------- 1 file changed, 4 insertions(+), 15 deletions(-) diff --git a/src/main/java/solitour_backend/solitour/information/service/InformationService.java b/src/main/java/solitour_backend/solitour/information/service/InformationService.java index 1da89337..88193ee2 100644 --- a/src/main/java/solitour_backend/solitour/information/service/InformationService.java +++ b/src/main/java/solitour_backend/solitour/information/service/InformationService.java @@ -175,6 +175,8 @@ public InformationDetailResponse getDetailInformation(Long userId, Long informat int likeCount = greatInformationRepository.countByInformationId(information.getId()); + List informationRecommend = informationRepository.getInformationRecommend(information.getId(), information.getCategory().getId(), userId); + return new InformationDetailResponse( information.getTitle(), information.getAddress(), @@ -187,23 +189,10 @@ public InformationDetailResponse getDetailInformation(Long userId, Long informat placeResponse, zoneCategoryResponse, imageResponseList, - likeCount); + likeCount, + informationRecommend); } - public List getRecommendInformation(Long informationId, Long categoryId, Long userId) { - Information information = informationRepository.findById(informationId) - .orElseThrow( - () -> new InformationNotExistsException("해당하는 id의 information 이 존재하지 않습니다") - ); - - if (!information.getCategory().getId().equals(categoryId)) { - throw new RequestValidationFailedException("해당하는 정보의 카테고리와 일치하지 않습니다"); - } - - return informationRepository.getInformationRecommend(informationId, categoryId, userId); - } - - @Transactional public InformationResponse modifyInformation(Long id, InformationModifyRequest informationModifyRequest, MultipartFile thumbNail, List contentImages) { Information information = informationRepository.findById(id) From ec76d8f2d95a9b82cba88dea21bd986195862892 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Tue, 30 Jul 2024 23:54:23 +0900 Subject: [PATCH 022/371] =?UTF-8?q?refactor:=20information=20=EC=83=81?= =?UTF-8?q?=EC=84=B8=20=ED=8E=98=EC=9D=B4=EC=A7=80=20=EC=9A=94=EC=B2=AD?= =?UTF-8?q?=EC=97=90=EC=84=9C=20=ED=95=98=EB=8B=A8=EC=9D=98=20=EC=B6=94?= =?UTF-8?q?=EC=B2=9C=20=EC=A0=95=EB=B3=B4=20=EB=8D=B0=EC=9D=B4=ED=84=B0=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80=20controller=20=EC=A0=84=EC=97=90=20?= =?UTF-8?q?=EB=B6=84=EB=A6=AC=ED=95=9C=20api=20=EB=8B=A4=EC=8B=9C=20?= =?UTF-8?q?=ED=95=A9=EC=B9=98=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/InformationController.java | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/src/main/java/solitour_backend/solitour/information/controller/InformationController.java b/src/main/java/solitour_backend/solitour/information/controller/InformationController.java index e3d98ad2..ec25678b 100644 --- a/src/main/java/solitour_backend/solitour/information/controller/InformationController.java +++ b/src/main/java/solitour_backend/solitour/information/controller/InformationController.java @@ -61,19 +61,6 @@ public ResponseEntity getDetailInformation(@PathVaria .body(informationDetailResponse); } - @GetMapping("/{informationId}/recommend/{categoryId}") - public ResponseEntity> getRecommendInformation(@PathVariable Long informationId, - @PathVariable Long categoryId, - HttpServletRequest request) { - - Long userId = findUser(request); - List recommendInformation = informationService.getRecommendInformation(categoryId, informationId, userId); - - return ResponseEntity - .status(HttpStatus.OK) - .body(recommendInformation); - } - @Authenticated @PutMapping("/{informationId}") public ResponseEntity modifyInformation(@PathVariable Long informationId, From 77b7ca9732811b054384a9140c59a3638bb5923e Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Wed, 31 Jul 2024 09:14:35 +0900 Subject: [PATCH 023/371] =?UTF-8?q?fix:=20main=20page=20information=203?= =?UTF-8?q?=EA=B0=9C=EC=9B=94=EC=9D=B4=EB=82=B4=EC=97=90=20=EB=A7=8C?= =?UTF-8?q?=EB=93=A4=EC=96=B4=EC=A7=84=20=EC=A0=95=EB=B3=B4=EB=93=A4=20?= =?UTF-8?q?=EC=A2=8B=EC=95=84=EC=9A=94=20=EC=88=9C=EC=9C=BC=EB=A1=9C=206?= =?UTF-8?q?=EA=B0=9C=20=EA=B0=80=EC=A0=B8=EC=98=A4=EB=8A=94=20sql=20?= =?UTF-8?q?=EB=AC=B8=20=EC=98=A4=EB=A5=98=EB=A1=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../repository/InformationRepositoryImpl.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/main/java/solitour_backend/solitour/information/repository/InformationRepositoryImpl.java b/src/main/java/solitour_backend/solitour/information/repository/InformationRepositoryImpl.java index 51e3fc2d..935f9ff5 100644 --- a/src/main/java/solitour_backend/solitour/information/repository/InformationRepositoryImpl.java +++ b/src/main/java/solitour_backend/solitour/information/repository/InformationRepositoryImpl.java @@ -269,16 +269,15 @@ public Page getInformationByChildCategoryFilterZoneCat @Override public List getInformationLikeCountFromCreatedIn3(Long userId) { return from(information) - .join(zoneCategoryChild).on(zoneCategoryChild.id.eq(information.zoneCategory.id)) + .leftJoin(zoneCategoryChild).on(zoneCategoryChild.id.eq(information.zoneCategory.id)) .leftJoin(zoneCategoryParent).on(zoneCategoryParent.id.eq(zoneCategoryChild.parentZoneCategory.id)) .leftJoin(bookMarkInformation).on(bookMarkInformation.information.id.eq(information.id).and(bookMarkInformation.user.id.eq(userId))) - .leftJoin(image).on(image.information.id.eq(information.id) - .and(image.imageStatus.eq(ImageStatus.THUMBNAIL))) + .leftJoin(image).on(image.information.id.eq(information.id).and(image.imageStatus.eq(ImageStatus.THUMBNAIL))) .leftJoin(greatInformation).on(greatInformation.information.id.eq(information.id)) - .join(category).on(category.id.eq(information.id)) + .leftJoin(category).on(category.id.eq(information.category.id)) .where(information.createdDate.after(LocalDateTime.now().minusMonths(3))) - .groupBy(information.id, image.id) - .orderBy(greatInformation.information.count().desc()) + .groupBy(information.id, information.title, zoneCategoryParent.name, zoneCategoryChild.name, bookMarkInformation.id, image.address) + .orderBy(greatInformation.information.id.count().desc()) .select(Projections.constructor( InformationMainResponse.class, information.id, @@ -291,6 +290,7 @@ public List getInformationLikeCountFromCreatedIn3(Long image.address, greatInformation.information.count().coalesce(0L).intValue() )).limit(6).fetch(); + } @Override From 4f3af2a51bd62bb23d0dbe0d15badd33d230df0a Mon Sep 17 00:00:00 2001 From: "SK\\ssssk" Date: Thu, 1 Aug 2024 03:16:11 +0900 Subject: [PATCH 024/371] =?UTF-8?q?fix:=20=EB=B6=88=ED=95=84=EC=9A=94?= =?UTF-8?q?=ED=95=9C=20=EC=BD=94=EB=93=9C=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../solitour_backend/solitour/admin/service/BannerService.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/solitour_backend/solitour/admin/service/BannerService.java b/src/main/java/solitour_backend/solitour/admin/service/BannerService.java index 49492284..6096dafc 100644 --- a/src/main/java/solitour_backend/solitour/admin/service/BannerService.java +++ b/src/main/java/solitour_backend/solitour/admin/service/BannerService.java @@ -58,7 +58,6 @@ public ResponseEntity deleteBanner(Long id) { public Banner createBanner(MultipartFile multipartFile, String dirName) { String fileName = dirName + "/" + new Date().toString(); try { - System.out.println(fileName); ObjectMetadata metadata = new ObjectMetadata(); metadata.setContentLength(multipartFile.getSize()); metadata.setContentType(multipartFile.getContentType()); From d7e3736d1ea2e054eb64e300e5935cf418da4b7b Mon Sep 17 00:00:00 2001 From: "SK\\ssssk" Date: Thu, 1 Aug 2024 03:21:21 +0900 Subject: [PATCH 025/371] =?UTF-8?q?feat:=20=EB=AA=A8=EC=9E=84=20=EC=B9=B4?= =?UTF-8?q?=ED=85=8C=EA=B3=A0=EB=A6=AC=20=EC=83=9D=EC=84=B1,=20=EC=A1=B0?= =?UTF-8?q?=ED=9A=8C,=20=EC=82=AD=EC=A0=9C=20=EA=B8=B0=EB=8A=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../GatheringCategoryController.java | 75 +++++++++++++++ .../dto/mapper/GatheringCategoryMapper.java | 16 ++++ .../admin/entity/GatheringCategory.java | 30 ++++++ .../GatheringCategoryRepository.java | 11 +++ .../service/GatheringCategoryService.java | 94 +++++++++++++++++++ 5 files changed, 226 insertions(+) create mode 100644 src/main/java/solitour_backend/solitour/admin/controller/GatheringCategoryController.java create mode 100644 src/main/java/solitour_backend/solitour/admin/dto/mapper/GatheringCategoryMapper.java create mode 100644 src/main/java/solitour_backend/solitour/admin/entity/GatheringCategory.java create mode 100644 src/main/java/solitour_backend/solitour/admin/repository/GatheringCategoryRepository.java create mode 100644 src/main/java/solitour_backend/solitour/admin/service/GatheringCategoryService.java diff --git a/src/main/java/solitour_backend/solitour/admin/controller/GatheringCategoryController.java b/src/main/java/solitour_backend/solitour/admin/controller/GatheringCategoryController.java new file mode 100644 index 00000000..d687ad4d --- /dev/null +++ b/src/main/java/solitour_backend/solitour/admin/controller/GatheringCategoryController.java @@ -0,0 +1,75 @@ +package solitour_backend.solitour.admin.controller; + +import jakarta.validation.Valid; +import lombok.RequiredArgsConstructor; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.validation.BindingResult; +import org.springframework.web.bind.annotation.*; +import solitour_backend.solitour.admin.service.GatheringCategoryService; +import solitour_backend.solitour.category.dto.request.CategoryModifyRequest; +import solitour_backend.solitour.category.dto.request.CategoryRegisterRequest; +import solitour_backend.solitour.category.dto.response.CategoryGetResponse; +import solitour_backend.solitour.category.dto.response.CategoryResponse; +import solitour_backend.solitour.error.exception.RequestValidationFailedException; + +import java.util.List; + +@RestController +@RequiredArgsConstructor +@RequestMapping("/api/categories/gathering") +public class GatheringCategoryController { + + private final GatheringCategoryService gatheringCategoryService; + + @GetMapping + public ResponseEntity> getAllCategories() { + List parentCategories = gatheringCategoryService.getParentCategories(); + + return ResponseEntity + .status(HttpStatus.OK) + .body(parentCategories); + } + + @GetMapping("/{id}") + public ResponseEntity getCategory(@PathVariable Long id) { + CategoryResponse category = gatheringCategoryService.getCategory(id); + + return ResponseEntity + .status(HttpStatus.OK) + .body(category); + } + + @PostMapping + public ResponseEntity registerCategory( + @Valid @RequestBody CategoryRegisterRequest categoryRegisterRequest, + BindingResult bindingResult) { + if (bindingResult.hasErrors()) { + throw new RequestValidationFailedException(bindingResult); + } + CategoryResponse categoryResponse = gatheringCategoryService.registerCategory( + categoryRegisterRequest); + return ResponseEntity + .status(HttpStatus.CREATED) + .body(categoryResponse); + + } + + @PutMapping("/{id}") + public ResponseEntity modifyCategory( + @Valid @RequestBody CategoryModifyRequest categoryModifyRequest, + BindingResult bindingResult, + @PathVariable Long id) { + if (bindingResult.hasErrors()) { + throw new RequestValidationFailedException(bindingResult); + } + CategoryResponse categoryResponse = gatheringCategoryService.modifyCategory(id, + categoryModifyRequest); + + return ResponseEntity + .status(HttpStatus.CREATED) + .body(categoryResponse); + } + + +} diff --git a/src/main/java/solitour_backend/solitour/admin/dto/mapper/GatheringCategoryMapper.java b/src/main/java/solitour_backend/solitour/admin/dto/mapper/GatheringCategoryMapper.java new file mode 100644 index 00000000..b5f7b864 --- /dev/null +++ b/src/main/java/solitour_backend/solitour/admin/dto/mapper/GatheringCategoryMapper.java @@ -0,0 +1,16 @@ +package solitour_backend.solitour.admin.dto.mapper; + +import org.mapstruct.Mapper; +import org.mapstruct.ReportingPolicy; +import solitour_backend.solitour.admin.entity.GatheringCategory; +import solitour_backend.solitour.category.dto.response.CategoryResponse; + +import java.util.List; + +@Mapper(componentModel = "spring", unmappedTargetPolicy = ReportingPolicy.ERROR) +public interface GatheringCategoryMapper { + + CategoryResponse mapToCategoryResponse(GatheringCategory category); + + List mapToCategoryResponses(List categories); +} diff --git a/src/main/java/solitour_backend/solitour/admin/entity/GatheringCategory.java b/src/main/java/solitour_backend/solitour/admin/entity/GatheringCategory.java new file mode 100644 index 00000000..3a99b3be --- /dev/null +++ b/src/main/java/solitour_backend/solitour/admin/entity/GatheringCategory.java @@ -0,0 +1,30 @@ +package solitour_backend.solitour.admin.entity; + +import jakarta.persistence.*; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +@Entity +@Getter +@Setter +@Table(name = "gathering_category") +@NoArgsConstructor +public class GatheringCategory { + + @Id + @Column(name = "gathering_category_id") + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + @ManyToOne(fetch = FetchType.EAGER) + @JoinColumn(name = "parent_category_id") + private GatheringCategory parentCategory; + + @Column(name = "gathering_category_name") + private String name; + + public GatheringCategory(GatheringCategory parentCategory, String name) { + this.parentCategory = parentCategory; + this.name = name; + } +} diff --git a/src/main/java/solitour_backend/solitour/admin/repository/GatheringCategoryRepository.java b/src/main/java/solitour_backend/solitour/admin/repository/GatheringCategoryRepository.java new file mode 100644 index 00000000..e2c176df --- /dev/null +++ b/src/main/java/solitour_backend/solitour/admin/repository/GatheringCategoryRepository.java @@ -0,0 +1,11 @@ +package solitour_backend.solitour.admin.repository; + +import org.springframework.data.jpa.repository.JpaRepository; +import solitour_backend.solitour.admin.entity.GatheringCategory; + +import java.util.List; + +public interface GatheringCategoryRepository extends JpaRepository { + + List findAllByParentCategoryId(Long parentCategoryId); +} diff --git a/src/main/java/solitour_backend/solitour/admin/service/GatheringCategoryService.java b/src/main/java/solitour_backend/solitour/admin/service/GatheringCategoryService.java new file mode 100644 index 00000000..e0cb511e --- /dev/null +++ b/src/main/java/solitour_backend/solitour/admin/service/GatheringCategoryService.java @@ -0,0 +1,94 @@ +package solitour_backend.solitour.admin.service; + +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import solitour_backend.solitour.admin.dto.mapper.GatheringCategoryMapper; +import solitour_backend.solitour.admin.entity.GatheringCategory; +import solitour_backend.solitour.admin.repository.GatheringCategoryRepository; +import solitour_backend.solitour.category.dto.request.CategoryModifyRequest; +import solitour_backend.solitour.category.dto.request.CategoryRegisterRequest; +import solitour_backend.solitour.category.dto.response.CategoryGetResponse; +import solitour_backend.solitour.category.dto.response.CategoryResponse; +import solitour_backend.solitour.category.exception.CategoryNotExistsException; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +@Service +@Transactional(readOnly = true) +@RequiredArgsConstructor +public class GatheringCategoryService { + + private final GatheringCategoryRepository gatheringCategoryRepository; + private final GatheringCategoryMapper gatheringCategoryMapper; + + @Transactional + public CategoryResponse registerCategory(CategoryRegisterRequest categoryRegisterRequest) { + GatheringCategory parentCategoryEntity; + if (Objects.isNull(categoryRegisterRequest.getParentCategory())) { + parentCategoryEntity = null; + } else { + parentCategoryEntity = gatheringCategoryRepository.findById( + categoryRegisterRequest.getParentCategory()) + .orElseThrow( + () -> new CategoryNotExistsException("Parent category not found")); + } + + GatheringCategory category = new GatheringCategory(parentCategoryEntity, categoryRegisterRequest.getName()); + GatheringCategory saveCategory = gatheringCategoryRepository.save(category); + + return gatheringCategoryMapper.mapToCategoryResponse(saveCategory); + } + + + public CategoryResponse getCategory(Long id) { + GatheringCategory category = gatheringCategoryRepository.findById(id) + .orElseThrow( + () -> new CategoryNotExistsException("category not found")); + + return gatheringCategoryMapper.mapToCategoryResponse(category); + } + + + public List getChildrenCategories(Long id) { + List childrenCategories = gatheringCategoryRepository.findAllByParentCategoryId(id); + + return gatheringCategoryMapper.mapToCategoryResponses(childrenCategories); + } + + public List getParentCategories() { + List parentCategories = gatheringCategoryRepository.findAllByParentCategoryId(null); + List categoryGetResponses = new ArrayList<>(); + + for (GatheringCategory category : parentCategories) { + List childrenCategories = getChildrenCategories(category.getId()); + categoryGetResponses.add( + new CategoryGetResponse(category.getId(), category.getName(), childrenCategories)); + } + + return categoryGetResponses; + } + + @Transactional + public CategoryResponse modifyCategory(Long id, CategoryModifyRequest categoryModifyRequest) { + GatheringCategory parentCategoryEntity; + if (Objects.isNull(categoryModifyRequest.getParentCategory())) { + parentCategoryEntity = null; + } else { + parentCategoryEntity = gatheringCategoryRepository.findById( + categoryModifyRequest.getParentCategory()) + .orElseThrow( + () -> new CategoryNotExistsException("Parent category not found")); + } + + GatheringCategory category = gatheringCategoryRepository.findById(id).orElseThrow(); + + category.setName(categoryModifyRequest.getName()); + category.setParentCategory(parentCategoryEntity); + + return gatheringCategoryMapper.mapToCategoryResponse(category); + } + +} From f43066ed1c2fa420b16a805c2c8937a960df4207 Mon Sep 17 00:00:00 2001 From: Donghun Won Date: Thu, 1 Aug 2024 10:53:30 +0900 Subject: [PATCH 026/371] =?UTF-8?q?Feat:=20=EC=9C=A0=EC=A0=80=20=EB=8B=89?= =?UTF-8?q?=EB=84=A4=EC=9E=84=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../auth/controller/OauthController.java | 2 -- .../user/controller/UserController.java | 20 +++++++++++++++++++ .../user/dto/UpdateNicknameRequest.java | 4 ++++ .../solitour/user/entity/User.java | 4 ++++ .../solitour/user/entity/UserRepository.java | 2 ++ .../NicknameAlreadyExistsException.java | 7 +++++++ .../solitour/user/service/UserService.java | 9 +++++++++ .../user_image/UserImageRepository.java | 14 ------------- 8 files changed, 46 insertions(+), 16 deletions(-) create mode 100644 src/main/java/solitour_backend/solitour/user/dto/UpdateNicknameRequest.java create mode 100644 src/main/java/solitour_backend/solitour/user/exception/NicknameAlreadyExistsException.java delete mode 100644 src/main/java/solitour_backend/solitour/user_image/UserImageRepository.java diff --git a/src/main/java/solitour_backend/solitour/auth/controller/OauthController.java b/src/main/java/solitour_backend/solitour/auth/controller/OauthController.java index 89eb8a60..7bdd0bbc 100644 --- a/src/main/java/solitour_backend/solitour/auth/controller/OauthController.java +++ b/src/main/java/solitour_backend/solitour/auth/controller/OauthController.java @@ -10,7 +10,6 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; -import solitour_backend.solitour.auth.config.Authenticated; import solitour_backend.solitour.auth.config.AuthenticationPrincipal; import solitour_backend.solitour.auth.config.AuthenticationRefreshPrincipal; import solitour_backend.solitour.auth.service.OauthService; @@ -45,7 +44,6 @@ public ResponseEntity login(HttpServletResponse response, @Reques return ResponseEntity.ok().build(); } - @Authenticated @PostMapping("/logout") public ResponseEntity logout(@AuthenticationPrincipal Long memberId) { oauthService.logout(memberId); diff --git a/src/main/java/solitour_backend/solitour/user/controller/UserController.java b/src/main/java/solitour_backend/solitour/user/controller/UserController.java index 64b50691..7e163a68 100644 --- a/src/main/java/solitour_backend/solitour/user/controller/UserController.java +++ b/src/main/java/solitour_backend/solitour/user/controller/UserController.java @@ -1,11 +1,17 @@ package solitour_backend.solitour.user.controller; import lombok.RequiredArgsConstructor; +import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import solitour_backend.solitour.auth.config.AuthenticationPrincipal; +import solitour_backend.solitour.user.dto.UpdateNicknameRequest; +import solitour_backend.solitour.user.exception.NicknameAlreadyExistsException; +import solitour_backend.solitour.user.exception.UserNotExistsException; import solitour_backend.solitour.user.service.UserService; import solitour_backend.solitour.user.service.dto.response.UserInfoResponse; @@ -24,4 +30,18 @@ public ResponseEntity retrieveUserInfo(@AuthenticationPrincipa return ResponseEntity.ok(response); } + @PutMapping("/nickname") + public ResponseEntity updateNickname(@AuthenticationPrincipal Long userId, @RequestBody UpdateNicknameRequest request) { + try { + service.updateNickname(userId, request.nickname()); + return ResponseEntity.ok("Nickname updated successfully"); + } catch (UserNotExistsException e) { + return ResponseEntity.status(HttpStatus.NOT_FOUND).body("User not found"); + } catch (NicknameAlreadyExistsException e) { + return ResponseEntity.status(HttpStatus.CONFLICT).body("Nickname already exists"); + } catch (Exception e) { + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("An internal error occurred"); + } + } + } diff --git a/src/main/java/solitour_backend/solitour/user/dto/UpdateNicknameRequest.java b/src/main/java/solitour_backend/solitour/user/dto/UpdateNicknameRequest.java new file mode 100644 index 00000000..26845597 --- /dev/null +++ b/src/main/java/solitour_backend/solitour/user/dto/UpdateNicknameRequest.java @@ -0,0 +1,4 @@ +package solitour_backend.solitour.user.dto; + +public record UpdateNicknameRequest(String nickname) { +} diff --git a/src/main/java/solitour_backend/solitour/user/entity/User.java b/src/main/java/solitour_backend/solitour/user/entity/User.java index df933ae4..ad3b1509 100644 --- a/src/main/java/solitour_backend/solitour/user/entity/User.java +++ b/src/main/java/solitour_backend/solitour/user/entity/User.java @@ -77,4 +77,8 @@ public class User { @Column(name = "user_deleted_at") private LocalDateTime deletedAt; + + public void updateNickname(String nickname) { + this.nickname = nickname; + } } diff --git a/src/main/java/solitour_backend/solitour/user/entity/UserRepository.java b/src/main/java/solitour_backend/solitour/user/entity/UserRepository.java index cb890187..3d6c1ac5 100644 --- a/src/main/java/solitour_backend/solitour/user/entity/UserRepository.java +++ b/src/main/java/solitour_backend/solitour/user/entity/UserRepository.java @@ -13,4 +13,6 @@ public interface UserRepository extends JpaRepository { @Query("SELECT u FROM User u JOIN FETCH u.userImage WHERE u.id = :userId") User findByUserId(Long userId); + + boolean existsByNickname(String nickname); } diff --git a/src/main/java/solitour_backend/solitour/user/exception/NicknameAlreadyExistsException.java b/src/main/java/solitour_backend/solitour/user/exception/NicknameAlreadyExistsException.java new file mode 100644 index 00000000..b8742134 --- /dev/null +++ b/src/main/java/solitour_backend/solitour/user/exception/NicknameAlreadyExistsException.java @@ -0,0 +1,7 @@ +package solitour_backend.solitour.user.exception; + +public class NicknameAlreadyExistsException extends RuntimeException { + public NicknameAlreadyExistsException(String message) { + super(message); + } +} diff --git a/src/main/java/solitour_backend/solitour/user/service/UserService.java b/src/main/java/solitour_backend/solitour/user/service/UserService.java index 1047004e..3a5cf5b3 100644 --- a/src/main/java/solitour_backend/solitour/user/service/UserService.java +++ b/src/main/java/solitour_backend/solitour/user/service/UserService.java @@ -5,6 +5,7 @@ import org.springframework.transaction.annotation.Transactional; import solitour_backend.solitour.user.entity.User; import solitour_backend.solitour.user.entity.UserRepository; +import solitour_backend.solitour.user.exception.NicknameAlreadyExistsException; import solitour_backend.solitour.user.service.dto.response.UserInfoResponse; @Service @@ -20,4 +21,12 @@ public UserInfoResponse retrieveUserInfo(Long userId) { return new UserInfoResponse(user); } + @Transactional + public void updateNickname(Long userId, String nickname) { + if (userRepository.existsByNickname(nickname)) { + throw new NicknameAlreadyExistsException("Nickname already exists"); + } + User user = userRepository.findByUserId(userId); + user.updateNickname(nickname); + } } diff --git a/src/main/java/solitour_backend/solitour/user_image/UserImageRepository.java b/src/main/java/solitour_backend/solitour/user_image/UserImageRepository.java deleted file mode 100644 index 16d27872..00000000 --- a/src/main/java/solitour_backend/solitour/user_image/UserImageRepository.java +++ /dev/null @@ -1,14 +0,0 @@ -package solitour_backend.solitour.user_image; - -import java.util.Optional; -import org.springframework.data.jpa.repository.Modifying; -import org.springframework.data.jpa.repository.Query; -import org.springframework.data.repository.Repository; -import org.springframework.data.repository.query.Param; -import solitour_backend.solitour.auth.entity.Token; - -public interface UserImageRepository extends Repository { - - UserImage save(UserImage userImage); - -} From 85a16ab3c9ac4415cfde5392b1ce4a106baf2995 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Fri, 2 Aug 2024 02:43:32 +0900 Subject: [PATCH 027/371] =?UTF-8?q?fix:=20comment=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../solitour/comment/entity/Comment.java | 56 ------------------- 1 file changed, 56 deletions(-) delete mode 100644 src/main/java/solitour_backend/solitour/comment/entity/Comment.java diff --git a/src/main/java/solitour_backend/solitour/comment/entity/Comment.java b/src/main/java/solitour_backend/solitour/comment/entity/Comment.java deleted file mode 100644 index 540911d3..00000000 --- a/src/main/java/solitour_backend/solitour/comment/entity/Comment.java +++ /dev/null @@ -1,56 +0,0 @@ -package solitour_backend.solitour.comment.entity; - -import jakarta.persistence.Column; -import jakarta.persistence.Entity; -import jakarta.persistence.FetchType; -import jakarta.persistence.GeneratedValue; -import jakarta.persistence.GenerationType; -import jakarta.persistence.Id; -import jakarta.persistence.JoinColumn; -import jakarta.persistence.ManyToOne; -import jakarta.persistence.Table; - -import java.time.LocalDateTime; - -import lombok.Getter; -import lombok.NoArgsConstructor; -import solitour_backend.solitour.gathering.entity.Gathering; -import solitour_backend.solitour.information.entity.Information; -import solitour_backend.solitour.user.entity.User; - -@Entity -@Getter -@Table(name = "comment") -@NoArgsConstructor -public class Comment { - - @Id - @Column(name = "comment_id") - @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long id; - - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "parent_comment_id") - private Comment parentComment; - - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "user_id") - private User user; - - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "information_id") - private Information information; - - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "gathering_id") - private Gathering gathering; - - @Column(name = "comment_content") - private String content; - - @Column(name = "comment_recent_date") - private LocalDateTime recentDate; - - @Column(name = "comment_is_edited") - private Boolean isEdited; -} From 29ce450c9bbffaac4ee2fcd15c2f47122d29d4b3 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Fri, 2 Aug 2024 02:44:10 +0900 Subject: [PATCH 028/371] =?UTF-8?q?refactor:=20gathering=20category=20?= =?UTF-8?q?=ED=8C=A8=ED=82=A4=EC=A7=80=20=EC=9D=B4=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../entity/GatheringCategory.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) rename src/main/java/solitour_backend/solitour/{admin => gathering_category}/entity/GatheringCategory.java (92%) diff --git a/src/main/java/solitour_backend/solitour/admin/entity/GatheringCategory.java b/src/main/java/solitour_backend/solitour/gathering_category/entity/GatheringCategory.java similarity index 92% rename from src/main/java/solitour_backend/solitour/admin/entity/GatheringCategory.java rename to src/main/java/solitour_backend/solitour/gathering_category/entity/GatheringCategory.java index 3a99b3be..a828d338 100644 --- a/src/main/java/solitour_backend/solitour/admin/entity/GatheringCategory.java +++ b/src/main/java/solitour_backend/solitour/gathering_category/entity/GatheringCategory.java @@ -1,4 +1,4 @@ -package solitour_backend.solitour.admin.entity; +package solitour_backend.solitour.gathering_category.entity; import jakarta.persistence.*; import lombok.Getter; @@ -16,6 +16,7 @@ public class GatheringCategory { @Column(name = "gathering_category_id") @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; + @ManyToOne(fetch = FetchType.EAGER) @JoinColumn(name = "parent_category_id") private GatheringCategory parentCategory; From f34fb3e93734ecadb649cb7c06b6b2594d290b12 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Fri, 2 Aug 2024 02:44:19 +0900 Subject: [PATCH 029/371] =?UTF-8?q?refactor:=20gathering=20category=20?= =?UTF-8?q?=ED=8C=A8=ED=82=A4=EC=A7=80=20=EC=9D=B4=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../solitour/admin/dto/mapper/GatheringCategoryMapper.java | 2 +- .../solitour/admin/service/GatheringCategoryService.java | 4 ++-- .../repository/GatheringCategoryRepository.java | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) rename src/main/java/solitour_backend/solitour/{admin => gathering_category}/repository/GatheringCategoryRepository.java (65%) diff --git a/src/main/java/solitour_backend/solitour/admin/dto/mapper/GatheringCategoryMapper.java b/src/main/java/solitour_backend/solitour/admin/dto/mapper/GatheringCategoryMapper.java index b5f7b864..65df0793 100644 --- a/src/main/java/solitour_backend/solitour/admin/dto/mapper/GatheringCategoryMapper.java +++ b/src/main/java/solitour_backend/solitour/admin/dto/mapper/GatheringCategoryMapper.java @@ -2,7 +2,7 @@ import org.mapstruct.Mapper; import org.mapstruct.ReportingPolicy; -import solitour_backend.solitour.admin.entity.GatheringCategory; +import solitour_backend.solitour.gathering_category.entity.GatheringCategory; import solitour_backend.solitour.category.dto.response.CategoryResponse; import java.util.List; diff --git a/src/main/java/solitour_backend/solitour/admin/service/GatheringCategoryService.java b/src/main/java/solitour_backend/solitour/admin/service/GatheringCategoryService.java index e0cb511e..2023a12a 100644 --- a/src/main/java/solitour_backend/solitour/admin/service/GatheringCategoryService.java +++ b/src/main/java/solitour_backend/solitour/admin/service/GatheringCategoryService.java @@ -4,8 +4,8 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import solitour_backend.solitour.admin.dto.mapper.GatheringCategoryMapper; -import solitour_backend.solitour.admin.entity.GatheringCategory; -import solitour_backend.solitour.admin.repository.GatheringCategoryRepository; +import solitour_backend.solitour.gathering_category.entity.GatheringCategory; +import solitour_backend.solitour.gathering_category.repository.GatheringCategoryRepository; import solitour_backend.solitour.category.dto.request.CategoryModifyRequest; import solitour_backend.solitour.category.dto.request.CategoryRegisterRequest; import solitour_backend.solitour.category.dto.response.CategoryGetResponse; diff --git a/src/main/java/solitour_backend/solitour/admin/repository/GatheringCategoryRepository.java b/src/main/java/solitour_backend/solitour/gathering_category/repository/GatheringCategoryRepository.java similarity index 65% rename from src/main/java/solitour_backend/solitour/admin/repository/GatheringCategoryRepository.java rename to src/main/java/solitour_backend/solitour/gathering_category/repository/GatheringCategoryRepository.java index e2c176df..650eb290 100644 --- a/src/main/java/solitour_backend/solitour/admin/repository/GatheringCategoryRepository.java +++ b/src/main/java/solitour_backend/solitour/gathering_category/repository/GatheringCategoryRepository.java @@ -1,7 +1,7 @@ -package solitour_backend.solitour.admin.repository; +package solitour_backend.solitour.gathering_category.repository; import org.springframework.data.jpa.repository.JpaRepository; -import solitour_backend.solitour.admin.entity.GatheringCategory; +import solitour_backend.solitour.gathering_category.entity.GatheringCategory; import java.util.List; From 4e26eefd6a56be54b3399fc22bd2187e6f3f99bd Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Fri, 2 Aug 2024 02:45:34 +0900 Subject: [PATCH 030/371] =?UTF-8?q?feat:=20gathering=20status=20enum=20?= =?UTF-8?q?=ED=81=B4=EB=9E=98=EC=8A=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../entity/GatheringStatus.java | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 src/main/java/solitour_backend/solitour/gathering_applicants/entity/GatheringStatus.java diff --git a/src/main/java/solitour_backend/solitour/gathering_applicants/entity/GatheringStatus.java b/src/main/java/solitour_backend/solitour/gathering_applicants/entity/GatheringStatus.java new file mode 100644 index 00000000..3d46ac64 --- /dev/null +++ b/src/main/java/solitour_backend/solitour/gathering_applicants/entity/GatheringStatus.java @@ -0,0 +1,25 @@ +package solitour_backend.solitour.gathering_applicants.entity; + +import lombok.Getter; + +import java.util.Arrays; + +@Getter +public enum GatheringStatus { + WAIT("대기"), + CONSENT("승낙"), + REFUSE("거절"); + + private final String name; + + GatheringStatus(String name) { + this.name = name; + } + + public static GatheringStatus fromName(String name) { + return Arrays.stream(GatheringStatus.values()) + .filter(e -> e.name.equals(name)) + .findAny() + .orElse(null); + } +} From 96d140e487a7eb21da96a01d0bb13167c61d0dcf Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Fri, 2 Aug 2024 02:45:43 +0900 Subject: [PATCH 031/371] =?UTF-8?q?feat:=20gathering=20status=20enum=20?= =?UTF-8?q?=ED=81=B4=EB=9E=98=EC=8A=A4=20converter?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../entity/GatheringStatusConverter.java | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 src/main/java/solitour_backend/solitour/gathering_applicants/entity/GatheringStatusConverter.java diff --git a/src/main/java/solitour_backend/solitour/gathering_applicants/entity/GatheringStatusConverter.java b/src/main/java/solitour_backend/solitour/gathering_applicants/entity/GatheringStatusConverter.java new file mode 100644 index 00000000..cd0d7eb0 --- /dev/null +++ b/src/main/java/solitour_backend/solitour/gathering_applicants/entity/GatheringStatusConverter.java @@ -0,0 +1,17 @@ +package solitour_backend.solitour.gathering_applicants.entity; + +import jakarta.persistence.AttributeConverter; +import jakarta.persistence.Converter; + +@Converter(autoApply = true) +public class GatheringStatusConverter implements AttributeConverter { + @Override + public String convertToDatabaseColumn(GatheringStatus gatheringStatus) { + return gatheringStatus.getName(); + } + + @Override + public GatheringStatus convertToEntityAttribute(String dbData) { + return GatheringStatus.fromName(dbData); + } +} From 9298821a71e87224141c946854bbca39866f27d4 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Fri, 2 Aug 2024 02:46:01 +0900 Subject: [PATCH 032/371] =?UTF-8?q?feat:=20gathering=20applicants=20?= =?UTF-8?q?=ED=85=8C=EC=9D=B4=EB=B8=94=20=ED=81=B4=EB=9E=98=EC=8A=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../entity/GatheringApplicants.java | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 src/main/java/solitour_backend/solitour/gathering_applicants/entity/GatheringApplicants.java diff --git a/src/main/java/solitour_backend/solitour/gathering_applicants/entity/GatheringApplicants.java b/src/main/java/solitour_backend/solitour/gathering_applicants/entity/GatheringApplicants.java new file mode 100644 index 00000000..833f247a --- /dev/null +++ b/src/main/java/solitour_backend/solitour/gathering_applicants/entity/GatheringApplicants.java @@ -0,0 +1,39 @@ +package solitour_backend.solitour.gathering_applicants.entity; + +import jakarta.persistence.*; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import solitour_backend.solitour.gathering.entity.Gathering; +import solitour_backend.solitour.user.entity.User; + +@Entity +@Getter +@Setter +@Table(name = "gathering_applicants") +@NoArgsConstructor +public class GatheringApplicants { + + @Id + @Column(name = "gathering_applicants_id") + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "gathering_id") + private Gathering gathering; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "user_id") + private User user; + + @Column(name = "gathering_applicants_state") + @Convert(converter = GatheringStatus.class) + private GatheringStatus gatheringStatus; + + public GatheringApplicants(Gathering gathering, User user, GatheringStatus gatheringStatus) { + this.gathering = gathering; + this.user = user; + this.gatheringStatus = gatheringStatus; + } +} From 6071b74a5bcfeca6eb009928c12b986d1dbbcb01 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Fri, 2 Aug 2024 02:46:20 +0900 Subject: [PATCH 033/371] =?UTF-8?q?feat:=20=ED=97=88=EC=9A=A9=20=EC=84=B1?= =?UTF-8?q?=EB=B3=84=20enum=20=ED=81=B4=EB=9E=98=EC=8A=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../solitour/gathering/entity/AllowedSex.java | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 src/main/java/solitour_backend/solitour/gathering/entity/AllowedSex.java diff --git a/src/main/java/solitour_backend/solitour/gathering/entity/AllowedSex.java b/src/main/java/solitour_backend/solitour/gathering/entity/AllowedSex.java new file mode 100644 index 00000000..59be28a7 --- /dev/null +++ b/src/main/java/solitour_backend/solitour/gathering/entity/AllowedSex.java @@ -0,0 +1,25 @@ +package solitour_backend.solitour.gathering.entity; + +import lombok.Getter; + +import java.util.Arrays; + +@Getter +public enum AllowedSex { + MALE("남자"), + FEMALE("여자"), + ALL("성별무관"); + + private final String name; + + AllowedSex(String name) { + this.name = name; + } + + public static AllowedSex fromName(String name) { + return Arrays.stream(AllowedSex.values()) + .filter(e -> e.name.equals(name)) + .findAny() + .orElse(null); + } +} From b1717075975d3f1831737cb4c2c009b7e9ef15e7 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Fri, 2 Aug 2024 02:46:27 +0900 Subject: [PATCH 034/371] =?UTF-8?q?feat:=20=ED=97=88=EC=9A=A9=20=EC=84=B1?= =?UTF-8?q?=EB=B3=84=20enum=20=ED=81=B4=EB=9E=98=EC=8A=A4=20converter?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../gathering/entity/AllowedSexConverter.java | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 src/main/java/solitour_backend/solitour/gathering/entity/AllowedSexConverter.java diff --git a/src/main/java/solitour_backend/solitour/gathering/entity/AllowedSexConverter.java b/src/main/java/solitour_backend/solitour/gathering/entity/AllowedSexConverter.java new file mode 100644 index 00000000..bb3f17d9 --- /dev/null +++ b/src/main/java/solitour_backend/solitour/gathering/entity/AllowedSexConverter.java @@ -0,0 +1,17 @@ +package solitour_backend.solitour.gathering.entity; + +import jakarta.persistence.AttributeConverter; +import jakarta.persistence.Converter; + +@Converter(autoApply = true) +public class AllowedSexConverter implements AttributeConverter { + @Override + public String convertToDatabaseColumn(AllowedSex allowedSex) { + return allowedSex.getName(); + } + + @Override + public AllowedSex convertToEntityAttribute(String dbData) { + return AllowedSex.fromName(dbData); + } +} From 1f73ac4b87f4a487f6a314de8a7662b5bae07082 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Fri, 2 Aug 2024 02:46:49 +0900 Subject: [PATCH 035/371] =?UTF-8?q?refactor:=20gathering=20=ED=85=8C?= =?UTF-8?q?=EC=9D=B4=EB=B8=94=20=EC=88=98=EC=A0=95=EC=9C=BC=EB=A1=9C=20?= =?UTF-8?q?=EC=9D=B8=ED=95=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../solitour/gathering/entity/Gathering.java | 74 +++++++++++++++---- 1 file changed, 59 insertions(+), 15 deletions(-) diff --git a/src/main/java/solitour_backend/solitour/gathering/entity/Gathering.java b/src/main/java/solitour_backend/solitour/gathering/entity/Gathering.java index 57740b0e..8dad85d8 100644 --- a/src/main/java/solitour_backend/solitour/gathering/entity/Gathering.java +++ b/src/main/java/solitour_backend/solitour/gathering/entity/Gathering.java @@ -1,19 +1,13 @@ package solitour_backend.solitour.gathering.entity; -import jakarta.persistence.Column; -import jakarta.persistence.Entity; -import jakarta.persistence.FetchType; -import jakarta.persistence.GeneratedValue; -import jakarta.persistence.GenerationType; -import jakarta.persistence.Id; -import jakarta.persistence.JoinColumn; -import jakarta.persistence.ManyToOne; -import jakarta.persistence.Table; +import jakarta.persistence.*; import java.time.LocalDateTime; import lombok.Getter; import lombok.NoArgsConstructor; +import solitour_backend.solitour.gathering_category.entity.GatheringCategory; +import solitour_backend.solitour.place.entity.Place; import solitour_backend.solitour.user.entity.User; import solitour_backend.solitour.zone_category.entity.ZoneCategory; @@ -36,21 +30,71 @@ public class Gathering { @JoinColumn(name = "zone_category_id") private ZoneCategory zoneCategory; + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "gathering_category_id") + private GatheringCategory gatheringCategory; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "place_id") + private Place place; + @Column(name = "gathering_title") private String title; + @Column(name = "gathering_content") + private String content; + @Column(name = "gathering_person_count") private Integer personCount; @Column(name = "gathering_view_count") private Integer viewCount; - @Column(name = "gathering_recent_date") - private LocalDateTime recentDate; + @Column(name = "gathering_created_at") + private LocalDateTime createdAt; - @Column(name = "gathering_is_edited") - private Boolean isEdited; + @Column(name = "gathering_edited_at") + private LocalDateTime editedAt; - @Column(name = "gathering_content") - private String content; + @Column(name = "gathering_schedule_start_date") + private LocalDateTime scheduleStartDate; + + @Column(name = "gathering_schedule_end_date") + private LocalDateTime scheduleEndDate; + + @Column(name = "gathering_is_finish") + private Boolean isFinish; + + @Column(name = "gathering_deadline") + private LocalDateTime deadline; + + @Column(name = "gathering_allowed_sex") + @Convert(converter = AllowedSex.class) + private AllowedSex allowedSex; + + @Column(name = "gathering_start_age") + private Integer startAge; + + @Column(name = "gathering_end_age") + private Integer endAge; + + public Gathering(User user, ZoneCategory zoneCategory, GatheringCategory gatheringCategory, Place place, String title, String content, Integer personCount, Integer viewCount, LocalDateTime createdAt, LocalDateTime editedAt, LocalDateTime scheduleStartDate, LocalDateTime scheduleEndDate, Boolean isFinish, LocalDateTime deadline, AllowedSex allowedSex, Integer startAge, Integer endAge) { + this.user = user; + this.zoneCategory = zoneCategory; + this.gatheringCategory = gatheringCategory; + this.place = place; + this.title = title; + this.content = content; + this.personCount = personCount; + this.viewCount = viewCount; + this.createdAt = createdAt; + this.editedAt = editedAt; + this.scheduleStartDate = scheduleStartDate; + this.scheduleEndDate = scheduleEndDate; + this.isFinish = isFinish; + this.deadline = deadline; + this.allowedSex = allowedSex; + this.startAge = startAge; + this.endAge = endAge; + } } From f1f26cb427d7a678a0fb531a459daee1d6803e93 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Fri, 2 Aug 2024 02:47:05 +0900 Subject: [PATCH 036/371] =?UTF-8?q?refactor:=20BookMarkGathering=20?= =?UTF-8?q?=ED=85=8C=EC=9D=B4=EB=B8=94=20=EC=88=98=EC=A0=95=EC=9C=BC?= =?UTF-8?q?=EB=A1=9C=20=EC=9D=B8=ED=95=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../solitour/book_mark_gathering/entity/BookMarkGathering.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main/java/solitour_backend/solitour/book_mark_gathering/entity/BookMarkGathering.java b/src/main/java/solitour_backend/solitour/book_mark_gathering/entity/BookMarkGathering.java index d4e67757..8cac38be 100644 --- a/src/main/java/solitour_backend/solitour/book_mark_gathering/entity/BookMarkGathering.java +++ b/src/main/java/solitour_backend/solitour/book_mark_gathering/entity/BookMarkGathering.java @@ -33,4 +33,7 @@ public class BookMarkGathering { @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "gathering_id") private Gathering gathering; + + @Column(name = "is_deleted") + private Boolean isDeleted; } From b22e2e0cfea8db3cf251a30551edfca6695b60f4 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Fri, 2 Aug 2024 02:47:18 +0900 Subject: [PATCH 037/371] =?UTF-8?q?refactor:=20GreatGathering=20=ED=85=8C?= =?UTF-8?q?=EC=9D=B4=EB=B8=94=20=EC=88=98=EC=A0=95=EC=9C=BC=EB=A1=9C=20?= =?UTF-8?q?=EC=9D=B8=ED=95=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../solitour/great_gathering/entity/GreatGathering.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main/java/solitour_backend/solitour/great_gathering/entity/GreatGathering.java b/src/main/java/solitour_backend/solitour/great_gathering/entity/GreatGathering.java index 7ed4a264..31ce2ee1 100644 --- a/src/main/java/solitour_backend/solitour/great_gathering/entity/GreatGathering.java +++ b/src/main/java/solitour_backend/solitour/great_gathering/entity/GreatGathering.java @@ -35,4 +35,7 @@ public class GreatGathering { @JoinColumn(name = "gathering_id") private Gathering gathering; + @Column(name = "is_deleted") + private Boolean isDeleted; + } From ba470a0a572b5a280834e5bce6d3169be479d09d Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Sat, 3 Aug 2024 00:51:25 +0900 Subject: [PATCH 038/371] =?UTF-8?q?fix:=20converter=20=EC=96=B4=EB=85=B8?= =?UTF-8?q?=ED=85=8C=EC=9D=B4=EC=85=98=20=EC=95=88=EC=97=90=20=EC=84=A4?= =?UTF-8?q?=EC=A0=95=20converter=EB=A1=9C=20=EC=84=A4=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../solitour_backend/solitour/gathering/entity/Gathering.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/solitour_backend/solitour/gathering/entity/Gathering.java b/src/main/java/solitour_backend/solitour/gathering/entity/Gathering.java index 8dad85d8..96e5d935 100644 --- a/src/main/java/solitour_backend/solitour/gathering/entity/Gathering.java +++ b/src/main/java/solitour_backend/solitour/gathering/entity/Gathering.java @@ -69,7 +69,7 @@ public class Gathering { private LocalDateTime deadline; @Column(name = "gathering_allowed_sex") - @Convert(converter = AllowedSex.class) + @Convert(converter = AllowedSexConverter.class) private AllowedSex allowedSex; @Column(name = "gathering_start_age") From 795060a97e271cc61cf629e032597756a91fa187 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Sat, 3 Aug 2024 00:51:28 +0900 Subject: [PATCH 039/371] =?UTF-8?q?fix:=20converter=20=EC=96=B4=EB=85=B8?= =?UTF-8?q?=ED=85=8C=EC=9D=B4=EC=85=98=20=EC=95=88=EC=97=90=20=EC=84=A4?= =?UTF-8?q?=EC=A0=95=20converter=EB=A1=9C=20=EC=84=A4=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../gathering_applicants/entity/GatheringApplicants.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/solitour_backend/solitour/gathering_applicants/entity/GatheringApplicants.java b/src/main/java/solitour_backend/solitour/gathering_applicants/entity/GatheringApplicants.java index 833f247a..c8d300f5 100644 --- a/src/main/java/solitour_backend/solitour/gathering_applicants/entity/GatheringApplicants.java +++ b/src/main/java/solitour_backend/solitour/gathering_applicants/entity/GatheringApplicants.java @@ -28,7 +28,7 @@ public class GatheringApplicants { private User user; @Column(name = "gathering_applicants_state") - @Convert(converter = GatheringStatus.class) + @Convert(converter = GatheringStatusConverter.class) private GatheringStatus gatheringStatus; public GatheringApplicants(Gathering gathering, User user, GatheringStatus gatheringStatus) { From 900e74fa1bb9a75f8db52d6be187f5c0814a59a7 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Sun, 4 Aug 2024 03:59:03 +0900 Subject: [PATCH 040/371] =?UTF-8?q?refactor:=20=EC=95=88=EC=93=B0=EB=8A=94?= =?UTF-8?q?=20service=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../solitour/info_tag/service/InfoTagService.java | 15 --------------- 1 file changed, 15 deletions(-) delete mode 100644 src/main/java/solitour_backend/solitour/info_tag/service/InfoTagService.java diff --git a/src/main/java/solitour_backend/solitour/info_tag/service/InfoTagService.java b/src/main/java/solitour_backend/solitour/info_tag/service/InfoTagService.java deleted file mode 100644 index 6a9655d2..00000000 --- a/src/main/java/solitour_backend/solitour/info_tag/service/InfoTagService.java +++ /dev/null @@ -1,15 +0,0 @@ -package solitour_backend.solitour.info_tag.service; - -import lombok.RequiredArgsConstructor; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; -import solitour_backend.solitour.info_tag.repository.InfoTagRepository; - -@Service -@Transactional -@RequiredArgsConstructor -public class InfoTagService { - - private final InfoTagRepository infoTagRepository; - -} From fb88d7e442af3f76b7e3ce268d46095ca3d64916 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Sun, 4 Aug 2024 03:59:27 +0900 Subject: [PATCH 041/371] =?UTF-8?q?feat:=20EnableJpaAuditing=20=EC=96=B4?= =?UTF-8?q?=EB=85=B8=ED=85=8C=EC=9D=B4=EC=85=98=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/solitour_backend/solitour/SolitourApplication.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/solitour_backend/solitour/SolitourApplication.java b/src/main/java/solitour_backend/solitour/SolitourApplication.java index 9b34f7aa..f21385ca 100644 --- a/src/main/java/solitour_backend/solitour/SolitourApplication.java +++ b/src/main/java/solitour_backend/solitour/SolitourApplication.java @@ -3,8 +3,10 @@ import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.context.properties.ConfigurationPropertiesScan; +import org.springframework.data.jpa.repository.config.EnableJpaAuditing; @SpringBootApplication +@EnableJpaAuditing @ConfigurationPropertiesScan public class SolitourApplication { From 0a1896860dac4bc559b81db6fc9b8701efb0d4e5 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Sun, 4 Aug 2024 03:59:42 +0900 Subject: [PATCH 042/371] =?UTF-8?q?refactor:=20=EC=BD=94=EB=93=9C=20?= =?UTF-8?q?=EC=A0=95=EB=A0=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../solitour/information/service/InformationService.java | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/main/java/solitour_backend/solitour/information/service/InformationService.java b/src/main/java/solitour_backend/solitour/information/service/InformationService.java index 88193ee2..2651f254 100644 --- a/src/main/java/solitour_backend/solitour/information/service/InformationService.java +++ b/src/main/java/solitour_backend/solitour/information/service/InformationService.java @@ -127,10 +127,8 @@ public InformationResponse registerInformation(InformationRegisterRequest inform Information saveInformation = informationRepository.save(information); LocalDate localDate = LocalDate.now(); - String thumbNailImageUrl = s3Uploader.upload(thumbnail, IMAGE_PATH, - saveInformation.getId()); - Image thumbImage = new Image(ImageStatus.THUMBNAIL, saveInformation, thumbNailImageUrl, - localDate); + String thumbNailImageUrl = s3Uploader.upload(thumbnail, IMAGE_PATH, saveInformation.getId()); + Image thumbImage = new Image(ImageStatus.THUMBNAIL, saveInformation, thumbNailImageUrl, localDate); imageRepository.save(thumbImage); for (MultipartFile multipartFile : contentImages) { From b959a9ac8664c6d986a1139f3588d3538c277180 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Sun, 4 Aug 2024 04:00:38 +0900 Subject: [PATCH 043/371] =?UTF-8?q?feat:=20create,=20update=20=EB=82=A0?= =?UTF-8?q?=EC=A7=9C=20jpa=20=EC=84=A4=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../solitour/gathering/entity/Gathering.java | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/main/java/solitour_backend/solitour/gathering/entity/Gathering.java b/src/main/java/solitour_backend/solitour/gathering/entity/Gathering.java index 96e5d935..fd7b0a75 100644 --- a/src/main/java/solitour_backend/solitour/gathering/entity/Gathering.java +++ b/src/main/java/solitour_backend/solitour/gathering/entity/Gathering.java @@ -6,6 +6,9 @@ import lombok.Getter; import lombok.NoArgsConstructor; +import org.springframework.data.annotation.CreatedDate; +import org.springframework.data.annotation.LastModifiedDate; +import org.springframework.data.jpa.domain.support.AuditingEntityListener; import solitour_backend.solitour.gathering_category.entity.GatheringCategory; import solitour_backend.solitour.place.entity.Place; import solitour_backend.solitour.user.entity.User; @@ -15,6 +18,7 @@ @Getter @Table(name = "gathering") @NoArgsConstructor +@EntityListeners(AuditingEntityListener.class) public class Gathering { @Id @@ -50,9 +54,11 @@ public class Gathering { @Column(name = "gathering_view_count") private Integer viewCount; + @CreatedDate @Column(name = "gathering_created_at") private LocalDateTime createdAt; + @LastModifiedDate @Column(name = "gathering_edited_at") private LocalDateTime editedAt; @@ -78,7 +84,7 @@ public class Gathering { @Column(name = "gathering_end_age") private Integer endAge; - public Gathering(User user, ZoneCategory zoneCategory, GatheringCategory gatheringCategory, Place place, String title, String content, Integer personCount, Integer viewCount, LocalDateTime createdAt, LocalDateTime editedAt, LocalDateTime scheduleStartDate, LocalDateTime scheduleEndDate, Boolean isFinish, LocalDateTime deadline, AllowedSex allowedSex, Integer startAge, Integer endAge) { + public Gathering(User user, ZoneCategory zoneCategory, GatheringCategory gatheringCategory, Place place, String title, String content, Integer personCount, Integer viewCount, LocalDateTime scheduleStartDate, LocalDateTime scheduleEndDate, Boolean isFinish, LocalDateTime deadline, AllowedSex allowedSex, Integer startAge, Integer endAge) { this.user = user; this.zoneCategory = zoneCategory; this.gatheringCategory = gatheringCategory; @@ -87,8 +93,6 @@ public Gathering(User user, ZoneCategory zoneCategory, GatheringCategory gatheri this.content = content; this.personCount = personCount; this.viewCount = viewCount; - this.createdAt = createdAt; - this.editedAt = editedAt; this.scheduleStartDate = scheduleStartDate; this.scheduleEndDate = scheduleEndDate; this.isFinish = isFinish; From 874090017bf38c5ad8e6ced03908e1c4c3d3bd58 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Sun, 4 Aug 2024 04:01:21 +0900 Subject: [PATCH 044/371] =?UTF-8?q?feat:=20gathering=20=EB=93=B1=EB=A1=9D?= =?UTF-8?q?=20request=20dto?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dto/request/GatheringRegisterRequest.java | 67 +++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 src/main/java/solitour_backend/solitour/gathering/dto/request/GatheringRegisterRequest.java diff --git a/src/main/java/solitour_backend/solitour/gathering/dto/request/GatheringRegisterRequest.java b/src/main/java/solitour_backend/solitour/gathering/dto/request/GatheringRegisterRequest.java new file mode 100644 index 00000000..f4832d35 --- /dev/null +++ b/src/main/java/solitour_backend/solitour/gathering/dto/request/GatheringRegisterRequest.java @@ -0,0 +1,67 @@ +package solitour_backend.solitour.gathering.dto.request; + +import com.fasterxml.jackson.annotation.JsonFormat; +import jakarta.validation.constraints.*; +import lombok.Getter; +import lombok.NoArgsConstructor; +import org.springframework.format.annotation.DateTimeFormat; +import solitour_backend.solitour.gathering.entity.AllowedSex; +import solitour_backend.solitour.place.dto.request.PlaceRegisterRequest; +import solitour_backend.solitour.tag.dto.request.TagRegisterRequest; + +import java.time.LocalDateTime; +import java.util.List; + +@Getter +@NoArgsConstructor +public class GatheringRegisterRequest { + @NotBlank + @Size(min = 1, max = 50) + private String title; + private String content; + + @NotNull + @Min(2) + @Max(10) + private Integer personCount; //몇명으로 제한 할 것인지 + + @JsonFormat(pattern = "yyyy-MM-dd HH:mm") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm") + private LocalDateTime scheduleStartDate; + + @JsonFormat(pattern = "yyyy-MM-dd HH:mm") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm") + private LocalDateTime scheduleEndDate; + + @JsonFormat(pattern = "yyyy-MM-dd HH:mm") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm") + private LocalDateTime deadline; + + @NotNull + private AllowedSex allowedSex; + + @NotNull + @Min(20) + private Integer startAge; + + @NotNull + @Min(20) + private Integer endAge; + + @NotNull + private PlaceRegisterRequest placeRegisterRequest; + + @NotNull + @Min(1) + private Long gatheringCategoryId; + + @NotBlank + @Size(min = 1, max = 20) + private String zoneCategoryNameParent; + + @NotBlank + @Size(min = 1, max = 20) + private String zoneCategoryNameChild; + + private List tagRegisterRequests; +} From e6be419505b970356622ce961a95931f8d542749 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Sun, 4 Aug 2024 04:01:55 +0900 Subject: [PATCH 045/371] feat: gathering tag repository --- .../gathering_tag/repository/GatheringTagRepository.java | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 src/main/java/solitour_backend/solitour/gathering_tag/repository/GatheringTagRepository.java diff --git a/src/main/java/solitour_backend/solitour/gathering_tag/repository/GatheringTagRepository.java b/src/main/java/solitour_backend/solitour/gathering_tag/repository/GatheringTagRepository.java new file mode 100644 index 00000000..e38c10a3 --- /dev/null +++ b/src/main/java/solitour_backend/solitour/gathering_tag/repository/GatheringTagRepository.java @@ -0,0 +1,7 @@ +package solitour_backend.solitour.gathering_tag.repository; + +import org.springframework.data.jpa.repository.JpaRepository; +import solitour_backend.solitour.gathering_tag.entity.GatheringTag; + +public interface GatheringTagRepository extends JpaRepository { +} From ca57266ab009532ddb7a07c7c496bcbde1e0c18a Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Sun, 4 Aug 2024 04:02:09 +0900 Subject: [PATCH 046/371] feat: gathering repository --- .../solitour/gathering/repository/GatheringRepository.java | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepository.java diff --git a/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepository.java b/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepository.java new file mode 100644 index 00000000..7ff7fae9 --- /dev/null +++ b/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepository.java @@ -0,0 +1,7 @@ +package solitour_backend.solitour.gathering.repository; + +import org.springframework.data.jpa.repository.JpaRepository; +import solitour_backend.solitour.gathering.entity.Gathering; + +public interface GatheringRepository extends JpaRepository { +} From e08534236385c38edbe0c36017d44e90c78bca3d Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Sun, 4 Aug 2024 04:02:31 +0900 Subject: [PATCH 047/371] feat: gathering response dto --- .../gathering/dto/response/GatheringResponse.java | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 src/main/java/solitour_backend/solitour/gathering/dto/response/GatheringResponse.java diff --git a/src/main/java/solitour_backend/solitour/gathering/dto/response/GatheringResponse.java b/src/main/java/solitour_backend/solitour/gathering/dto/response/GatheringResponse.java new file mode 100644 index 00000000..30a501ed --- /dev/null +++ b/src/main/java/solitour_backend/solitour/gathering/dto/response/GatheringResponse.java @@ -0,0 +1,10 @@ +package solitour_backend.solitour.gathering.dto.response; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor +public class GatheringResponse { + private Long id; +} From 63ee47d63ac74c1f3f93ab224932aa3b4cc4c318 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Sun, 4 Aug 2024 04:02:49 +0900 Subject: [PATCH 048/371] feat: gathering Applicants repository --- .../repository/GatheringApplicantsRepository.java | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 src/main/java/solitour_backend/solitour/gathering_applicants/repository/GatheringApplicantsRepository.java diff --git a/src/main/java/solitour_backend/solitour/gathering_applicants/repository/GatheringApplicantsRepository.java b/src/main/java/solitour_backend/solitour/gathering_applicants/repository/GatheringApplicantsRepository.java new file mode 100644 index 00000000..978ef27f --- /dev/null +++ b/src/main/java/solitour_backend/solitour/gathering_applicants/repository/GatheringApplicantsRepository.java @@ -0,0 +1,7 @@ +package solitour_backend.solitour.gathering_applicants.repository; + +import org.springframework.data.jpa.repository.JpaRepository; +import solitour_backend.solitour.gathering_applicants.entity.GatheringApplicants; + +public interface GatheringApplicantsRepository extends JpaRepository { +} From eb601cadc0cdf55141273a472fcf96d3877f7ec6 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Sun, 4 Aug 2024 04:03:00 +0900 Subject: [PATCH 049/371] feat: gathering mapper --- .../gathering/dto/mapper/GatheringMapper.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 src/main/java/solitour_backend/solitour/gathering/dto/mapper/GatheringMapper.java diff --git a/src/main/java/solitour_backend/solitour/gathering/dto/mapper/GatheringMapper.java b/src/main/java/solitour_backend/solitour/gathering/dto/mapper/GatheringMapper.java new file mode 100644 index 00000000..5737bf83 --- /dev/null +++ b/src/main/java/solitour_backend/solitour/gathering/dto/mapper/GatheringMapper.java @@ -0,0 +1,12 @@ +package solitour_backend.solitour.gathering.dto.mapper; + +import org.mapstruct.Mapper; +import org.mapstruct.ReportingPolicy; +import solitour_backend.solitour.gathering.dto.response.GatheringResponse; +import solitour_backend.solitour.gathering.entity.Gathering; + +@Mapper(componentModel = "spring", unmappedTargetPolicy = ReportingPolicy.ERROR) +public interface GatheringMapper { + GatheringResponse mapToGatheringResponse(Gathering gathering); +} + From 017d7af2744ed07ab762dcd87fa6397a023972a8 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Sun, 4 Aug 2024 04:03:37 +0900 Subject: [PATCH 050/371] =?UTF-8?q?feat:=20gathering=20category=20?= =?UTF-8?q?=EC=A1=B4=EC=9E=AC=ED=95=98=EC=A7=80=20=EC=95=8A=EB=8A=94?= =?UTF-8?q?=EB=8B=A4=EB=8A=94=20exception?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../exception/GatheringCategoryNotExistsException.java | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 src/main/java/solitour_backend/solitour/gathering/exception/GatheringCategoryNotExistsException.java diff --git a/src/main/java/solitour_backend/solitour/gathering/exception/GatheringCategoryNotExistsException.java b/src/main/java/solitour_backend/solitour/gathering/exception/GatheringCategoryNotExistsException.java new file mode 100644 index 00000000..2fd7a390 --- /dev/null +++ b/src/main/java/solitour_backend/solitour/gathering/exception/GatheringCategoryNotExistsException.java @@ -0,0 +1,7 @@ +package solitour_backend.solitour.gathering.exception; + +public class GatheringCategoryNotExistsException extends RuntimeException { + public GatheringCategoryNotExistsException(String message) { + super(message); + } +} From 0228de9125eaf71500e4f95f5b4fa3230558a106 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Sun, 4 Aug 2024 04:03:55 +0900 Subject: [PATCH 051/371] =?UTF-8?q?feat:=20exception=20handler=20=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../solitour/error/GlobalControllerAdvice.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/java/solitour_backend/solitour/error/GlobalControllerAdvice.java b/src/main/java/solitour_backend/solitour/error/GlobalControllerAdvice.java index acf52a3c..5dc23b05 100644 --- a/src/main/java/solitour_backend/solitour/error/GlobalControllerAdvice.java +++ b/src/main/java/solitour_backend/solitour/error/GlobalControllerAdvice.java @@ -6,6 +6,7 @@ import org.springframework.web.bind.annotation.RestControllerAdvice; import solitour_backend.solitour.category.exception.CategoryNotExistsException; import solitour_backend.solitour.error.exception.RequestValidationFailedException; +import solitour_backend.solitour.gathering.exception.GatheringCategoryNotExistsException; import solitour_backend.solitour.image.exception.ImageAlreadyExistsException; import solitour_backend.solitour.image.exception.ImageNotExistsException; import solitour_backend.solitour.image.exception.ImageRequestValidationFailedException; @@ -32,8 +33,8 @@ public ResponseEntity conflictException(Exception exception) { } @ExceptionHandler({ZoneCategoryNotExistsException.class, ImageNotExistsException.class, - CategoryNotExistsException.class, InformationNotExistsException.class, UserNotExistsException.class,}) - public ResponseEntity exception(Exception exception) { + CategoryNotExistsException.class, InformationNotExistsException.class, UserNotExistsException.class, GatheringCategoryNotExistsException.class}) + public ResponseEntity notFoundException(Exception exception) { return ResponseEntity .status(HttpStatus.NOT_FOUND) .body(exception.getMessage()); From 9b93c250326d79c5e0defa8bf7ab68a4a57d4c1c Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Sun, 4 Aug 2024 04:04:16 +0900 Subject: [PATCH 052/371] =?UTF-8?q?feat:=20gathering=20service,=20?= =?UTF-8?q?=EB=93=B1=EB=A1=9D=20=EB=A9=94=EC=84=9C=EB=93=9C=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../gathering/service/GatheringService.java | 104 ++++++++++++++++++ 1 file changed, 104 insertions(+) create mode 100644 src/main/java/solitour_backend/solitour/gathering/service/GatheringService.java diff --git a/src/main/java/solitour_backend/solitour/gathering/service/GatheringService.java b/src/main/java/solitour_backend/solitour/gathering/service/GatheringService.java new file mode 100644 index 00000000..9c2d5cb3 --- /dev/null +++ b/src/main/java/solitour_backend/solitour/gathering/service/GatheringService.java @@ -0,0 +1,104 @@ +package solitour_backend.solitour.gathering.service; + +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import solitour_backend.solitour.gathering.dto.mapper.GatheringMapper; +import solitour_backend.solitour.gathering.dto.request.GatheringRegisterRequest; +import solitour_backend.solitour.gathering.dto.response.GatheringResponse; +import solitour_backend.solitour.gathering.entity.Gathering; +import solitour_backend.solitour.gathering.exception.GatheringCategoryNotExistsException; +import solitour_backend.solitour.gathering.repository.GatheringRepository; +import solitour_backend.solitour.gathering_category.entity.GatheringCategory; +import solitour_backend.solitour.gathering_category.repository.GatheringCategoryRepository; +import solitour_backend.solitour.gathering_tag.entity.GatheringTag; +import solitour_backend.solitour.gathering_tag.repository.GatheringTagRepository; +import solitour_backend.solitour.place.dto.request.PlaceRegisterRequest; +import solitour_backend.solitour.place.entity.Place; +import solitour_backend.solitour.place.repository.PlaceRepository; +import solitour_backend.solitour.tag.dto.mapper.TagMapper; +import solitour_backend.solitour.tag.entity.Tag; +import solitour_backend.solitour.tag.repository.TagRepository; +import solitour_backend.solitour.user.entity.User; +import solitour_backend.solitour.user.entity.UserRepository; +import solitour_backend.solitour.user.exception.UserNotExistsException; +import solitour_backend.solitour.zone_category.entity.ZoneCategory; +import solitour_backend.solitour.zone_category.exception.ZoneCategoryNotExistsException; +import solitour_backend.solitour.zone_category.repository.ZoneCategoryRepository; + +import java.util.List; + +@Service +@Transactional(readOnly = true) +@RequiredArgsConstructor +public class GatheringService { + private final GatheringRepository gatheringRepository; + private final UserRepository userRepository; + private final ZoneCategoryRepository zoneCategoryRepository; + private final PlaceRepository placeRepository; + private final GatheringCategoryRepository gatheringCategoryRepository; + private final TagMapper tagMapper; + private final TagRepository tagRepository; + private final GatheringTagRepository gatheringTagRepository; + private final GatheringMapper gatheringMapper; + + @Transactional + public GatheringResponse registerGathering(Long userId, GatheringRegisterRequest gatheringRegisterRequest) { + PlaceRegisterRequest placeRegisterRequest = gatheringRegisterRequest.getPlaceRegisterRequest(); + Place place = new Place( + placeRegisterRequest.getSearchId(), + placeRegisterRequest.getName(), + placeRegisterRequest.getXAxis(), + placeRegisterRequest.getYAxis(), + placeRegisterRequest.getAddress()); + + Place savePlace = placeRepository.save(place); + User user = userRepository.findById(userId) + .orElseThrow( + () -> new UserNotExistsException("해당하는 id의 User 가 없습니다")); + GatheringCategory gatheringCategory = gatheringCategoryRepository.findById( + gatheringRegisterRequest.getGatheringCategoryId()) + .orElseThrow( + () -> new GatheringCategoryNotExistsException("해당하는 id의 category 가 없습니다")); + + ZoneCategory parentZoneCategory = zoneCategoryRepository.findByParentZoneCategoryIdAndName( + null, gatheringRegisterRequest.getZoneCategoryNameParent()) + .orElseThrow( + () -> + new ZoneCategoryNotExistsException("해당하는 name의 ZoneCategory 없습니다")); + + ZoneCategory childZoneCategory = zoneCategoryRepository.findByParentZoneCategoryIdAndName( + parentZoneCategory.getId(), gatheringRegisterRequest.getZoneCategoryNameChild()) + .orElseThrow( + () -> new ZoneCategoryNotExistsException("해당하는 name의 ZoneCategory 없습니다")); + + Gathering gathering = + new Gathering( + user, + childZoneCategory, + gatheringCategory, + savePlace, + gatheringRegisterRequest.getTitle(), + gatheringRegisterRequest.getContent(), + gatheringRegisterRequest.getPersonCount(), + 0, + gatheringRegisterRequest.getScheduleStartDate(), + gatheringRegisterRequest.getScheduleEndDate(), + false, + gatheringRegisterRequest.getDeadline(), + gatheringRegisterRequest.getAllowedSex(), + gatheringRegisterRequest.getStartAge(), + gatheringRegisterRequest.getEndAge() + ); + Gathering saveGathering = gatheringRepository.save(gathering); + + List tags = tagMapper.mapToTags(gatheringRegisterRequest.getTagRegisterRequests()); + List saveTags = tagRepository.saveAll(tags); + + for (Tag tag : saveTags) { + gatheringTagRepository.save(new GatheringTag(tag, saveGathering)); + } + return gatheringMapper.mapToGatheringResponse(saveGathering); + } + +} From 162da07de233e63106054e6559742262572c9c70 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Sun, 4 Aug 2024 04:04:31 +0900 Subject: [PATCH 053/371] =?UTF-8?q?feat:=20gathering=20=EB=93=B1=EB=A1=9D?= =?UTF-8?q?=20api?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/GatheringController.java | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 src/main/java/solitour_backend/solitour/gathering/controller/GatheringController.java diff --git a/src/main/java/solitour_backend/solitour/gathering/controller/GatheringController.java b/src/main/java/solitour_backend/solitour/gathering/controller/GatheringController.java new file mode 100644 index 00000000..053d985b --- /dev/null +++ b/src/main/java/solitour_backend/solitour/gathering/controller/GatheringController.java @@ -0,0 +1,38 @@ +package solitour_backend.solitour.gathering.controller; + +import jakarta.validation.Valid; +import lombok.RequiredArgsConstructor; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.validation.BindingResult; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import solitour_backend.solitour.auth.config.AuthenticationPrincipal; +import solitour_backend.solitour.error.Utils; +import solitour_backend.solitour.gathering.dto.request.GatheringRegisterRequest; +import solitour_backend.solitour.gathering.dto.response.GatheringResponse; +import solitour_backend.solitour.gathering.service.GatheringService; + +@RestController +@RequiredArgsConstructor +@RequestMapping("/api/gatherings") +public class GatheringController { + private final GatheringService gatheringService; + + @PostMapping + public ResponseEntity createGathering(@AuthenticationPrincipal Long userId, + @Valid @RequestBody GatheringRegisterRequest gatheringRegisterRequest, + BindingResult bindingResult) { + Utils.validationRequest(bindingResult); + + GatheringResponse gatheringResponse = gatheringService.registerGathering(userId, gatheringRegisterRequest); + + return ResponseEntity + .status(HttpStatus.CREATED) + .body(gatheringResponse); + } + + +} From 3154df92459449ab843f39663019b5d524512d1e Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Sun, 4 Aug 2024 15:47:17 +0900 Subject: [PATCH 054/371] =?UTF-8?q?feat:=20enum=20=EA=B0=92=20=EC=88=98?= =?UTF-8?q?=EC=A0=95=20ex)=20=EB=82=A8=EC=9E=90=20->=20male?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../solitour/gathering/entity/AllowedSex.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/solitour_backend/solitour/gathering/entity/AllowedSex.java b/src/main/java/solitour_backend/solitour/gathering/entity/AllowedSex.java index 59be28a7..73252417 100644 --- a/src/main/java/solitour_backend/solitour/gathering/entity/AllowedSex.java +++ b/src/main/java/solitour_backend/solitour/gathering/entity/AllowedSex.java @@ -6,9 +6,9 @@ @Getter public enum AllowedSex { - MALE("남자"), - FEMALE("여자"), - ALL("성별무관"); + MALE("male"), + FEMALE("female"), + ALL("all"); private final String name; From 64edff8e83c153ef58440611b78261a32730cd8e Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Sun, 4 Aug 2024 15:47:33 +0900 Subject: [PATCH 055/371] feat: validation --- .../gathering/controller/GatheringController.java | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/main/java/solitour_backend/solitour/gathering/controller/GatheringController.java b/src/main/java/solitour_backend/solitour/gathering/controller/GatheringController.java index 053d985b..76bc5fee 100644 --- a/src/main/java/solitour_backend/solitour/gathering/controller/GatheringController.java +++ b/src/main/java/solitour_backend/solitour/gathering/controller/GatheringController.java @@ -11,10 +11,13 @@ import org.springframework.web.bind.annotation.RestController; import solitour_backend.solitour.auth.config.AuthenticationPrincipal; import solitour_backend.solitour.error.Utils; +import solitour_backend.solitour.error.exception.RequestValidationFailedException; import solitour_backend.solitour.gathering.dto.request.GatheringRegisterRequest; import solitour_backend.solitour.gathering.dto.response.GatheringResponse; import solitour_backend.solitour.gathering.service.GatheringService; +import java.time.LocalDateTime; + @RestController @RequiredArgsConstructor @RequestMapping("/api/gatherings") @@ -27,6 +30,17 @@ public ResponseEntity createGathering(@AuthenticationPrincipa BindingResult bindingResult) { Utils.validationRequest(bindingResult); + if (gatheringRegisterRequest.getEndAge() > gatheringRegisterRequest.getStartAge()) { + throw new RequestValidationFailedException("시작 나이 연도가 끝 나이 연도 보다 앞에 있네요"); + } + if (gatheringRegisterRequest.getScheduleStartDate().isAfter(gatheringRegisterRequest.getScheduleEndDate())) { + throw new RequestValidationFailedException("시작 날짜는 종료 날짜보다 앞에 있어야 합니다."); + } + + if (gatheringRegisterRequest.getDeadline().isBefore(LocalDateTime.now())) { + throw new RequestValidationFailedException("마감일은 현재 시간보다 이후여야 합니다."); + } + GatheringResponse gatheringResponse = gatheringService.registerGathering(userId, gatheringRegisterRequest); return ResponseEntity From 77d21c5c879de48fa36c3902dd8f9ac620821a9d Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Tue, 6 Aug 2024 02:50:58 +0900 Subject: [PATCH 056/371] =?UTF-8?q?feat:=20user=20gathering=20=EC=A0=95?= =?UTF-8?q?=EB=B3=B4=20response=20dto?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../user/dto/response/UserGatheringResponse.java | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 src/main/java/solitour_backend/solitour/user/dto/response/UserGatheringResponse.java diff --git a/src/main/java/solitour_backend/solitour/user/dto/response/UserGatheringResponse.java b/src/main/java/solitour_backend/solitour/user/dto/response/UserGatheringResponse.java new file mode 100644 index 00000000..7a6aaf9e --- /dev/null +++ b/src/main/java/solitour_backend/solitour/user/dto/response/UserGatheringResponse.java @@ -0,0 +1,13 @@ +package solitour_backend.solitour.user.dto.response; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor +public class UserGatheringResponse { + private String profileUrl; + private String nickname; + private Integer age; + private String sex; +} From 5b0b3ff8b1f13afa8d3f370a2858fc46102e3579 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Tue, 6 Aug 2024 02:51:16 +0900 Subject: [PATCH 057/371] =?UTF-8?q?feat:=20=EB=AA=A8=EC=9E=84=20=EC=A2=8B?= =?UTF-8?q?=EC=95=84=EC=9A=94=20repository?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../repository/GreatGatheringRepository.java | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 src/main/java/solitour_backend/solitour/great_gathering/repository/GreatGatheringRepository.java diff --git a/src/main/java/solitour_backend/solitour/great_gathering/repository/GreatGatheringRepository.java b/src/main/java/solitour_backend/solitour/great_gathering/repository/GreatGatheringRepository.java new file mode 100644 index 00000000..c9f8eb3c --- /dev/null +++ b/src/main/java/solitour_backend/solitour/great_gathering/repository/GreatGatheringRepository.java @@ -0,0 +1,11 @@ +package solitour_backend.solitour.great_gathering.repository; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import solitour_backend.solitour.great_gathering.entity.GreatGathering; + +public interface GreatGatheringRepository extends JpaRepository { + + @Query("SELECT COUNT(g) FROM GreatGathering g WHERE g.gathering.id = :gatheringId") + int countByGatheringId(Long gatheringId); +} From 696cbcef901339dc00e79abf530347e118bcc377 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Tue, 6 Aug 2024 02:51:41 +0900 Subject: [PATCH 058/371] =?UTF-8?q?feat:=20gathering=20=EC=9D=B4=20?= =?UTF-8?q?=EC=A1=B4=EC=9E=AC=ED=95=98=EC=A7=80=20=EC=95=8A=EB=8A=94=20exc?= =?UTF-8?q?eption?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../gathering/exception/GatheringNotExistsException.java | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 src/main/java/solitour_backend/solitour/gathering/exception/GatheringNotExistsException.java diff --git a/src/main/java/solitour_backend/solitour/gathering/exception/GatheringNotExistsException.java b/src/main/java/solitour_backend/solitour/gathering/exception/GatheringNotExistsException.java new file mode 100644 index 00000000..5d2aa1c1 --- /dev/null +++ b/src/main/java/solitour_backend/solitour/gathering/exception/GatheringNotExistsException.java @@ -0,0 +1,7 @@ +package solitour_backend.solitour.gathering.exception; + +public class GatheringNotExistsException extends RuntimeException { + public GatheringNotExistsException(String message) { + super(message); + } +} From 0762dd181006da4accc13756d2f4a2a93a97f953 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Tue, 6 Aug 2024 02:52:04 +0900 Subject: [PATCH 059/371] feat: user mapper --- .../solitour/user/dto/mapper/UserMapper.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/main/java/solitour_backend/solitour/user/dto/mapper/UserMapper.java b/src/main/java/solitour_backend/solitour/user/dto/mapper/UserMapper.java index 6c2cf460..67f66d58 100644 --- a/src/main/java/solitour_backend/solitour/user/dto/mapper/UserMapper.java +++ b/src/main/java/solitour_backend/solitour/user/dto/mapper/UserMapper.java @@ -1,12 +1,17 @@ package solitour_backend.solitour.user.dto.mapper; import org.mapstruct.Mapper; +import org.mapstruct.Mapping; import org.mapstruct.ReportingPolicy; import solitour_backend.solitour.user.dto.UserPostingResponse; +import solitour_backend.solitour.user.dto.response.UserGatheringResponse; import solitour_backend.solitour.user.entity.User; @Mapper(componentModel = "spring", unmappedTargetPolicy = ReportingPolicy.ERROR) public interface UserMapper { UserPostingResponse mapToUserPostingResponse(User user); + + @Mapping(source = "userImage.address", target = "profileUrl") + UserGatheringResponse mapToUserGatheringResponse(User user); } From 7eac5996c528bb98816ce42d73fea8677b9ffee1 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Tue, 6 Aug 2024 02:52:20 +0900 Subject: [PATCH 060/371] =?UTF-8?q?feat:=20=EB=AA=A8=EC=9E=84=EC=9D=B4=20?= =?UTF-8?q?=EC=97=86=EB=8A=94=20exception=20=EB=93=B1=EB=A1=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../solitour/error/GlobalControllerAdvice.java | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/main/java/solitour_backend/solitour/error/GlobalControllerAdvice.java b/src/main/java/solitour_backend/solitour/error/GlobalControllerAdvice.java index 5dc23b05..a9c6d7de 100644 --- a/src/main/java/solitour_backend/solitour/error/GlobalControllerAdvice.java +++ b/src/main/java/solitour_backend/solitour/error/GlobalControllerAdvice.java @@ -7,6 +7,7 @@ import solitour_backend.solitour.category.exception.CategoryNotExistsException; import solitour_backend.solitour.error.exception.RequestValidationFailedException; import solitour_backend.solitour.gathering.exception.GatheringCategoryNotExistsException; +import solitour_backend.solitour.gathering.exception.GatheringNotExistsException; import solitour_backend.solitour.image.exception.ImageAlreadyExistsException; import solitour_backend.solitour.image.exception.ImageNotExistsException; import solitour_backend.solitour.image.exception.ImageRequestValidationFailedException; @@ -32,8 +33,14 @@ public ResponseEntity conflictException(Exception exception) { .body(exception.getMessage()); } - @ExceptionHandler({ZoneCategoryNotExistsException.class, ImageNotExistsException.class, - CategoryNotExistsException.class, InformationNotExistsException.class, UserNotExistsException.class, GatheringCategoryNotExistsException.class}) + @ExceptionHandler({ + ZoneCategoryNotExistsException.class, + ImageNotExistsException.class, + CategoryNotExistsException.class, + InformationNotExistsException.class, + UserNotExistsException.class, + GatheringCategoryNotExistsException.class, + GatheringNotExistsException.class}) public ResponseEntity notFoundException(Exception exception) { return ResponseEntity .status(HttpStatus.NOT_FOUND) From 4a31f706c476bcd1401816582c7afe34075f19ce Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Tue, 6 Aug 2024 02:52:52 +0900 Subject: [PATCH 061/371] =?UTF-8?q?refactor:=20enum=20=ED=81=B4=EB=9E=98?= =?UTF-8?q?=EC=8A=A4=20=EB=8D=B0=EC=9D=B4=ED=84=B0=20=ED=95=9C=EA=B8=80?= =?UTF-8?q?=EC=97=90=EC=84=9C=20=EC=98=81=EC=96=B4=EB=A1=9C=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 --- .../gathering_applicants/entity/GatheringStatus.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/solitour_backend/solitour/gathering_applicants/entity/GatheringStatus.java b/src/main/java/solitour_backend/solitour/gathering_applicants/entity/GatheringStatus.java index 3d46ac64..403b4c36 100644 --- a/src/main/java/solitour_backend/solitour/gathering_applicants/entity/GatheringStatus.java +++ b/src/main/java/solitour_backend/solitour/gathering_applicants/entity/GatheringStatus.java @@ -6,9 +6,9 @@ @Getter public enum GatheringStatus { - WAIT("대기"), - CONSENT("승낙"), - REFUSE("거절"); + WAIT("wait"), + CONSENT("consent"), + REFUSE("refuse"); private final String name; From fb93ceaed5de12e8457f7e74a5e3d9cbc2537bf2 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Tue, 6 Aug 2024 02:53:17 +0900 Subject: [PATCH 062/371] feat: gathering applicants response dto --- .../dto/response/GatheringApplicantsResponse.java | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 src/main/java/solitour_backend/solitour/gathering_applicants/dto/response/GatheringApplicantsResponse.java diff --git a/src/main/java/solitour_backend/solitour/gathering_applicants/dto/response/GatheringApplicantsResponse.java b/src/main/java/solitour_backend/solitour/gathering_applicants/dto/response/GatheringApplicantsResponse.java new file mode 100644 index 00000000..f7d0fd7a --- /dev/null +++ b/src/main/java/solitour_backend/solitour/gathering_applicants/dto/response/GatheringApplicantsResponse.java @@ -0,0 +1,13 @@ +package solitour_backend.solitour.gathering_applicants.dto.response; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import solitour_backend.solitour.gathering_applicants.entity.GatheringStatus; +import solitour_backend.solitour.user.dto.response.UserGatheringResponse; + +@Getter +@AllArgsConstructor +public class GatheringApplicantsResponse { + private UserGatheringResponse userGatheringResponse; + private GatheringStatus gatheringStatus; +} From 92472cfd129c38952eca54cce7ef5cb57d18fbc1 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Tue, 6 Aug 2024 02:53:29 +0900 Subject: [PATCH 063/371] feat: gathering applicants mapper --- .../dto/mapper/GatheringApplicantsMapper.java | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 src/main/java/solitour_backend/solitour/gathering_applicants/dto/mapper/GatheringApplicantsMapper.java diff --git a/src/main/java/solitour_backend/solitour/gathering_applicants/dto/mapper/GatheringApplicantsMapper.java b/src/main/java/solitour_backend/solitour/gathering_applicants/dto/mapper/GatheringApplicantsMapper.java new file mode 100644 index 00000000..f02f72ae --- /dev/null +++ b/src/main/java/solitour_backend/solitour/gathering_applicants/dto/mapper/GatheringApplicantsMapper.java @@ -0,0 +1,19 @@ +package solitour_backend.solitour.gathering_applicants.dto.mapper; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.ReportingPolicy; +import solitour_backend.solitour.gathering_applicants.dto.response.GatheringApplicantsResponse; +import solitour_backend.solitour.gathering_applicants.entity.GatheringApplicants; +import solitour_backend.solitour.user.dto.mapper.UserMapper; + +import java.util.List; + +@Mapper(componentModel = "spring", unmappedTargetPolicy = ReportingPolicy.ERROR, uses = UserMapper.class) +public interface GatheringApplicantsMapper { + + @Mapping(source = "user", target = "userGatheringResponse") + GatheringApplicantsResponse mapToGatheringApplicantsResponse(GatheringApplicants gatheringApplicants); + + List mapToGatheringApplicantsResponses(List gatheringApplicants); +} From 2b6771bb7d357d111d2876245340affc4fcf786d Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Tue, 6 Aug 2024 02:54:06 +0900 Subject: [PATCH 064/371] =?UTF-8?q?feat:=20gathering=20id=EB=A1=9C=20gathe?= =?UTF-8?q?ringTag=20list=20=EC=B0=BE=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../gathering_tag/repository/GatheringTagRepository.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main/java/solitour_backend/solitour/gathering_tag/repository/GatheringTagRepository.java b/src/main/java/solitour_backend/solitour/gathering_tag/repository/GatheringTagRepository.java index e38c10a3..96e08e2d 100644 --- a/src/main/java/solitour_backend/solitour/gathering_tag/repository/GatheringTagRepository.java +++ b/src/main/java/solitour_backend/solitour/gathering_tag/repository/GatheringTagRepository.java @@ -3,5 +3,8 @@ import org.springframework.data.jpa.repository.JpaRepository; import solitour_backend.solitour.gathering_tag.entity.GatheringTag; +import java.util.List; + public interface GatheringTagRepository extends JpaRepository { + List findAllByGathering_Id(Long gatheringId); } From 1b930f8979c636400477d9975bfa667394786359 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Tue, 6 Aug 2024 02:54:32 +0900 Subject: [PATCH 065/371] feat: gathering Repository extends custom --- .../solitour/gathering/repository/GatheringRepository.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepository.java b/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepository.java index 7ff7fae9..8efacbe3 100644 --- a/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepository.java +++ b/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepository.java @@ -3,5 +3,5 @@ import org.springframework.data.jpa.repository.JpaRepository; import solitour_backend.solitour.gathering.entity.Gathering; -public interface GatheringRepository extends JpaRepository { +public interface GatheringRepository extends JpaRepository, GatheringRepositoryCustom { } From f19abbb75df14fd3bbec27f951afd0a218a4ed72 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Tue, 6 Aug 2024 02:54:55 +0900 Subject: [PATCH 066/371] =?UTF-8?q?feat:=20gathering=20=EC=9A=94=EC=95=BD?= =?UTF-8?q?=20response=20dto?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dto/response/GatheringBriefResponse.java | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 src/main/java/solitour_backend/solitour/gathering/dto/response/GatheringBriefResponse.java diff --git a/src/main/java/solitour_backend/solitour/gathering/dto/response/GatheringBriefResponse.java b/src/main/java/solitour_backend/solitour/gathering/dto/response/GatheringBriefResponse.java new file mode 100644 index 00000000..72f033f9 --- /dev/null +++ b/src/main/java/solitour_backend/solitour/gathering/dto/response/GatheringBriefResponse.java @@ -0,0 +1,36 @@ +package solitour_backend.solitour.gathering.dto.response; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import solitour_backend.solitour.gathering.entity.AllowedSex; + +import java.time.LocalDateTime; + +@Getter +@AllArgsConstructor +public class GatheringBriefResponse { + private Long gatheringId; + private String title; + private String zoneCategoryParentName; + private String zoneCategoryChildName; + private Integer viewCount; + private Boolean isBookMark; + private Integer likeCount; + + private String gatheringCategoryName; + private String userName; + + private LocalDateTime scheduleStartDate; + private LocalDateTime scheduleEndDate; + + private LocalDateTime deadline; + + private AllowedSex allowedSex; + + private Integer startAge; + private Integer endAge; + private Integer personCount; + private Integer nowPersonCount; + + +} From c5a75bc715398f8c7096d3b64344e455d01c09ed Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Tue, 6 Aug 2024 02:55:04 +0900 Subject: [PATCH 067/371] =?UTF-8?q?feat:=20gathering=20=EC=83=81=EC=84=B8?= =?UTF-8?q?=20response=20dto?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dto/response/GatheringDetailResponse.java | 45 +++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 src/main/java/solitour_backend/solitour/gathering/dto/response/GatheringDetailResponse.java diff --git a/src/main/java/solitour_backend/solitour/gathering/dto/response/GatheringDetailResponse.java b/src/main/java/solitour_backend/solitour/gathering/dto/response/GatheringDetailResponse.java new file mode 100644 index 00000000..492b08ed --- /dev/null +++ b/src/main/java/solitour_backend/solitour/gathering/dto/response/GatheringDetailResponse.java @@ -0,0 +1,45 @@ +package solitour_backend.solitour.gathering.dto.response; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import solitour_backend.solitour.gathering.entity.AllowedSex; +import solitour_backend.solitour.gathering_applicants.dto.response.GatheringApplicantsResponse; +import solitour_backend.solitour.place.dto.response.PlaceResponse; +import solitour_backend.solitour.tag.dto.response.TagResponse; +import solitour_backend.solitour.user.dto.UserPostingResponse; +import solitour_backend.solitour.zone_category.dto.response.ZoneCategoryResponse; + +import java.time.LocalDateTime; +import java.util.List; + +@Getter +@AllArgsConstructor +public class GatheringDetailResponse { + private String title; + private String content; + private Integer personCount; + private Integer viewCount; + private LocalDateTime createdAt; + + private LocalDateTime scheduleStartDate; + private LocalDateTime scheduleEndDate; + private LocalDateTime deadline; + private Boolean isFinish; + + private AllowedSex allowedSex; + private Integer startAge; + private Integer endAge; + + private List tagResponses; + + private UserPostingResponse userPostingResponse; + private PlaceResponse placeResponse; + private ZoneCategoryResponse zoneCategoryResponse; + + private Integer likeCount; + private Integer nowPersonCount; + + private List gatheringApplicantsResponses; + + private List gatheringRecommend; +} From 73f93e8e03f515f703976928f400ac879fdfcc5b Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Tue, 6 Aug 2024 02:55:19 +0900 Subject: [PATCH 068/371] feat: gathering repository custom interface --- .../repository/GatheringRepositoryCustom.java | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryCustom.java diff --git a/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryCustom.java b/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryCustom.java new file mode 100644 index 00000000..def6f2d9 --- /dev/null +++ b/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryCustom.java @@ -0,0 +1,11 @@ +package solitour_backend.solitour.gathering.repository; + +import org.springframework.data.repository.NoRepositoryBean; +import solitour_backend.solitour.gathering.dto.response.GatheringBriefResponse; + +import java.util.List; + +@NoRepositoryBean +public interface GatheringRepositoryCustom { + List getGatheringRecommend(Long informationId, Long gatheringCategoryId, Long userId); +} From 6569280bda06df53d2fe76f66e011ac84275d383 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Tue, 6 Aug 2024 02:56:19 +0900 Subject: [PATCH 069/371] feat: gathering applicants repository --- .../repository/GatheringApplicantsRepository.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/main/java/solitour_backend/solitour/gathering_applicants/repository/GatheringApplicantsRepository.java b/src/main/java/solitour_backend/solitour/gathering_applicants/repository/GatheringApplicantsRepository.java index 978ef27f..8ecb3d53 100644 --- a/src/main/java/solitour_backend/solitour/gathering_applicants/repository/GatheringApplicantsRepository.java +++ b/src/main/java/solitour_backend/solitour/gathering_applicants/repository/GatheringApplicantsRepository.java @@ -2,6 +2,12 @@ import org.springframework.data.jpa.repository.JpaRepository; import solitour_backend.solitour.gathering_applicants.entity.GatheringApplicants; +import solitour_backend.solitour.gathering_applicants.entity.GatheringStatus; + +import java.util.List; public interface GatheringApplicantsRepository extends JpaRepository { + List findAllByGathering_Id(Long id); + + int countAllByGathering_IdAndGatheringStatus(Long id, GatheringStatus gatheringStatus); } From 1f609afdf3b17fa2efda33e939ddf445d908a445 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Tue, 6 Aug 2024 02:56:42 +0900 Subject: [PATCH 070/371] feat: gathering repository impl --- .../repository/GatheringRepositoryImpl.java | 70 +++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryImpl.java diff --git a/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryImpl.java b/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryImpl.java new file mode 100644 index 00000000..4336dfd1 --- /dev/null +++ b/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryImpl.java @@ -0,0 +1,70 @@ +package solitour_backend.solitour.gathering.repository; + +import com.querydsl.core.types.Projections; +import org.springframework.data.jpa.repository.support.QuerydslRepositorySupport; +import solitour_backend.solitour.book_mark_gathering.entity.QBookMarkGathering; +import solitour_backend.solitour.gathering.dto.response.GatheringBriefResponse; +import solitour_backend.solitour.gathering.entity.Gathering; +import solitour_backend.solitour.gathering.entity.QGathering; +import solitour_backend.solitour.gathering_applicants.entity.GatheringStatus; +import solitour_backend.solitour.gathering_applicants.entity.QGatheringApplicants; +import solitour_backend.solitour.gathering_category.entity.QGatheringCategory; +import solitour_backend.solitour.great_gathering.entity.QGreatGathering; +import solitour_backend.solitour.zone_category.entity.QZoneCategory; + +import java.util.List; + +public class GatheringRepositoryImpl extends QuerydslRepositorySupport implements GatheringRepositoryCustom { + public GatheringRepositoryImpl() { + super(Gathering.class); + } + + QGathering gathering = QGathering.gathering; + QZoneCategory zoneCategoryChild = QZoneCategory.zoneCategory; + QZoneCategory zoneCategoryParent = new QZoneCategory("zoneCategoryParent"); + QBookMarkGathering bookMarkGathering = QBookMarkGathering.bookMarkGathering; + QGreatGathering greatGathering = QGreatGathering.greatGathering; + QGatheringCategory category = QGatheringCategory.gatheringCategory; + QGatheringApplicants gatheringApplicants = QGatheringApplicants.gatheringApplicants; + + + @Override + public List getGatheringRecommend(Long gatheringId, Long gatheringCategoryId, Long userId) { + return from(gathering) + .join(zoneCategoryChild).on(zoneCategoryChild.id.eq(gathering.zoneCategory.id)) + .leftJoin(zoneCategoryParent).on(zoneCategoryParent.id.eq(zoneCategoryChild.parentZoneCategory.id)) + .leftJoin(bookMarkGathering).on(bookMarkGathering.gathering.id.eq(gathering.id).and(bookMarkGathering.user.id.eq(userId))) + .leftJoin(greatGathering).on(greatGathering.gathering.id.eq(gathering.id)) + .leftJoin(category).on(category.id.eq(gathering.gatheringCategory.id)) + .leftJoin(gatheringApplicants).on(gatheringApplicants.gathering.id.eq(gathering.id)) + .where(gathering.isFinish.eq(Boolean.FALSE) + .and(gathering.gatheringCategory.id.eq(gatheringCategoryId)) + .and(gathering.id.ne(gatheringId)) + .and(gatheringApplicants.gatheringStatus.eq(GatheringStatus.CONSENT).or(gatheringApplicants.gatheringStatus.isNull())) + ) + .groupBy(gathering.id, zoneCategoryChild.id, zoneCategoryParent.id, category.id) + .orderBy(gathering.createdAt.desc()) + .select(Projections.constructor( + GatheringBriefResponse.class, + gathering.id, + gathering.title, + zoneCategoryParent.name, + zoneCategoryChild.name, + gathering.viewCount, + bookMarkGathering.user.id.isNotNull(), + greatGathering.gathering.count().coalesce(0L).intValue(), + category.name, + gathering.user.name, + gathering.scheduleStartDate, + gathering.scheduleEndDate, + gathering.deadline, + gathering.allowedSex, + gathering.startAge, + gathering.endAge, + gathering.personCount, + gatheringApplicants.count().coalesce(0L).intValue() + )).limit(3L).fetch(); + } + + +} From 92f7a2a37318c9bc7cbe78942c340a4550e18539 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Tue, 6 Aug 2024 02:57:06 +0900 Subject: [PATCH 071/371] =?UTF-8?q?feat:=20gathering=20=EC=83=81=EC=84=B8?= =?UTF-8?q?=20=ED=8E=98=EC=9D=B4=EC=A7=80=20=EC=A1=B0=ED=9A=8C=20service?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../gathering/service/GatheringService.java | 77 +++++++++++++++++++ 1 file changed, 77 insertions(+) diff --git a/src/main/java/solitour_backend/solitour/gathering/service/GatheringService.java b/src/main/java/solitour_backend/solitour/gathering/service/GatheringService.java index 9c2d5cb3..9d10ad4d 100644 --- a/src/main/java/solitour_backend/solitour/gathering/service/GatheringService.java +++ b/src/main/java/solitour_backend/solitour/gathering/service/GatheringService.java @@ -5,27 +5,43 @@ import org.springframework.transaction.annotation.Transactional; import solitour_backend.solitour.gathering.dto.mapper.GatheringMapper; import solitour_backend.solitour.gathering.dto.request.GatheringRegisterRequest; +import solitour_backend.solitour.gathering.dto.response.GatheringBriefResponse; +import solitour_backend.solitour.gathering.dto.response.GatheringDetailResponse; import solitour_backend.solitour.gathering.dto.response.GatheringResponse; import solitour_backend.solitour.gathering.entity.Gathering; import solitour_backend.solitour.gathering.exception.GatheringCategoryNotExistsException; +import solitour_backend.solitour.gathering.exception.GatheringNotExistsException; import solitour_backend.solitour.gathering.repository.GatheringRepository; +import solitour_backend.solitour.gathering_applicants.dto.mapper.GatheringApplicantsMapper; +import solitour_backend.solitour.gathering_applicants.dto.response.GatheringApplicantsResponse; +import solitour_backend.solitour.gathering_applicants.entity.GatheringStatus; +import solitour_backend.solitour.gathering_applicants.repository.GatheringApplicantsRepository; import solitour_backend.solitour.gathering_category.entity.GatheringCategory; import solitour_backend.solitour.gathering_category.repository.GatheringCategoryRepository; import solitour_backend.solitour.gathering_tag.entity.GatheringTag; import solitour_backend.solitour.gathering_tag.repository.GatheringTagRepository; +import solitour_backend.solitour.great_gathering.repository.GreatGatheringRepository; +import solitour_backend.solitour.place.dto.mapper.PlaceMapper; import solitour_backend.solitour.place.dto.request.PlaceRegisterRequest; +import solitour_backend.solitour.place.dto.response.PlaceResponse; import solitour_backend.solitour.place.entity.Place; import solitour_backend.solitour.place.repository.PlaceRepository; import solitour_backend.solitour.tag.dto.mapper.TagMapper; +import solitour_backend.solitour.tag.dto.response.TagResponse; import solitour_backend.solitour.tag.entity.Tag; import solitour_backend.solitour.tag.repository.TagRepository; +import solitour_backend.solitour.user.dto.UserPostingResponse; +import solitour_backend.solitour.user.dto.mapper.UserMapper; import solitour_backend.solitour.user.entity.User; import solitour_backend.solitour.user.entity.UserRepository; import solitour_backend.solitour.user.exception.UserNotExistsException; +import solitour_backend.solitour.zone_category.dto.mapper.ZoneCategoryMapper; +import solitour_backend.solitour.zone_category.dto.response.ZoneCategoryResponse; import solitour_backend.solitour.zone_category.entity.ZoneCategory; import solitour_backend.solitour.zone_category.exception.ZoneCategoryNotExistsException; import solitour_backend.solitour.zone_category.repository.ZoneCategoryRepository; +import java.util.ArrayList; import java.util.List; @Service @@ -41,6 +57,66 @@ public class GatheringService { private final TagRepository tagRepository; private final GatheringTagRepository gatheringTagRepository; private final GatheringMapper gatheringMapper; + private final UserMapper userMapper; + private final PlaceMapper placeMapper; + private final ZoneCategoryMapper zoneCategoryMapper; + private final GreatGatheringRepository greatGatheringRepository; + private final GatheringApplicantsRepository gatheringApplicantsRepository; + private final GatheringApplicantsMapper gatheringApplicantsMapper; + + public GatheringDetailResponse getGatheringDetail(Long userId, Long gatheringId) { + Gathering gathering = gatheringRepository.findById(gatheringId) + .orElseThrow( + () -> new GatheringNotExistsException("해당하는 id의 gathering 이 존재 하지 않습니다")); + UserPostingResponse userPostingResponse = userMapper.mapToUserPostingResponse(gathering.getUser()); + + List gatheringTags = gatheringTagRepository.findAllByGathering_Id(gathering.getId()); + + List tagResponses = new ArrayList<>(); + + if (!gatheringTags.isEmpty()) { + tagResponses = gatheringTags.stream() + .map(data -> + tagMapper.mapToTagResponse(data.getTag())) + .toList(); + } + + PlaceResponse placeResponse = placeMapper.mapToPlaceResponse(gathering.getPlace()); + + ZoneCategoryResponse zoneCategoryResponse = zoneCategoryMapper.mapToZoneCategoryResponse(gathering.getZoneCategory()); + + int likeCount = greatGatheringRepository.countByGatheringId(gathering.getId()); + + List gatheringApplicantsResponses = gatheringApplicantsMapper.mapToGatheringApplicantsResponses(gatheringApplicantsRepository.findAllByGathering_Id(gathering.getId())); + + int nowPersonCount = gatheringApplicantsRepository.countAllByGathering_IdAndGatheringStatus(gathering.getId(), GatheringStatus.CONSENT); + + List gatheringRecommend = gatheringRepository.getGatheringRecommend(gathering.getId(), gathering.getGatheringCategory().getId(), userId); + + return new GatheringDetailResponse( + gathering.getTitle(), + gathering.getContent(), + gathering.getPersonCount(), + gathering.getViewCount(), + gathering.getCreatedAt(), + gathering.getScheduleStartDate(), + gathering.getScheduleEndDate(), + gathering.getDeadline(), + gathering.getIsFinish(), + gathering.getAllowedSex(), + gathering.getStartAge(), + gathering.getEndAge(), + tagResponses, + userPostingResponse, + placeResponse, + zoneCategoryResponse, + likeCount, + nowPersonCount, + gatheringApplicantsResponses, + gatheringRecommend + ); + } + @Transactional public GatheringResponse registerGathering(Long userId, GatheringRegisterRequest gatheringRegisterRequest) { @@ -101,4 +177,5 @@ public GatheringResponse registerGathering(Long userId, GatheringRegisterRequest return gatheringMapper.mapToGatheringResponse(saveGathering); } + } From 2ab11076b169867340f67c31e9029f4063d5e7fa Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Tue, 6 Aug 2024 02:57:26 +0900 Subject: [PATCH 072/371] =?UTF-8?q?feat:=20gathering=20=EC=83=81=EC=84=B8?= =?UTF-8?q?=20=ED=8E=98=EC=9D=B4=EC=A7=80=20=EC=A1=B0=ED=9A=8C=20controlle?= =?UTF-8?q?r?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/GatheringController.java | 36 ++++++++++++++++--- 1 file changed, 32 insertions(+), 4 deletions(-) diff --git a/src/main/java/solitour_backend/solitour/gathering/controller/GatheringController.java b/src/main/java/solitour_backend/solitour/gathering/controller/GatheringController.java index 76bc5fee..c0891100 100644 --- a/src/main/java/solitour_backend/solitour/gathering/controller/GatheringController.java +++ b/src/main/java/solitour_backend/solitour/gathering/controller/GatheringController.java @@ -1,28 +1,31 @@ package solitour_backend.solitour.gathering.controller; +import jakarta.servlet.http.HttpServletRequest; import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.validation.BindingResult; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; import solitour_backend.solitour.auth.config.AuthenticationPrincipal; +import solitour_backend.solitour.auth.support.CookieExtractor; +import solitour_backend.solitour.auth.support.JwtTokenProvider; import solitour_backend.solitour.error.Utils; import solitour_backend.solitour.error.exception.RequestValidationFailedException; import solitour_backend.solitour.gathering.dto.request.GatheringRegisterRequest; +import solitour_backend.solitour.gathering.dto.response.GatheringDetailResponse; import solitour_backend.solitour.gathering.dto.response.GatheringResponse; import solitour_backend.solitour.gathering.service.GatheringService; import java.time.LocalDateTime; +import java.util.Objects; @RestController @RequiredArgsConstructor @RequestMapping("/api/gatherings") public class GatheringController { private final GatheringService gatheringService; + private final JwtTokenProvider jwtTokenProvider; @PostMapping public ResponseEntity createGathering(@AuthenticationPrincipal Long userId, @@ -48,5 +51,30 @@ public ResponseEntity createGathering(@AuthenticationPrincipa .body(gatheringResponse); } + @GetMapping("/{id}") + public ResponseEntity getGatheringDetail(@PathVariable Long id, + HttpServletRequest request) { + Long userId = findUser(request); + GatheringDetailResponse gatheringDetail = gatheringService.getGatheringDetail(userId, id); + + return ResponseEntity + .status(HttpStatus.OK) + .body(gatheringDetail); + } + + + private Long findUser(HttpServletRequest request) { + String token = CookieExtractor.findToken("access_token", request.getCookies()); + + if (Objects.isNull(token)) { + token = CookieExtractor.findToken("refresh_token", request.getCookies()); + } + if (Objects.isNull(token)) { + return (long) 0; + } + + return jwtTokenProvider.getPayload(token); + } + } From e50285fcb023be2111045c96e405e43eda7faf3c Mon Sep 17 00:00:00 2001 From: Donghun Won Date: Tue, 6 Aug 2024 16:50:36 +0900 Subject: [PATCH 073/371] =?UTF-8?q?Feat=20:=20=EC=9C=A0=EC=A0=80=20?= =?UTF-8?q?=EC=84=B1=EB=B3=84,=20=EC=83=9D=EB=85=84=EC=9B=94=EC=9D=BC=20?= =?UTF-8?q?=EC=88=98=EC=A0=95=20=EA=B8=B0=EB=8A=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../user/controller/UserController.java | 17 +++++++++++++++-- .../solitour/user/dto/UpdateAgeAndSex.java | 4 ++++ .../solitour/user/entity/User.java | 6 ++++++ .../solitour/user/service/UserService.java | 7 +++++++ 4 files changed, 32 insertions(+), 2 deletions(-) create mode 100644 src/main/java/solitour_backend/solitour/user/dto/UpdateAgeAndSex.java diff --git a/src/main/java/solitour_backend/solitour/user/controller/UserController.java b/src/main/java/solitour_backend/solitour/user/controller/UserController.java index 7e163a68..1b6d3431 100644 --- a/src/main/java/solitour_backend/solitour/user/controller/UserController.java +++ b/src/main/java/solitour_backend/solitour/user/controller/UserController.java @@ -25,7 +25,7 @@ public class UserController { @GetMapping("/info") public ResponseEntity retrieveUserInfo(@AuthenticationPrincipal Long userId) { - UserInfoResponse response = service.retrieveUserInfo(userId); + UserInfoResponse response = userService.retrieveUserInfo(userId); return ResponseEntity.ok(response); } @@ -33,7 +33,7 @@ public ResponseEntity retrieveUserInfo(@AuthenticationPrincipa @PutMapping("/nickname") public ResponseEntity updateNickname(@AuthenticationPrincipal Long userId, @RequestBody UpdateNicknameRequest request) { try { - service.updateNickname(userId, request.nickname()); + userService.updateNickname(userId, request.nickname()); return ResponseEntity.ok("Nickname updated successfully"); } catch (UserNotExistsException e) { return ResponseEntity.status(HttpStatus.NOT_FOUND).body("User not found"); @@ -44,4 +44,17 @@ public ResponseEntity updateNickname(@AuthenticationPrincipal Long userI } } + @Authenticated + @PutMapping("/age-sex") + public ResponseEntity updateAgeAndSex(@AuthenticationPrincipal Long userId, @RequestBody UpdateAgeAndSex request) { + try { + userService.updateAgeAndSex(userId, request.age(),request.sex()); + return ResponseEntity.ok("Age and Sex updated successfully"); + } catch (UserNotExistsException e) { + return ResponseEntity.status(HttpStatus.NOT_FOUND).body("User not found"); + } catch (Exception e) { + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("An internal error occurred"); + } + } + } diff --git a/src/main/java/solitour_backend/solitour/user/dto/UpdateAgeAndSex.java b/src/main/java/solitour_backend/solitour/user/dto/UpdateAgeAndSex.java new file mode 100644 index 00000000..b8b051b0 --- /dev/null +++ b/src/main/java/solitour_backend/solitour/user/dto/UpdateAgeAndSex.java @@ -0,0 +1,4 @@ +package solitour_backend.solitour.user.dto; + +public record UpdateAgeAndSex(String age,String sex) { +} diff --git a/src/main/java/solitour_backend/solitour/user/entity/User.java b/src/main/java/solitour_backend/solitour/user/entity/User.java index ad3b1509..e5bea85c 100644 --- a/src/main/java/solitour_backend/solitour/user/entity/User.java +++ b/src/main/java/solitour_backend/solitour/user/entity/User.java @@ -81,4 +81,10 @@ public class User { public void updateNickname(String nickname) { this.nickname = nickname; } + + public void updateAgeAndSex(String age, String sex) { + this.age = Integer.parseInt(age); + this.sex= sex; + } + } diff --git a/src/main/java/solitour_backend/solitour/user/service/UserService.java b/src/main/java/solitour_backend/solitour/user/service/UserService.java index 3a5cf5b3..72697c0b 100644 --- a/src/main/java/solitour_backend/solitour/user/service/UserService.java +++ b/src/main/java/solitour_backend/solitour/user/service/UserService.java @@ -29,4 +29,11 @@ public void updateNickname(Long userId, String nickname) { User user = userRepository.findByUserId(userId); user.updateNickname(nickname); } + + @Transactional + public void updateAgeAndSex(Long userId, String age, String sex) { + User user = userRepository.findByUserId(userId); + user.updateAgeAndSex(age,sex); + } + } From d2c95575c68045338679617e19cf851e3469057d Mon Sep 17 00:00:00 2001 From: Donghun Won Date: Tue, 6 Aug 2024 16:51:02 +0900 Subject: [PATCH 074/371] =?UTF-8?q?Feat=20:=20=ED=9A=8C=EC=9B=90=ED=83=88?= =?UTF-8?q?=ED=87=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../solitour/auth/service/OauthService.java | 20 ++++++-- .../auth/support/google/GoogleConnector.java | 38 ++++++++++++-- .../auth/support/google/GoogleProvider.java | 3 ++ .../auth/support/kakao/KakaoConnector.java | 2 +- .../user/controller/UserController.java | 51 ++++++++++++++++++- .../solitour/user/entity/User.java | 4 ++ .../solitour/user/entity/UserRepository.java | 5 +- .../solitour/user/service/UserService.java | 6 +++ 8 files changed, 116 insertions(+), 13 deletions(-) diff --git a/src/main/java/solitour_backend/solitour/auth/service/OauthService.java b/src/main/java/solitour_backend/solitour/auth/service/OauthService.java index c487826b..a8cc5eed 100644 --- a/src/main/java/solitour_backend/solitour/auth/service/OauthService.java +++ b/src/main/java/solitour_backend/solitour/auth/service/OauthService.java @@ -2,12 +2,12 @@ import jakarta.servlet.http.Cookie; - +import java.io.IOException; import java.time.LocalDateTime; import java.util.Objects; import java.util.concurrent.TimeUnit; - import lombok.RequiredArgsConstructor; +import org.springframework.http.HttpStatusCode; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import solitour_backend.solitour.auth.service.dto.response.AccessTokenResponse; @@ -176,7 +176,19 @@ public AccessTokenResponse reissueAccessToken(Long userId) { } @Transactional - public void logout(Long memberId) { - tokenService.deleteByMemberId(memberId); + public void logout(Long userId) { + tokenService.deleteByMemberId(userId); + } + + public void revokeToken(String token) throws IOException { + + HttpStatusCode responseCode = googleConnector.requestRevoke(token); + + if (responseCode.is2xxSuccessful()) { + System.out.println("Token successfully revoked"); + } else { + System.out.println("Failed to revoke token, response code: " + responseCode); + throw new RuntimeException("Failed to revoke token"); + } } } diff --git a/src/main/java/solitour_backend/solitour/auth/support/google/GoogleConnector.java b/src/main/java/solitour_backend/solitour/auth/support/google/GoogleConnector.java index 5e4d7028..c40dd71d 100644 --- a/src/main/java/solitour_backend/solitour/auth/support/google/GoogleConnector.java +++ b/src/main/java/solitour_backend/solitour/auth/support/google/GoogleConnector.java @@ -1,14 +1,21 @@ package solitour_backend.solitour.auth.support.google; +import java.io.IOException; +import java.io.OutputStream; +import java.net.HttpURLConnection; +import java.net.URL; import java.util.Collections; +import java.util.HashMap; +import java.util.Map; import java.util.Optional; - +import java.util.stream.Collectors; import lombok.Getter; import lombok.RequiredArgsConstructor; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; +import org.springframework.http.HttpStatusCode; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Component; @@ -40,9 +47,9 @@ public ResponseEntity requestGoogleUserInfo(String code, Str GoogleUserResponse.class); } - private String requestAccessToken(String code, String redirectUrl) { + public String requestAccessToken(String code, String redirectUrl) { HttpEntity> entity = new HttpEntity<>( - createBody(code, redirectUrl), createHeaders()); + createLoginBody(code, redirectUrl), createLoginHeaders()); ResponseEntity response = REST_TEMPLATE.postForEntity( provider.getAccessTokenUrl(), @@ -51,14 +58,23 @@ private String requestAccessToken(String code, String redirectUrl) { return extractAccessToken(response); } - private HttpHeaders createHeaders() { + public HttpStatusCode requestRevoke(String token) throws IOException { + HttpEntity> entity = new HttpEntity<>( + createLogoutBody(token), createLogoutHeaders()); + + ResponseEntity response = REST_TEMPLATE.postForEntity(provider.getRevokeUrl(), entity, Void.class); + + return response.getStatusCode(); + } + + private HttpHeaders createLoginHeaders() { HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED); headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON)); return headers; } - private MultiValueMap createBody(String code, String redirectUrl) { + private MultiValueMap createLoginBody(String code, String redirectUrl) { MultiValueMap body = new LinkedMultiValueMap<>(); body.add("code", code); body.add("client_id", provider.getClientId()); @@ -68,6 +84,18 @@ private MultiValueMap createBody(String code, String redirectUrl return body; } + private HttpHeaders createLogoutHeaders() { + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED); + return headers; + } + + private MultiValueMap createLogoutBody(String token) { + MultiValueMap body = new LinkedMultiValueMap<>(); + body.add("token", token); + return body; + } + private String extractAccessToken(ResponseEntity responseEntity) { GoogleTokenResponse response = Optional.ofNullable(responseEntity.getBody()) .orElseThrow(() -> new RuntimeException("구글 토큰을 가져오는데 실패했습니다.")); diff --git a/src/main/java/solitour_backend/solitour/auth/support/google/GoogleProvider.java b/src/main/java/solitour_backend/solitour/auth/support/google/GoogleProvider.java index 683b9a11..34ecc4bb 100644 --- a/src/main/java/solitour_backend/solitour/auth/support/google/GoogleProvider.java +++ b/src/main/java/solitour_backend/solitour/auth/support/google/GoogleProvider.java @@ -17,6 +17,7 @@ public class GoogleProvider { private final String authUrl; private final String accessTokenUrl; private final String userInfoUrl; + private final String revokeUrl; private final String grantType; private final String scope; @@ -25,6 +26,7 @@ public GoogleProvider(@Value("${oauth2.google.client.id}") String clientId, @Value("${oauth2.google.url.auth}") String authUrl, @Value("${oauth2.google.url.token}") String accessTokenUrl, @Value("${oauth2.google.url.userinfo}") String userInfoUrl, + @Value("${oauth2.google.url.revoke}") String revokeUrl, @Value("${oauth2.google.grant-type}") String grantType, @Value("${oauth2.google.scope}") String scope) { this.clientId = clientId; @@ -32,6 +34,7 @@ public GoogleProvider(@Value("${oauth2.google.client.id}") String clientId, this.authUrl = authUrl; this.accessTokenUrl = accessTokenUrl; this.userInfoUrl = userInfoUrl; + this.revokeUrl = revokeUrl; this.grantType = grantType; this.scope = scope; } diff --git a/src/main/java/solitour_backend/solitour/auth/support/kakao/KakaoConnector.java b/src/main/java/solitour_backend/solitour/auth/support/kakao/KakaoConnector.java index 0eba1c48..3d19251f 100644 --- a/src/main/java/solitour_backend/solitour/auth/support/kakao/KakaoConnector.java +++ b/src/main/java/solitour_backend/solitour/auth/support/kakao/KakaoConnector.java @@ -39,7 +39,7 @@ public ResponseEntity requestKakaoUserInfo(String code, Strin KakaoUserResponse.class); } - private String requestAccessToken(String code, String redirectUrl) { + public String requestAccessToken(String code, String redirectUrl) { HttpEntity> entity = new HttpEntity<>( createBody(code, redirectUrl), createHeaders()); diff --git a/src/main/java/solitour_backend/solitour/user/controller/UserController.java b/src/main/java/solitour_backend/solitour/user/controller/UserController.java index 1b6d3431..262df1df 100644 --- a/src/main/java/solitour_backend/solitour/user/controller/UserController.java +++ b/src/main/java/solitour_backend/solitour/user/controller/UserController.java @@ -1,14 +1,26 @@ package solitour_backend.solitour.user.controller; +import jakarta.servlet.http.HttpServletRequest; import lombok.RequiredArgsConstructor; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestHeader; import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; +import solitour_backend.solitour.auth.config.Authenticated; import solitour_backend.solitour.auth.config.AuthenticationPrincipal; +import solitour_backend.solitour.auth.service.OauthService; +import solitour_backend.solitour.auth.service.TokenService; +import solitour_backend.solitour.auth.support.CookieExtractor; +import solitour_backend.solitour.auth.support.google.GoogleConnector; +import solitour_backend.solitour.auth.support.kakao.KakaoConnector; +import solitour_backend.solitour.user.dto.UpdateAgeAndSex; import solitour_backend.solitour.user.dto.UpdateNicknameRequest; import solitour_backend.solitour.user.exception.NicknameAlreadyExistsException; import solitour_backend.solitour.user.exception.UserNotExistsException; @@ -20,9 +32,13 @@ @RequestMapping("/api/users") public class UserController { - private final UserService service; - + private final UserService userService; + private final OauthService oauthservice; + private final KakaoConnector kakaoConnector; + private final GoogleConnector googleConnector; + private final TokenService tokenService; + @Authenticated @GetMapping("/info") public ResponseEntity retrieveUserInfo(@AuthenticationPrincipal Long userId) { UserInfoResponse response = userService.retrieveUserInfo(userId); @@ -30,6 +46,7 @@ public ResponseEntity retrieveUserInfo(@AuthenticationPrincipa return ResponseEntity.ok(response); } + @Authenticated @PutMapping("/nickname") public ResponseEntity updateNickname(@AuthenticationPrincipal Long userId, @RequestBody UpdateNicknameRequest request) { try { @@ -57,4 +74,34 @@ public ResponseEntity updateAgeAndSex(@AuthenticationPrincipal Long user } } + @Authenticated + @DeleteMapping() + public ResponseEntity deleteUser(@AuthenticationPrincipal Long id, @RequestParam String type, @RequestParam String code, @RequestParam String redirectUrl) { + String token = getOauthAccessToken(type,code,redirectUrl); + + try { + oauthservice.revokeToken(token); + + userService.deleteUser(id); + oauthservice.logout(id); + + return ResponseEntity.ok("User deleted successfully"); + } catch (Exception e) { + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("An error occurred"); + } + } + + private String getOauthAccessToken(String type, String code, String redirectUrl){ + String token = ""; + switch (type) { + case "kakao" -> { + token = kakaoConnector.requestAccessToken(code, redirectUrl); + } + case "google" -> { + token = googleConnector.requestAccessToken(code, redirectUrl); + } + default -> throw new RuntimeException("Unsupported oauth type"); + } + return token; + } } diff --git a/src/main/java/solitour_backend/solitour/user/entity/User.java b/src/main/java/solitour_backend/solitour/user/entity/User.java index e5bea85c..28cc6909 100644 --- a/src/main/java/solitour_backend/solitour/user/entity/User.java +++ b/src/main/java/solitour_backend/solitour/user/entity/User.java @@ -87,4 +87,8 @@ public void updateAgeAndSex(String age, String sex) { this.sex= sex; } + public void deleteUser(Long userId) { + this.userStatus = UserStatus.DELETE; + this.deletedAt = LocalDateTime.now(); + } } diff --git a/src/main/java/solitour_backend/solitour/user/entity/UserRepository.java b/src/main/java/solitour_backend/solitour/user/entity/UserRepository.java index 3d6c1ac5..a6df04db 100644 --- a/src/main/java/solitour_backend/solitour/user/entity/UserRepository.java +++ b/src/main/java/solitour_backend/solitour/user/entity/UserRepository.java @@ -4,14 +4,17 @@ import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; +import solitour_backend.solitour.user.user_status.UserStatus; public interface UserRepository extends JpaRepository { + @Query("SELECT u FROM User u JOIN FETCH u.userImage WHERE u.nickname = :nickname AND u.userStatus = '활성화'") Optional findByNickname(String nickname); + @Query("SELECT u FROM User u JOIN FETCH u.userImage WHERE u.email = :email AND u.userStatus = '활성화'") Optional findByEmail(String email); - @Query("SELECT u FROM User u JOIN FETCH u.userImage WHERE u.id = :userId") + @Query("SELECT u FROM User u JOIN FETCH u.userImage WHERE u.id = :userId AND u.userStatus = '활성화'") User findByUserId(Long userId); boolean existsByNickname(String nickname); diff --git a/src/main/java/solitour_backend/solitour/user/service/UserService.java b/src/main/java/solitour_backend/solitour/user/service/UserService.java index 72697c0b..5f51e382 100644 --- a/src/main/java/solitour_backend/solitour/user/service/UserService.java +++ b/src/main/java/solitour_backend/solitour/user/service/UserService.java @@ -36,4 +36,10 @@ public void updateAgeAndSex(Long userId, String age, String sex) { user.updateAgeAndSex(age,sex); } + + @Transactional + public void deleteUser(Long userId) { + User user = userRepository.findByUserId(userId); + user.deleteUser(userId); + } } From 180462b4b881c7edbe1fab37448040eef7c5b036 Mon Sep 17 00:00:00 2001 From: Donghun Won Date: Tue, 6 Aug 2024 16:53:29 +0900 Subject: [PATCH 075/371] =?UTF-8?q?Style=20:=20=EC=BD=94=EB=93=9C=20?= =?UTF-8?q?=ED=8F=AC=EB=A7=B7=ED=8C=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../admin/controller/AdminController.java | 3 +- .../admin/controller/BannerController.java | 8 +- .../GatheringCategoryController.java | 43 ++++---- .../admin/dto/UserListResponseDTO.java | 9 +- .../solitour/admin/dto/UserListWithPage.java | 7 +- .../dto/mapper/GatheringCategoryMapper.java | 3 +- .../solitour/admin/entity/Banner.java | 7 +- .../admin/entity/GatheringCategory.java | 10 +- .../admin/repository/BannerRepository.java | 3 +- .../GatheringCategoryRepository.java | 3 +- .../solitour/admin/service/AdminService.java | 3 +- .../solitour/admin/service/BannerService.java | 11 +- .../service/GatheringCategoryService.java | 25 ++--- .../auth/config/AuthConfiguration.java | 3 +- .../solitour/auth/config/AuthInterceptor.java | 2 - .../solitour/auth/config/TokenResolver.java | 3 +- .../auth/controller/OauthController.java | 8 +- .../solitour/auth/entity/TokenRepository.java | 1 - .../auth/support/JwtTokenProvider.java | 2 - .../auth/support/google/GoogleConnector.java | 6 - .../auth/support/google/GoogleProvider.java | 1 - .../google/dto/GoogleUserResponse.java | 2 - .../auth/support/kakao/KakaoConnector.java | 1 - .../auth/support/kakao/KakaoProvider.java | 1 - .../support/kakao/dto/KakaoUserResponse.java | 2 - .../entity/BookMarkInformationRepository.java | 1 - .../service/BookMarkInformationService.java | 2 - .../controller/CategoryController.java | 14 +-- .../category/dto/mapper/CategoryMapper.java | 1 - .../dto/response/CategoryGetResponse.java | 1 - .../repository/CategoryRepository.java | 1 - .../category/service/CategoryService.java | 1 - .../solitour/comment/entity/Comment.java | 2 - .../RequestValidationFailedException.java | 2 - .../solitour/gathering/entity/Gathering.java | 2 - .../GreatInformationRepository.java | 1 - .../image/dto/mapper/ImageMapper.java | 1 - .../solitour/image/entity/Image.java | 2 - .../image/image_status/ImageStatus.java | 1 - .../image/repository/ImageRepository.java | 1 - .../solitour/image/s3/S3Uploader.java | 2 - .../repository/InfoTagRepository.java | 1 - .../controller/InformationController.java | 104 +++++++++++------- .../dto/request/InformationModifyRequest.java | 3 +- .../request/InformationRegisterRequest.java | 2 - .../response/InformationDetailResponse.java | 1 - .../information/entity/Information.java | 14 ++- .../InformationRepositoryCustom.java | 41 ++++--- .../repository/InformationRepositoryImpl.java | 73 ++++++++---- .../service/InformationService.java | 73 +++++++----- .../place/dto/request/PlaceModifyRequest.java | 2 - .../dto/request/PlaceRegisterRequest.java | 2 - .../place/dto/response/PlaceResponse.java | 1 - .../solitour/place/entity/Place.java | 2 - .../solitour/tag/dto/mapper/TagMapper.java | 1 - .../user/controller/UserController.java | 19 ++-- .../solitour/user/dto/UpdateAgeAndSex.java | 2 +- .../solitour/user/entity/User.java | 4 +- .../solitour/user/entity/UserRepository.java | 2 - .../solitour/user/service/UserService.java | 2 +- .../solitour/user/user_status/UserStatus.java | 1 - .../solitour/user_image/entity/UserImage.java | 2 - .../user_image/service/UserImageService.java | 1 - .../solitour/util/TimeUtil.java | 3 +- .../controller/ZoneCategoryController.java | 5 +- .../repository/ZoneCategoryRepository.java | 1 - .../service/ZoneCategoryService.java | 1 - 67 files changed, 313 insertions(+), 252 deletions(-) diff --git a/src/main/java/solitour_backend/solitour/admin/controller/AdminController.java b/src/main/java/solitour_backend/solitour/admin/controller/AdminController.java index 7890b0ef..5e43e2bf 100644 --- a/src/main/java/solitour_backend/solitour/admin/controller/AdminController.java +++ b/src/main/java/solitour_backend/solitour/admin/controller/AdminController.java @@ -17,7 +17,8 @@ public class AdminController { private final AdminService adminService; @GetMapping("/user/list") - public ResponseEntity getUserInfoList(@RequestParam(defaultValue = "1") int page, @RequestParam(defaultValue = "") String nickname) { + public ResponseEntity getUserInfoList(@RequestParam(defaultValue = "1") int page, + @RequestParam(defaultValue = "") String nickname) { UserListWithPage response = adminService.getUserInfoList(nickname, page); return ResponseEntity.ok(response); } diff --git a/src/main/java/solitour_backend/solitour/admin/controller/BannerController.java b/src/main/java/solitour_backend/solitour/admin/controller/BannerController.java index 339a8b5f..2aa5e245 100644 --- a/src/main/java/solitour_backend/solitour/admin/controller/BannerController.java +++ b/src/main/java/solitour_backend/solitour/admin/controller/BannerController.java @@ -3,7 +3,11 @@ import lombok.RequiredArgsConstructor; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.*; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RequestPart; +import org.springframework.web.bind.annotation.RestController; import org.springframework.web.multipart.MultipartFile; import solitour_backend.solitour.admin.entity.Banner; import solitour_backend.solitour.admin.service.BannerService; @@ -17,7 +21,7 @@ public class BannerController { @RequestMapping(method = RequestMethod.POST) public ResponseEntity createBanner(@RequestPart("imageFile") MultipartFile imageFile, @RequestPart("directory") String directory) { - Banner banner = bannerService.createBanner(imageFile,directory); + Banner banner = bannerService.createBanner(imageFile, directory); return ResponseEntity .status(HttpStatus.OK) .body(banner); diff --git a/src/main/java/solitour_backend/solitour/admin/controller/GatheringCategoryController.java b/src/main/java/solitour_backend/solitour/admin/controller/GatheringCategoryController.java index d687ad4d..9a2e822c 100644 --- a/src/main/java/solitour_backend/solitour/admin/controller/GatheringCategoryController.java +++ b/src/main/java/solitour_backend/solitour/admin/controller/GatheringCategoryController.java @@ -1,11 +1,18 @@ package solitour_backend.solitour.admin.controller; import jakarta.validation.Valid; +import java.util.List; import lombok.RequiredArgsConstructor; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.validation.BindingResult; -import org.springframework.web.bind.annotation.*; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; import solitour_backend.solitour.admin.service.GatheringCategoryService; import solitour_backend.solitour.category.dto.request.CategoryModifyRequest; import solitour_backend.solitour.category.dto.request.CategoryRegisterRequest; @@ -13,22 +20,20 @@ import solitour_backend.solitour.category.dto.response.CategoryResponse; import solitour_backend.solitour.error.exception.RequestValidationFailedException; -import java.util.List; - @RestController @RequiredArgsConstructor @RequestMapping("/api/categories/gathering") public class GatheringCategoryController { private final GatheringCategoryService gatheringCategoryService; - + @GetMapping public ResponseEntity> getAllCategories() { List parentCategories = gatheringCategoryService.getParentCategories(); return ResponseEntity - .status(HttpStatus.OK) - .body(parentCategories); + .status(HttpStatus.OK) + .body(parentCategories); } @GetMapping("/{id}") @@ -36,39 +41,39 @@ public ResponseEntity getCategory(@PathVariable Long id) { CategoryResponse category = gatheringCategoryService.getCategory(id); return ResponseEntity - .status(HttpStatus.OK) - .body(category); + .status(HttpStatus.OK) + .body(category); } @PostMapping public ResponseEntity registerCategory( - @Valid @RequestBody CategoryRegisterRequest categoryRegisterRequest, - BindingResult bindingResult) { + @Valid @RequestBody CategoryRegisterRequest categoryRegisterRequest, + BindingResult bindingResult) { if (bindingResult.hasErrors()) { throw new RequestValidationFailedException(bindingResult); } CategoryResponse categoryResponse = gatheringCategoryService.registerCategory( - categoryRegisterRequest); + categoryRegisterRequest); return ResponseEntity - .status(HttpStatus.CREATED) - .body(categoryResponse); + .status(HttpStatus.CREATED) + .body(categoryResponse); } @PutMapping("/{id}") public ResponseEntity modifyCategory( - @Valid @RequestBody CategoryModifyRequest categoryModifyRequest, - BindingResult bindingResult, - @PathVariable Long id) { + @Valid @RequestBody CategoryModifyRequest categoryModifyRequest, + BindingResult bindingResult, + @PathVariable Long id) { if (bindingResult.hasErrors()) { throw new RequestValidationFailedException(bindingResult); } CategoryResponse categoryResponse = gatheringCategoryService.modifyCategory(id, - categoryModifyRequest); + categoryModifyRequest); return ResponseEntity - .status(HttpStatus.CREATED) - .body(categoryResponse); + .status(HttpStatus.CREATED) + .body(categoryResponse); } diff --git a/src/main/java/solitour_backend/solitour/admin/dto/UserListResponseDTO.java b/src/main/java/solitour_backend/solitour/admin/dto/UserListResponseDTO.java index 21d689fa..ec325fdd 100644 --- a/src/main/java/solitour_backend/solitour/admin/dto/UserListResponseDTO.java +++ b/src/main/java/solitour_backend/solitour/admin/dto/UserListResponseDTO.java @@ -1,9 +1,12 @@ package solitour_backend.solitour.admin.dto; -import lombok.*; -import solitour_backend.solitour.user.user_status.UserStatus; - import java.time.LocalDateTime; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import solitour_backend.solitour.user.user_status.UserStatus; @Getter diff --git a/src/main/java/solitour_backend/solitour/admin/dto/UserListWithPage.java b/src/main/java/solitour_backend/solitour/admin/dto/UserListWithPage.java index 1ba166ad..b62e6c67 100644 --- a/src/main/java/solitour_backend/solitour/admin/dto/UserListWithPage.java +++ b/src/main/java/solitour_backend/solitour/admin/dto/UserListWithPage.java @@ -1,8 +1,11 @@ package solitour_backend.solitour.admin.dto; -import lombok.*; - import java.util.List; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; @Getter @NoArgsConstructor diff --git a/src/main/java/solitour_backend/solitour/admin/dto/mapper/GatheringCategoryMapper.java b/src/main/java/solitour_backend/solitour/admin/dto/mapper/GatheringCategoryMapper.java index b5f7b864..e78e1982 100644 --- a/src/main/java/solitour_backend/solitour/admin/dto/mapper/GatheringCategoryMapper.java +++ b/src/main/java/solitour_backend/solitour/admin/dto/mapper/GatheringCategoryMapper.java @@ -1,12 +1,11 @@ package solitour_backend.solitour.admin.dto.mapper; +import java.util.List; import org.mapstruct.Mapper; import org.mapstruct.ReportingPolicy; import solitour_backend.solitour.admin.entity.GatheringCategory; import solitour_backend.solitour.category.dto.response.CategoryResponse; -import java.util.List; - @Mapper(componentModel = "spring", unmappedTargetPolicy = ReportingPolicy.ERROR) public interface GatheringCategoryMapper { diff --git a/src/main/java/solitour_backend/solitour/admin/entity/Banner.java b/src/main/java/solitour_backend/solitour/admin/entity/Banner.java index 46ddd687..62fed976 100644 --- a/src/main/java/solitour_backend/solitour/admin/entity/Banner.java +++ b/src/main/java/solitour_backend/solitour/admin/entity/Banner.java @@ -1,6 +1,11 @@ package solitour_backend.solitour.admin.entity; -import jakarta.persistence.*; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.Table; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Getter; diff --git a/src/main/java/solitour_backend/solitour/admin/entity/GatheringCategory.java b/src/main/java/solitour_backend/solitour/admin/entity/GatheringCategory.java index 3a99b3be..41fd08dc 100644 --- a/src/main/java/solitour_backend/solitour/admin/entity/GatheringCategory.java +++ b/src/main/java/solitour_backend/solitour/admin/entity/GatheringCategory.java @@ -1,6 +1,14 @@ package solitour_backend.solitour.admin.entity; -import jakarta.persistence.*; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.FetchType; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.ManyToOne; +import jakarta.persistence.Table; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; diff --git a/src/main/java/solitour_backend/solitour/admin/repository/BannerRepository.java b/src/main/java/solitour_backend/solitour/admin/repository/BannerRepository.java index 979b1c22..acc57843 100644 --- a/src/main/java/solitour_backend/solitour/admin/repository/BannerRepository.java +++ b/src/main/java/solitour_backend/solitour/admin/repository/BannerRepository.java @@ -1,10 +1,9 @@ package solitour_backend.solitour.admin.repository; +import java.util.List; import org.springframework.data.jpa.repository.JpaRepository; import solitour_backend.solitour.admin.entity.Banner; -import java.util.List; - public interface BannerRepository extends JpaRepository { diff --git a/src/main/java/solitour_backend/solitour/admin/repository/GatheringCategoryRepository.java b/src/main/java/solitour_backend/solitour/admin/repository/GatheringCategoryRepository.java index e2c176df..e1626a26 100644 --- a/src/main/java/solitour_backend/solitour/admin/repository/GatheringCategoryRepository.java +++ b/src/main/java/solitour_backend/solitour/admin/repository/GatheringCategoryRepository.java @@ -1,10 +1,9 @@ package solitour_backend.solitour.admin.repository; +import java.util.List; import org.springframework.data.jpa.repository.JpaRepository; import solitour_backend.solitour.admin.entity.GatheringCategory; -import java.util.List; - public interface GatheringCategoryRepository extends JpaRepository { List findAllByParentCategoryId(Long parentCategoryId); diff --git a/src/main/java/solitour_backend/solitour/admin/service/AdminService.java b/src/main/java/solitour_backend/solitour/admin/service/AdminService.java index bf0821ab..6c0f2bd0 100644 --- a/src/main/java/solitour_backend/solitour/admin/service/AdminService.java +++ b/src/main/java/solitour_backend/solitour/admin/service/AdminService.java @@ -1,5 +1,6 @@ package solitour_backend.solitour.admin.service; +import java.util.List; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.data.domain.Page; @@ -12,8 +13,6 @@ import solitour_backend.solitour.admin.repository.AdminRepository; import solitour_backend.solitour.user.entity.User; -import java.util.List; - @Service @Slf4j @RequiredArgsConstructor diff --git a/src/main/java/solitour_backend/solitour/admin/service/BannerService.java b/src/main/java/solitour_backend/solitour/admin/service/BannerService.java index 6096dafc..b9c77dad 100644 --- a/src/main/java/solitour_backend/solitour/admin/service/BannerService.java +++ b/src/main/java/solitour_backend/solitour/admin/service/BannerService.java @@ -3,6 +3,10 @@ import com.amazonaws.services.s3.AmazonS3Client; import com.amazonaws.services.s3.model.ObjectMetadata; import com.amazonaws.services.s3.model.PutObjectRequest; +import java.io.IOException; +import java.util.Date; +import java.util.List; +import java.util.UUID; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; @@ -16,11 +20,6 @@ import solitour_backend.solitour.admin.repository.BannerRepository; import solitour_backend.solitour.util.TimeUtil; -import java.io.IOException; -import java.util.Date; -import java.util.List; -import java.util.UUID; - @Service @Slf4j @RequiredArgsConstructor @@ -36,7 +35,7 @@ public class BannerService { public ResponseEntity getBannerList() { List banners = bannerRepository.findAllByOrderById(); HttpHeaders headers = new HttpHeaders(); - headers.setCacheControl("max-age="+timeUtil.getSecondsUntilMidnightInKST()); + headers.setCacheControl("max-age=" + timeUtil.getSecondsUntilMidnightInKST()); return new ResponseEntity<>(banners, HttpStatus.OK); } diff --git a/src/main/java/solitour_backend/solitour/admin/service/GatheringCategoryService.java b/src/main/java/solitour_backend/solitour/admin/service/GatheringCategoryService.java index e0cb511e..f0a8e63e 100644 --- a/src/main/java/solitour_backend/solitour/admin/service/GatheringCategoryService.java +++ b/src/main/java/solitour_backend/solitour/admin/service/GatheringCategoryService.java @@ -1,5 +1,8 @@ package solitour_backend.solitour.admin.service; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -12,10 +15,6 @@ import solitour_backend.solitour.category.dto.response.CategoryResponse; import solitour_backend.solitour.category.exception.CategoryNotExistsException; -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; - @Service @Transactional(readOnly = true) @RequiredArgsConstructor @@ -31,9 +30,9 @@ public CategoryResponse registerCategory(CategoryRegisterRequest categoryRegiste parentCategoryEntity = null; } else { parentCategoryEntity = gatheringCategoryRepository.findById( - categoryRegisterRequest.getParentCategory()) - .orElseThrow( - () -> new CategoryNotExistsException("Parent category not found")); + categoryRegisterRequest.getParentCategory()) + .orElseThrow( + () -> new CategoryNotExistsException("Parent category not found")); } GatheringCategory category = new GatheringCategory(parentCategoryEntity, categoryRegisterRequest.getName()); @@ -45,8 +44,8 @@ public CategoryResponse registerCategory(CategoryRegisterRequest categoryRegiste public CategoryResponse getCategory(Long id) { GatheringCategory category = gatheringCategoryRepository.findById(id) - .orElseThrow( - () -> new CategoryNotExistsException("category not found")); + .orElseThrow( + () -> new CategoryNotExistsException("category not found")); return gatheringCategoryMapper.mapToCategoryResponse(category); } @@ -65,7 +64,7 @@ public List getParentCategories() { for (GatheringCategory category : parentCategories) { List childrenCategories = getChildrenCategories(category.getId()); categoryGetResponses.add( - new CategoryGetResponse(category.getId(), category.getName(), childrenCategories)); + new CategoryGetResponse(category.getId(), category.getName(), childrenCategories)); } return categoryGetResponses; @@ -78,9 +77,9 @@ public CategoryResponse modifyCategory(Long id, CategoryModifyRequest categoryMo parentCategoryEntity = null; } else { parentCategoryEntity = gatheringCategoryRepository.findById( - categoryModifyRequest.getParentCategory()) - .orElseThrow( - () -> new CategoryNotExistsException("Parent category not found")); + categoryModifyRequest.getParentCategory()) + .orElseThrow( + () -> new CategoryNotExistsException("Parent category not found")); } GatheringCategory category = gatheringCategoryRepository.findById(id).orElseThrow(); diff --git a/src/main/java/solitour_backend/solitour/auth/config/AuthConfiguration.java b/src/main/java/solitour_backend/solitour/auth/config/AuthConfiguration.java index 318198c2..f522392b 100644 --- a/src/main/java/solitour_backend/solitour/auth/config/AuthConfiguration.java +++ b/src/main/java/solitour_backend/solitour/auth/config/AuthConfiguration.java @@ -1,5 +1,6 @@ package solitour_backend.solitour.auth.config; +import java.util.List; import lombok.RequiredArgsConstructor; import org.springframework.context.annotation.Configuration; import org.springframework.web.method.support.HandlerMethodArgumentResolver; @@ -10,8 +11,6 @@ import solitour_backend.solitour.auth.entity.TokenRepository; import solitour_backend.solitour.auth.support.JwtTokenProvider; -import java.util.List; - @RequiredArgsConstructor @Configuration public class AuthConfiguration implements WebMvcConfigurer { diff --git a/src/main/java/solitour_backend/solitour/auth/config/AuthInterceptor.java b/src/main/java/solitour_backend/solitour/auth/config/AuthInterceptor.java index 6796d8c0..eea6b2c8 100644 --- a/src/main/java/solitour_backend/solitour/auth/config/AuthInterceptor.java +++ b/src/main/java/solitour_backend/solitour/auth/config/AuthInterceptor.java @@ -3,10 +3,8 @@ import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; - import java.lang.annotation.Annotation; import java.util.Optional; - import lombok.RequiredArgsConstructor; import org.springframework.web.cors.CorsUtils; import org.springframework.web.method.HandlerMethod; diff --git a/src/main/java/solitour_backend/solitour/auth/config/TokenResolver.java b/src/main/java/solitour_backend/solitour/auth/config/TokenResolver.java index e6a1340b..440b2779 100644 --- a/src/main/java/solitour_backend/solitour/auth/config/TokenResolver.java +++ b/src/main/java/solitour_backend/solitour/auth/config/TokenResolver.java @@ -25,7 +25,8 @@ public boolean supportsParameter(MethodParameter parameter) { } @Override - public Long resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) { + public Long resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, + NativeWebRequest webRequest, WebDataBinderFactory binderFactory) { String token = ""; HttpServletRequest request = webRequest.getNativeRequest(HttpServletRequest.class); diff --git a/src/main/java/solitour_backend/solitour/auth/controller/OauthController.java b/src/main/java/solitour_backend/solitour/auth/controller/OauthController.java index 7bdd0bbc..fbc48ea3 100644 --- a/src/main/java/solitour_backend/solitour/auth/controller/OauthController.java +++ b/src/main/java/solitour_backend/solitour/auth/controller/OauthController.java @@ -32,7 +32,8 @@ public ResponseEntity access(@RequestParam String type, @Requ } @GetMapping(value = "/login", params = {"type", "code", "redirectUrl"}) - public ResponseEntity login(HttpServletResponse response, @RequestParam String type, @RequestParam String code, @RequestParam String redirectUrl) { + public ResponseEntity login(HttpServletResponse response, @RequestParam String type, + @RequestParam String code, @RequestParam String redirectUrl) { LoginResponse loginResponse = oauthService.requestAccessToken(type, code, redirectUrl); String accessCookieHeader = setCookieHeader(loginResponse.getAccessToken()); @@ -53,7 +54,8 @@ public ResponseEntity logout(@AuthenticationPrincipal Long memberId) { @PostMapping("/token/refresh") - public ResponseEntity reissueAccessToken(HttpServletResponse response, @AuthenticationRefreshPrincipal Long memberId) { + public ResponseEntity reissueAccessToken(HttpServletResponse response, + @AuthenticationRefreshPrincipal Long memberId) { AccessTokenResponse accessToken = oauthService.reissueAccessToken(memberId); String accessCookieHeader = setCookieHeader(accessToken.getAccessToken()); @@ -64,6 +66,6 @@ public ResponseEntity reissueAccessToken(HttpServletResponse response, @Au private String setCookieHeader(Cookie cookie) { return String.format("%s=%s; Path=%s; Max-Age=%d;Secure; HttpOnly; SameSite=Lax", - cookie.getName(), cookie.getValue(), cookie.getPath(),cookie.getMaxAge()); + cookie.getName(), cookie.getValue(), cookie.getPath(), cookie.getMaxAge()); } } diff --git a/src/main/java/solitour_backend/solitour/auth/entity/TokenRepository.java b/src/main/java/solitour_backend/solitour/auth/entity/TokenRepository.java index 03b6f5d0..d020ddf0 100644 --- a/src/main/java/solitour_backend/solitour/auth/entity/TokenRepository.java +++ b/src/main/java/solitour_backend/solitour/auth/entity/TokenRepository.java @@ -1,7 +1,6 @@ package solitour_backend.solitour.auth.entity; import java.util.Optional; - import org.springframework.data.jpa.repository.Modifying; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.Repository; diff --git a/src/main/java/solitour_backend/solitour/auth/support/JwtTokenProvider.java b/src/main/java/solitour_backend/solitour/auth/support/JwtTokenProvider.java index fe18d5b9..cbd79737 100644 --- a/src/main/java/solitour_backend/solitour/auth/support/JwtTokenProvider.java +++ b/src/main/java/solitour_backend/solitour/auth/support/JwtTokenProvider.java @@ -7,10 +7,8 @@ import io.jsonwebtoken.Jwts; import io.jsonwebtoken.io.Decoders; import io.jsonwebtoken.security.Keys; - import java.util.Date; import javax.crypto.SecretKey; - import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; diff --git a/src/main/java/solitour_backend/solitour/auth/support/google/GoogleConnector.java b/src/main/java/solitour_backend/solitour/auth/support/google/GoogleConnector.java index c40dd71d..0355f882 100644 --- a/src/main/java/solitour_backend/solitour/auth/support/google/GoogleConnector.java +++ b/src/main/java/solitour_backend/solitour/auth/support/google/GoogleConnector.java @@ -2,14 +2,8 @@ import java.io.IOException; -import java.io.OutputStream; -import java.net.HttpURLConnection; -import java.net.URL; import java.util.Collections; -import java.util.HashMap; -import java.util.Map; import java.util.Optional; -import java.util.stream.Collectors; import lombok.Getter; import lombok.RequiredArgsConstructor; import org.springframework.http.HttpEntity; diff --git a/src/main/java/solitour_backend/solitour/auth/support/google/GoogleProvider.java b/src/main/java/solitour_backend/solitour/auth/support/google/GoogleProvider.java index 34ecc4bb..c11140db 100644 --- a/src/main/java/solitour_backend/solitour/auth/support/google/GoogleProvider.java +++ b/src/main/java/solitour_backend/solitour/auth/support/google/GoogleProvider.java @@ -3,7 +3,6 @@ import java.util.HashMap; import java.util.Map; import java.util.stream.Collectors; - import lombok.Getter; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; diff --git a/src/main/java/solitour_backend/solitour/auth/support/google/dto/GoogleUserResponse.java b/src/main/java/solitour_backend/solitour/auth/support/google/dto/GoogleUserResponse.java index 29984b49..65425753 100644 --- a/src/main/java/solitour_backend/solitour/auth/support/google/dto/GoogleUserResponse.java +++ b/src/main/java/solitour_backend/solitour/auth/support/google/dto/GoogleUserResponse.java @@ -1,9 +1,7 @@ package solitour_backend.solitour.auth.support.google.dto; import com.fasterxml.jackson.annotation.JsonProperty; - import java.util.List; - import lombok.AllArgsConstructor; import lombok.Data; import lombok.Getter; diff --git a/src/main/java/solitour_backend/solitour/auth/support/kakao/KakaoConnector.java b/src/main/java/solitour_backend/solitour/auth/support/kakao/KakaoConnector.java index 3d19251f..bcfe0708 100644 --- a/src/main/java/solitour_backend/solitour/auth/support/kakao/KakaoConnector.java +++ b/src/main/java/solitour_backend/solitour/auth/support/kakao/KakaoConnector.java @@ -3,7 +3,6 @@ import java.util.Collections; import java.util.Optional; - import lombok.Getter; import lombok.RequiredArgsConstructor; import org.springframework.http.HttpEntity; diff --git a/src/main/java/solitour_backend/solitour/auth/support/kakao/KakaoProvider.java b/src/main/java/solitour_backend/solitour/auth/support/kakao/KakaoProvider.java index 4c9353df..4b4975a1 100644 --- a/src/main/java/solitour_backend/solitour/auth/support/kakao/KakaoProvider.java +++ b/src/main/java/solitour_backend/solitour/auth/support/kakao/KakaoProvider.java @@ -3,7 +3,6 @@ import java.util.HashMap; import java.util.Map; import java.util.stream.Collectors; - import lombok.Getter; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; diff --git a/src/main/java/solitour_backend/solitour/auth/support/kakao/dto/KakaoUserResponse.java b/src/main/java/solitour_backend/solitour/auth/support/kakao/dto/KakaoUserResponse.java index 2f5bb124..af3b0ab5 100644 --- a/src/main/java/solitour_backend/solitour/auth/support/kakao/dto/KakaoUserResponse.java +++ b/src/main/java/solitour_backend/solitour/auth/support/kakao/dto/KakaoUserResponse.java @@ -2,10 +2,8 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; - import java.util.Date; import java.util.HashMap; - import lombok.Getter; import lombok.NoArgsConstructor; diff --git a/src/main/java/solitour_backend/solitour/book_mark_information/entity/BookMarkInformationRepository.java b/src/main/java/solitour_backend/solitour/book_mark_information/entity/BookMarkInformationRepository.java index efe21532..cbc5d85a 100644 --- a/src/main/java/solitour_backend/solitour/book_mark_information/entity/BookMarkInformationRepository.java +++ b/src/main/java/solitour_backend/solitour/book_mark_information/entity/BookMarkInformationRepository.java @@ -2,7 +2,6 @@ import java.util.List; import java.util.Optional; - import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; diff --git a/src/main/java/solitour_backend/solitour/book_mark_information/service/BookMarkInformationService.java b/src/main/java/solitour_backend/solitour/book_mark_information/service/BookMarkInformationService.java index e2dbfccd..34666823 100644 --- a/src/main/java/solitour_backend/solitour/book_mark_information/service/BookMarkInformationService.java +++ b/src/main/java/solitour_backend/solitour/book_mark_information/service/BookMarkInformationService.java @@ -1,9 +1,7 @@ package solitour_backend.solitour.book_mark_information.service; import jakarta.persistence.EntityNotFoundException; - import java.util.List; - import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; diff --git a/src/main/java/solitour_backend/solitour/category/controller/CategoryController.java b/src/main/java/solitour_backend/solitour/category/controller/CategoryController.java index d5fa0e6f..e7216be0 100644 --- a/src/main/java/solitour_backend/solitour/category/controller/CategoryController.java +++ b/src/main/java/solitour_backend/solitour/category/controller/CategoryController.java @@ -1,9 +1,7 @@ package solitour_backend.solitour.category.controller; import jakarta.validation.Valid; - import java.util.List; - import lombok.RequiredArgsConstructor; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -48,8 +46,9 @@ public ResponseEntity getCategory(@PathVariable Long id) { } @PostMapping - public ResponseEntity registerCategory(@Valid @RequestBody CategoryRegisterRequest categoryRegisterRequest, - BindingResult bindingResult) { + public ResponseEntity registerCategory( + @Valid @RequestBody CategoryRegisterRequest categoryRegisterRequest, + BindingResult bindingResult) { if (bindingResult.hasErrors()) { throw new RequestValidationFailedException(bindingResult); } @@ -62,9 +61,10 @@ public ResponseEntity registerCategory(@Valid @RequestBody Cat } @PutMapping("/{id}") - public ResponseEntity modifyCategory(@Valid @RequestBody CategoryModifyRequest categoryModifyRequest, - BindingResult bindingResult, - @PathVariable Long id) { + public ResponseEntity modifyCategory( + @Valid @RequestBody CategoryModifyRequest categoryModifyRequest, + BindingResult bindingResult, + @PathVariable Long id) { if (bindingResult.hasErrors()) { throw new RequestValidationFailedException(bindingResult); } diff --git a/src/main/java/solitour_backend/solitour/category/dto/mapper/CategoryMapper.java b/src/main/java/solitour_backend/solitour/category/dto/mapper/CategoryMapper.java index e0e8f3d0..4f9c294a 100644 --- a/src/main/java/solitour_backend/solitour/category/dto/mapper/CategoryMapper.java +++ b/src/main/java/solitour_backend/solitour/category/dto/mapper/CategoryMapper.java @@ -1,7 +1,6 @@ package solitour_backend.solitour.category.dto.mapper; import java.util.List; - import org.mapstruct.Mapper; import org.mapstruct.ReportingPolicy; import solitour_backend.solitour.category.dto.response.CategoryResponse; diff --git a/src/main/java/solitour_backend/solitour/category/dto/response/CategoryGetResponse.java b/src/main/java/solitour_backend/solitour/category/dto/response/CategoryGetResponse.java index 4d0ff101..f4fb2c1d 100644 --- a/src/main/java/solitour_backend/solitour/category/dto/response/CategoryGetResponse.java +++ b/src/main/java/solitour_backend/solitour/category/dto/response/CategoryGetResponse.java @@ -1,7 +1,6 @@ package solitour_backend.solitour.category.dto.response; import java.util.List; - import lombok.AllArgsConstructor; import lombok.Getter; diff --git a/src/main/java/solitour_backend/solitour/category/repository/CategoryRepository.java b/src/main/java/solitour_backend/solitour/category/repository/CategoryRepository.java index d51394ea..2600c43b 100644 --- a/src/main/java/solitour_backend/solitour/category/repository/CategoryRepository.java +++ b/src/main/java/solitour_backend/solitour/category/repository/CategoryRepository.java @@ -1,7 +1,6 @@ package solitour_backend.solitour.category.repository; import java.util.List; - import org.springframework.data.jpa.repository.JpaRepository; import solitour_backend.solitour.category.entity.Category; diff --git a/src/main/java/solitour_backend/solitour/category/service/CategoryService.java b/src/main/java/solitour_backend/solitour/category/service/CategoryService.java index 91163cd2..68667240 100644 --- a/src/main/java/solitour_backend/solitour/category/service/CategoryService.java +++ b/src/main/java/solitour_backend/solitour/category/service/CategoryService.java @@ -3,7 +3,6 @@ import java.util.ArrayList; import java.util.List; import java.util.Objects; - import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; diff --git a/src/main/java/solitour_backend/solitour/comment/entity/Comment.java b/src/main/java/solitour_backend/solitour/comment/entity/Comment.java index 540911d3..36446400 100644 --- a/src/main/java/solitour_backend/solitour/comment/entity/Comment.java +++ b/src/main/java/solitour_backend/solitour/comment/entity/Comment.java @@ -9,9 +9,7 @@ import jakarta.persistence.JoinColumn; import jakarta.persistence.ManyToOne; import jakarta.persistence.Table; - import java.time.LocalDateTime; - import lombok.Getter; import lombok.NoArgsConstructor; import solitour_backend.solitour.gathering.entity.Gathering; diff --git a/src/main/java/solitour_backend/solitour/error/exception/RequestValidationFailedException.java b/src/main/java/solitour_backend/solitour/error/exception/RequestValidationFailedException.java index 8bfb679a..81bfc786 100644 --- a/src/main/java/solitour_backend/solitour/error/exception/RequestValidationFailedException.java +++ b/src/main/java/solitour_backend/solitour/error/exception/RequestValidationFailedException.java @@ -1,9 +1,7 @@ package solitour_backend.solitour.error.exception; import jakarta.validation.ValidationException; - import java.util.stream.Collectors; - import org.springframework.validation.BindingResult; public class RequestValidationFailedException extends ValidationException { diff --git a/src/main/java/solitour_backend/solitour/gathering/entity/Gathering.java b/src/main/java/solitour_backend/solitour/gathering/entity/Gathering.java index 57740b0e..0ce48388 100644 --- a/src/main/java/solitour_backend/solitour/gathering/entity/Gathering.java +++ b/src/main/java/solitour_backend/solitour/gathering/entity/Gathering.java @@ -9,9 +9,7 @@ import jakarta.persistence.JoinColumn; import jakarta.persistence.ManyToOne; import jakarta.persistence.Table; - import java.time.LocalDateTime; - import lombok.Getter; import lombok.NoArgsConstructor; import solitour_backend.solitour.user.entity.User; diff --git a/src/main/java/solitour_backend/solitour/great_information/repository/GreatInformationRepository.java b/src/main/java/solitour_backend/solitour/great_information/repository/GreatInformationRepository.java index 7bf38e06..60d6448c 100644 --- a/src/main/java/solitour_backend/solitour/great_information/repository/GreatInformationRepository.java +++ b/src/main/java/solitour_backend/solitour/great_information/repository/GreatInformationRepository.java @@ -1,7 +1,6 @@ package solitour_backend.solitour.great_information.repository; import java.util.Optional; - import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; import solitour_backend.solitour.great_information.entity.GreatInformation; diff --git a/src/main/java/solitour_backend/solitour/image/dto/mapper/ImageMapper.java b/src/main/java/solitour_backend/solitour/image/dto/mapper/ImageMapper.java index 7398c584..b961d950 100644 --- a/src/main/java/solitour_backend/solitour/image/dto/mapper/ImageMapper.java +++ b/src/main/java/solitour_backend/solitour/image/dto/mapper/ImageMapper.java @@ -1,7 +1,6 @@ package solitour_backend.solitour.image.dto.mapper; import java.util.List; - import org.mapstruct.Mapper; import org.mapstruct.Mapping; import org.mapstruct.Named; diff --git a/src/main/java/solitour_backend/solitour/image/entity/Image.java b/src/main/java/solitour_backend/solitour/image/entity/Image.java index 457e6b24..5c77f5a9 100644 --- a/src/main/java/solitour_backend/solitour/image/entity/Image.java +++ b/src/main/java/solitour_backend/solitour/image/entity/Image.java @@ -10,9 +10,7 @@ import jakarta.persistence.JoinColumn; import jakarta.persistence.ManyToOne; import jakarta.persistence.Table; - import java.time.LocalDate; - import lombok.Getter; import lombok.NoArgsConstructor; import solitour_backend.solitour.image.image_status.ImageStatus; diff --git a/src/main/java/solitour_backend/solitour/image/image_status/ImageStatus.java b/src/main/java/solitour_backend/solitour/image/image_status/ImageStatus.java index 725f9ecc..3c8541b7 100644 --- a/src/main/java/solitour_backend/solitour/image/image_status/ImageStatus.java +++ b/src/main/java/solitour_backend/solitour/image/image_status/ImageStatus.java @@ -1,7 +1,6 @@ package solitour_backend.solitour.image.image_status; import java.util.Arrays; - import lombok.Getter; @Getter diff --git a/src/main/java/solitour_backend/solitour/image/repository/ImageRepository.java b/src/main/java/solitour_backend/solitour/image/repository/ImageRepository.java index 790014fc..7e04a88c 100644 --- a/src/main/java/solitour_backend/solitour/image/repository/ImageRepository.java +++ b/src/main/java/solitour_backend/solitour/image/repository/ImageRepository.java @@ -1,7 +1,6 @@ package solitour_backend.solitour.image.repository; import java.util.List; - import org.springframework.data.jpa.repository.JpaRepository; import solitour_backend.solitour.image.entity.Image; import solitour_backend.solitour.image.image_status.ImageStatus; diff --git a/src/main/java/solitour_backend/solitour/image/s3/S3Uploader.java b/src/main/java/solitour_backend/solitour/image/s3/S3Uploader.java index fbb3cc0a..69a74f5e 100644 --- a/src/main/java/solitour_backend/solitour/image/s3/S3Uploader.java +++ b/src/main/java/solitour_backend/solitour/image/s3/S3Uploader.java @@ -4,11 +4,9 @@ import com.amazonaws.services.s3.model.DeleteObjectRequest; import com.amazonaws.services.s3.model.ObjectMetadata; import com.amazonaws.services.s3.model.PutObjectRequest; - import java.io.IOException; import java.io.InputStream; import java.util.UUID; - import lombok.RequiredArgsConstructor; import org.springframework.beans.factory.annotation.Value; import org.springframework.http.HttpStatus; diff --git a/src/main/java/solitour_backend/solitour/info_tag/repository/InfoTagRepository.java b/src/main/java/solitour_backend/solitour/info_tag/repository/InfoTagRepository.java index 9ec0216c..3dc611c9 100644 --- a/src/main/java/solitour_backend/solitour/info_tag/repository/InfoTagRepository.java +++ b/src/main/java/solitour_backend/solitour/info_tag/repository/InfoTagRepository.java @@ -1,7 +1,6 @@ package solitour_backend.solitour.info_tag.repository; import java.util.List; - import org.springframework.data.jpa.repository.JpaRepository; import solitour_backend.solitour.info_tag.entity.InfoTag; diff --git a/src/main/java/solitour_backend/solitour/information/controller/InformationController.java b/src/main/java/solitour_backend/solitour/information/controller/InformationController.java index ec25678b..5e642038 100644 --- a/src/main/java/solitour_backend/solitour/information/controller/InformationController.java +++ b/src/main/java/solitour_backend/solitour/information/controller/InformationController.java @@ -3,10 +3,8 @@ import jakarta.servlet.http.HttpServletRequest; import jakarta.validation.Valid; - import java.util.List; import java.util.Objects; - import lombok.RequiredArgsConstructor; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; @@ -14,15 +12,27 @@ import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.validation.BindingResult; -import org.springframework.web.bind.annotation.*; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RequestPart; +import org.springframework.web.bind.annotation.RestController; import org.springframework.web.multipart.MultipartFile; +import solitour_backend.solitour.auth.config.Authenticated; import solitour_backend.solitour.auth.support.CookieExtractor; import solitour_backend.solitour.auth.support.JwtTokenProvider; -import solitour_backend.solitour.auth.config.Authenticated; import solitour_backend.solitour.error.Utils; import solitour_backend.solitour.information.dto.request.InformationModifyRequest; import solitour_backend.solitour.information.dto.request.InformationRegisterRequest; -import solitour_backend.solitour.information.dto.response.*; +import solitour_backend.solitour.information.dto.response.InformationBriefResponse; +import solitour_backend.solitour.information.dto.response.InformationDetailResponse; +import solitour_backend.solitour.information.dto.response.InformationMainResponse; +import solitour_backend.solitour.information.dto.response.InformationRankResponse; +import solitour_backend.solitour.information.dto.response.InformationResponse; import solitour_backend.solitour.information.service.InformationService; @RestController @@ -37,10 +47,11 @@ public class InformationController { @PostMapping @Authenticated - public ResponseEntity createInformation(@Valid @RequestPart("request") InformationRegisterRequest informationRegisterRequest, - @RequestPart("thumbNailImage") MultipartFile thumbnail, - @RequestPart("contentImages") List contentImages, - BindingResult bindingResult) { + public ResponseEntity createInformation( + @Valid @RequestPart("request") InformationRegisterRequest informationRegisterRequest, + @RequestPart("thumbNailImage") MultipartFile thumbnail, + @RequestPart("contentImages") List contentImages, + BindingResult bindingResult) { Utils.validationRequest(bindingResult); InformationResponse informationResponse = informationService.registerInformation( informationRegisterRequest, thumbnail, contentImages); @@ -54,7 +65,8 @@ public ResponseEntity createInformation(@Valid @RequestPart public ResponseEntity getDetailInformation(@PathVariable Long informationId, HttpServletRequest request) { Long userId = findUser(request); - InformationDetailResponse informationDetailResponse = informationService.getDetailInformation(userId, informationId); + InformationDetailResponse informationDetailResponse = informationService.getDetailInformation(userId, + informationId); return ResponseEntity .status(HttpStatus.OK) @@ -89,15 +101,17 @@ public ResponseEntity deleteInformation(@PathVariable Long informationId) } @GetMapping("/parent-category/{parentCategoryId}") - public ResponseEntity> pageInformationByParentCategoryFilterZoneCategory(@RequestParam(defaultValue = "0") int page, - @RequestParam(required = false, name = "zoneCategory") Long zoneCategoryId, - @PathVariable("parentCategoryId") Long categoryId, - HttpServletRequest request) { + public ResponseEntity> pageInformationByParentCategoryFilterZoneCategory( + @RequestParam(defaultValue = "0") int page, + @RequestParam(required = false, name = "zoneCategory") Long zoneCategoryId, + @PathVariable("parentCategoryId") Long categoryId, + HttpServletRequest request) { Long userId = findUser(request); Pageable pageable = PageRequest.of(page, PAGE_SIZE); - Page briefInformationPage = informationService.getBriefInformationPageByParentCategoryFilterZoneCategory(pageable, categoryId, userId, zoneCategoryId); + Page briefInformationPage = informationService.getBriefInformationPageByParentCategoryFilterZoneCategory( + pageable, categoryId, userId, zoneCategoryId); return ResponseEntity .status(HttpStatus.OK) @@ -105,14 +119,16 @@ public ResponseEntity> pageInformationByParentCat } @GetMapping("/child-category/{childCategoryId}") - public ResponseEntity> pageInformationByChildCategoryFilterZoneCategory(@RequestParam(defaultValue = "0") int page, - @PathVariable("childCategoryId") Long categoryId, - @RequestParam(required = false, name = "zoneCategory") Long zoneCategoryId, - HttpServletRequest request) { + public ResponseEntity> pageInformationByChildCategoryFilterZoneCategory( + @RequestParam(defaultValue = "0") int page, + @PathVariable("childCategoryId") Long categoryId, + @RequestParam(required = false, name = "zoneCategory") Long zoneCategoryId, + HttpServletRequest request) { Long userId = findUser(request); Pageable pageable = PageRequest.of(page, PAGE_SIZE); - Page briefInformationPage = informationService.getBriefInformationPageByChildCategoryFilterZoneCategory(pageable, categoryId, userId, zoneCategoryId); + Page briefInformationPage = informationService.getBriefInformationPageByChildCategoryFilterZoneCategory( + pageable, categoryId, userId, zoneCategoryId); return ResponseEntity .status(HttpStatus.OK) @@ -121,26 +137,30 @@ public ResponseEntity> pageInformationByChildCate //지역 카테고리 별 좋아요순 @GetMapping("/parent-category/{parentCategory}/like-count") - public ResponseEntity> pageInformationByParentCategoryFilterZoneCategoryLikeCount(@RequestParam(defaultValue = "0") int page, - @RequestParam(required = false, name = "zoneCategory") Long zoneCategoryId, - @PathVariable("parentCategory") Long categoryId, - HttpServletRequest request) { + public ResponseEntity> pageInformationByParentCategoryFilterZoneCategoryLikeCount( + @RequestParam(defaultValue = "0") int page, + @RequestParam(required = false, name = "zoneCategory") Long zoneCategoryId, + @PathVariable("parentCategory") Long categoryId, + HttpServletRequest request) { Long userId = findUser(request); Pageable pageable = PageRequest.of(page, PAGE_SIZE); - Page briefInformationPage = informationService.getBriefInformationPageByParentCategoryFilterZoneCategoryLikeCount(pageable, categoryId, userId, zoneCategoryId); + Page briefInformationPage = informationService.getBriefInformationPageByParentCategoryFilterZoneCategoryLikeCount( + pageable, categoryId, userId, zoneCategoryId); return ResponseEntity .status(HttpStatus.OK) .body(briefInformationPage); } @GetMapping("/child-category/{childCategory}/like-count") - public ResponseEntity> pageInformationChildCategoryFilterZoneCategoryLikeCount(@RequestParam(defaultValue = "0") int page, - @RequestParam(required = false, name = "zoneCategory") Long zoneCategoryId, - @PathVariable("childCategory") Long categoryId, - HttpServletRequest request) { + public ResponseEntity> pageInformationChildCategoryFilterZoneCategoryLikeCount( + @RequestParam(defaultValue = "0") int page, + @RequestParam(required = false, name = "zoneCategory") Long zoneCategoryId, + @PathVariable("childCategory") Long categoryId, + HttpServletRequest request) { Long userId = findUser(request); Pageable pageable = PageRequest.of(page, PAGE_SIZE); - Page briefInformationPage = informationService.getBriefInformationPageByChildCategoryFilterZoneCategoryLikeCount(pageable, categoryId, userId, zoneCategoryId); + Page briefInformationPage = informationService.getBriefInformationPageByChildCategoryFilterZoneCategoryLikeCount( + pageable, categoryId, userId, zoneCategoryId); return ResponseEntity .status(HttpStatus.OK) .body(briefInformationPage); @@ -149,27 +169,31 @@ public ResponseEntity> pageInformationChildCatego //지역 카테고리 별 조회순 @GetMapping("/parent-category/{parentCategoryId}/view-count") - public ResponseEntity> pageInformationByParentCategoryFilterZoneCategoryViewCount(@RequestParam(defaultValue = "0") int page, - @RequestParam(required = false, name = "zoneCategory") Long zoneCategoryId, - @PathVariable("parentCategoryId") Long categoryId, - HttpServletRequest request) { + public ResponseEntity> pageInformationByParentCategoryFilterZoneCategoryViewCount( + @RequestParam(defaultValue = "0") int page, + @RequestParam(required = false, name = "zoneCategory") Long zoneCategoryId, + @PathVariable("parentCategoryId") Long categoryId, + HttpServletRequest request) { Long userId = findUser(request); Pageable pageable = PageRequest.of(page, PAGE_SIZE); - Page briefInformationPage = informationService.getBriefInformationPageByParentCategoryFilterZoneCategoryViewCount(pageable, categoryId, userId, zoneCategoryId); + Page briefInformationPage = informationService.getBriefInformationPageByParentCategoryFilterZoneCategoryViewCount( + pageable, categoryId, userId, zoneCategoryId); return ResponseEntity .status(HttpStatus.OK) .body(briefInformationPage); } @GetMapping("/child-category/{childCategoryId}/view-count") - public ResponseEntity> pageInformationByChildCategoryViewCount(@RequestParam(defaultValue = "0") int page, - @PathVariable("childCategoryId") Long categoryId, - @RequestParam(required = false, name = "zoneCategory") Long zoneCategoryId, - HttpServletRequest request) { + public ResponseEntity> pageInformationByChildCategoryViewCount( + @RequestParam(defaultValue = "0") int page, + @PathVariable("childCategoryId") Long categoryId, + @RequestParam(required = false, name = "zoneCategory") Long zoneCategoryId, + HttpServletRequest request) { Long userId = findUser(request); Pageable pageable = PageRequest.of(page, PAGE_SIZE); - Page briefInformationPage = informationService.getBriefInformationPageByChildCategoryFilterZoneCategoryViewCount(pageable, categoryId, userId, zoneCategoryId); + Page briefInformationPage = informationService.getBriefInformationPageByChildCategoryFilterZoneCategoryViewCount( + pageable, categoryId, userId, zoneCategoryId); return ResponseEntity .status(HttpStatus.OK) .body(briefInformationPage); diff --git a/src/main/java/solitour_backend/solitour/information/dto/request/InformationModifyRequest.java b/src/main/java/solitour_backend/solitour/information/dto/request/InformationModifyRequest.java index 9140375c..a5bcc333 100644 --- a/src/main/java/solitour_backend/solitour/information/dto/request/InformationModifyRequest.java +++ b/src/main/java/solitour_backend/solitour/information/dto/request/InformationModifyRequest.java @@ -4,6 +4,7 @@ import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.Size; +import java.util.List; import lombok.Getter; import lombok.NoArgsConstructor; import solitour_backend.solitour.image.dto.request.ImageDeleteRequest; @@ -11,8 +12,6 @@ import solitour_backend.solitour.place.dto.request.PlaceModifyRequest; import solitour_backend.solitour.tag.dto.request.TagRegisterRequest; -import java.util.List; - @Getter @NoArgsConstructor public class InformationModifyRequest { diff --git a/src/main/java/solitour_backend/solitour/information/dto/request/InformationRegisterRequest.java b/src/main/java/solitour_backend/solitour/information/dto/request/InformationRegisterRequest.java index 25254a27..64c4d73e 100644 --- a/src/main/java/solitour_backend/solitour/information/dto/request/InformationRegisterRequest.java +++ b/src/main/java/solitour_backend/solitour/information/dto/request/InformationRegisterRequest.java @@ -4,9 +4,7 @@ import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.Size; - import java.util.List; - import lombok.Getter; import lombok.NoArgsConstructor; import solitour_backend.solitour.place.dto.request.PlaceRegisterRequest; diff --git a/src/main/java/solitour_backend/solitour/information/dto/response/InformationDetailResponse.java b/src/main/java/solitour_backend/solitour/information/dto/response/InformationDetailResponse.java index bdfc33bf..574c7e84 100644 --- a/src/main/java/solitour_backend/solitour/information/dto/response/InformationDetailResponse.java +++ b/src/main/java/solitour_backend/solitour/information/dto/response/InformationDetailResponse.java @@ -2,7 +2,6 @@ import java.time.LocalDateTime; import java.util.List; - import lombok.AllArgsConstructor; import lombok.Getter; import solitour_backend.solitour.image.dto.response.ImageResponse; diff --git a/src/main/java/solitour_backend/solitour/information/entity/Information.java b/src/main/java/solitour_backend/solitour/information/entity/Information.java index 9bc83035..bb60e6bc 100644 --- a/src/main/java/solitour_backend/solitour/information/entity/Information.java +++ b/src/main/java/solitour_backend/solitour/information/entity/Information.java @@ -1,9 +1,17 @@ package solitour_backend.solitour.information.entity; -import jakarta.persistence.*; - +import jakarta.persistence.CascadeType; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.FetchType; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.ManyToOne; +import jakarta.persistence.OneToOne; +import jakarta.persistence.Table; import java.time.LocalDateTime; - import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; diff --git a/src/main/java/solitour_backend/solitour/information/repository/InformationRepositoryCustom.java b/src/main/java/solitour_backend/solitour/information/repository/InformationRepositoryCustom.java index 07ff36c6..0ad412ad 100644 --- a/src/main/java/solitour_backend/solitour/information/repository/InformationRepositoryCustom.java +++ b/src/main/java/solitour_backend/solitour/information/repository/InformationRepositoryCustom.java @@ -1,5 +1,6 @@ package solitour_backend.solitour.information.repository; +import java.util.List; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.repository.NoRepositoryBean; @@ -7,23 +8,37 @@ import solitour_backend.solitour.information.dto.response.InformationMainResponse; import solitour_backend.solitour.information.dto.response.InformationRankResponse; -import java.util.List; - @NoRepositoryBean public interface InformationRepositoryCustom { - Page getInformationByParentCategoryFilterZoneCategory(Pageable pageable, Long parentCategoryId, Long userId, Long zoneCategoryId); - - Page getInformationByChildCategoryFilterZoneCategory(Pageable pageable, Long childCategoryId, Long userId, Long zoneCategoryId); - - Page getInformationByParentCategoryFilterZoneCategoryLikeCount(Pageable pageable, Long categoryId, Long userId, Long zoneCategoryId); - - Page getInformationByChildCategoryFilterZoneCategoryLikeCount(Pageable pageable, Long categoryId, Long userId, Long zoneCategoryId); - - Page getInformationByParentCategoryFilterZoneCategoryViewCount(Pageable pageable, Long categoryId, Long userId, Long zoneCategoryId); - - Page getInformationByChildCategoryFilterZoneCategoryViewCount(Pageable pageable, Long categoryId, Long userId, Long zoneCategoryId); + Page getInformationByParentCategoryFilterZoneCategory(Pageable pageable, + Long parentCategoryId, Long userId, + Long zoneCategoryId); + + Page getInformationByChildCategoryFilterZoneCategory(Pageable pageable, + Long childCategoryId, Long userId, + Long zoneCategoryId); + + Page getInformationByParentCategoryFilterZoneCategoryLikeCount(Pageable pageable, + Long categoryId, + Long userId, + Long zoneCategoryId); + + Page getInformationByChildCategoryFilterZoneCategoryLikeCount(Pageable pageable, + Long categoryId, + Long userId, + Long zoneCategoryId); + + Page getInformationByParentCategoryFilterZoneCategoryViewCount(Pageable pageable, + Long categoryId, + Long userId, + Long zoneCategoryId); + + Page getInformationByChildCategoryFilterZoneCategoryViewCount(Pageable pageable, + Long categoryId, + Long userId, + Long zoneCategoryId); List getInformationRank(); diff --git a/src/main/java/solitour_backend/solitour/information/repository/InformationRepositoryImpl.java b/src/main/java/solitour_backend/solitour/information/repository/InformationRepositoryImpl.java index 935f9ff5..27794bb3 100644 --- a/src/main/java/solitour_backend/solitour/information/repository/InformationRepositoryImpl.java +++ b/src/main/java/solitour_backend/solitour/information/repository/InformationRepositoryImpl.java @@ -2,6 +2,9 @@ import com.querydsl.core.types.Projections; import com.querydsl.jpa.JPQLQuery; +import java.time.LocalDateTime; +import java.util.List; +import java.util.Objects; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageImpl; import org.springframework.data.domain.Pageable; @@ -18,10 +21,6 @@ import solitour_backend.solitour.information.entity.QInformation; import solitour_backend.solitour.zone_category.entity.QZoneCategory; -import java.time.LocalDateTime; -import java.util.List; -import java.util.Objects; - public class InformationRepositoryImpl extends QuerydslRepositorySupport implements InformationRepositoryCustom { public InformationRepositoryImpl() { @@ -38,11 +37,15 @@ public InformationRepositoryImpl() { @Override - public Page getInformationByParentCategoryFilterZoneCategory(Pageable pageable, Long parentCategoryId, Long userId, Long zoneCategoryId) { + public Page getInformationByParentCategoryFilterZoneCategory(Pageable pageable, + Long parentCategoryId, + Long userId, + Long zoneCategoryId) { JPQLQuery query = from(information) .join(zoneCategoryChild).on(zoneCategoryChild.id.eq(information.zoneCategory.id)) .leftJoin(zoneCategoryParent).on(zoneCategoryParent.id.eq(zoneCategoryChild.parentZoneCategory.id)) - .leftJoin(bookMarkInformation).on(bookMarkInformation.information.id.eq(information.id).and(bookMarkInformation.user.id.eq(userId))) + .leftJoin(bookMarkInformation) + .on(bookMarkInformation.information.id.eq(information.id).and(bookMarkInformation.user.id.eq(userId))) .leftJoin(image).on(image.information.id.eq(information.id) .and(image.imageStatus.eq(ImageStatus.THUMBNAIL))) .leftJoin(greatInformation).on(greatInformation.information.id.eq(information.id)) @@ -76,11 +79,15 @@ public Page getInformationByParentCategoryFilterZoneCa } @Override - public Page getInformationByChildCategoryFilterZoneCategory(Pageable pageable, Long childCategoryId, Long userId, Long zoneCategoryId) { + public Page getInformationByChildCategoryFilterZoneCategory(Pageable pageable, + Long childCategoryId, + Long userId, + Long zoneCategoryId) { JPQLQuery query = from(information) .join(zoneCategoryChild).on(zoneCategoryChild.id.eq(information.zoneCategory.id)) .leftJoin(zoneCategoryParent).on(zoneCategoryParent.id.eq(zoneCategoryChild.parentZoneCategory.id)) - .leftJoin(bookMarkInformation).on(bookMarkInformation.information.id.eq(information.id).and(bookMarkInformation.user.id.eq(userId))) + .leftJoin(bookMarkInformation) + .on(bookMarkInformation.information.id.eq(information.id).and(bookMarkInformation.user.id.eq(userId))) .leftJoin(image).on(image.information.id.eq(information.id) .and(image.imageStatus.eq(ImageStatus.THUMBNAIL))) .leftJoin(greatInformation).on(greatInformation.information.id.eq(information.id)) @@ -115,11 +122,15 @@ public Page getInformationByChildCategoryFilterZoneCat @Override - public Page getInformationByParentCategoryFilterZoneCategoryLikeCount(Pageable pageable, Long categoryId, Long userId, Long zoneCategoryId) { + public Page getInformationByParentCategoryFilterZoneCategoryLikeCount(Pageable pageable, + Long categoryId, + Long userId, + Long zoneCategoryId) { JPQLQuery query = from(information) .join(zoneCategoryChild).on(zoneCategoryChild.id.eq(information.zoneCategory.id)) .leftJoin(zoneCategoryParent).on(zoneCategoryParent.id.eq(zoneCategoryChild.parentZoneCategory.id)) - .leftJoin(bookMarkInformation).on(bookMarkInformation.information.id.eq(information.id).and(bookMarkInformation.user.id.eq(userId))) + .leftJoin(bookMarkInformation) + .on(bookMarkInformation.information.id.eq(information.id).and(bookMarkInformation.user.id.eq(userId))) .leftJoin(image).on(image.information.id.eq(information.id) .and(image.imageStatus.eq(ImageStatus.THUMBNAIL))) .leftJoin(greatInformation).on(greatInformation.information.id.eq(information.id)) @@ -129,7 +140,8 @@ public Page getInformationByParentCategoryFilterZoneCa query = query.where(information.zoneCategory.parentZoneCategory.id.eq(zoneCategoryId)); } - List list = query.groupBy(information.id, zoneCategoryChild.id, zoneCategoryParent.id, image.id) + List list = query.groupBy(information.id, zoneCategoryChild.id, zoneCategoryParent.id, + image.id) .orderBy(greatInformation.information.count().desc()) .select(Projections.constructor( InformationBriefResponse.class, @@ -152,11 +164,15 @@ public Page getInformationByParentCategoryFilterZoneCa } @Override - public Page getInformationByChildCategoryFilterZoneCategoryLikeCount(Pageable pageable, Long categoryId, Long userId, Long zoneCategoryId) { + public Page getInformationByChildCategoryFilterZoneCategoryLikeCount(Pageable pageable, + Long categoryId, + Long userId, + Long zoneCategoryId) { JPQLQuery query = from(information) .join(zoneCategoryChild).on(zoneCategoryChild.id.eq(information.zoneCategory.id)) .leftJoin(zoneCategoryParent).on(zoneCategoryParent.id.eq(zoneCategoryChild.parentZoneCategory.id)) - .leftJoin(bookMarkInformation).on(bookMarkInformation.information.id.eq(information.id).and(bookMarkInformation.user.id.eq(userId))) + .leftJoin(bookMarkInformation) + .on(bookMarkInformation.information.id.eq(information.id).and(bookMarkInformation.user.id.eq(userId))) .leftJoin(image).on(image.information.id.eq(information.id) .and(image.imageStatus.eq(ImageStatus.THUMBNAIL))) .leftJoin(greatInformation).on(greatInformation.information.id.eq(information.id)) @@ -190,11 +206,15 @@ public Page getInformationByChildCategoryFilterZoneCat } @Override - public Page getInformationByParentCategoryFilterZoneCategoryViewCount(Pageable pageable, Long categoryId, Long userId, Long zoneCategoryId) { + public Page getInformationByParentCategoryFilterZoneCategoryViewCount(Pageable pageable, + Long categoryId, + Long userId, + Long zoneCategoryId) { JPQLQuery query = from(information) .join(zoneCategoryChild).on(zoneCategoryChild.id.eq(information.zoneCategory.id)) .leftJoin(zoneCategoryParent).on(zoneCategoryParent.id.eq(zoneCategoryChild.parentZoneCategory.id)) - .leftJoin(bookMarkInformation).on(bookMarkInformation.information.id.eq(information.id).and(bookMarkInformation.user.id.eq(userId))) + .leftJoin(bookMarkInformation) + .on(bookMarkInformation.information.id.eq(information.id).and(bookMarkInformation.user.id.eq(userId))) .leftJoin(image).on(image.information.id.eq(information.id) .and(image.imageStatus.eq(ImageStatus.THUMBNAIL))) .leftJoin(greatInformation).on(greatInformation.information.id.eq(information.id)) @@ -228,11 +248,15 @@ public Page getInformationByParentCategoryFilterZoneCa } @Override - public Page getInformationByChildCategoryFilterZoneCategoryViewCount(Pageable pageable, Long categoryId, Long userId, Long zoneCategoryId) { + public Page getInformationByChildCategoryFilterZoneCategoryViewCount(Pageable pageable, + Long categoryId, + Long userId, + Long zoneCategoryId) { JPQLQuery query = from(information) .join(zoneCategoryChild).on(zoneCategoryChild.id.eq(information.zoneCategory.id)) .leftJoin(zoneCategoryParent).on(zoneCategoryParent.id.eq(zoneCategoryChild.parentZoneCategory.id)) - .leftJoin(bookMarkInformation).on(bookMarkInformation.information.id.eq(information.id).and(bookMarkInformation.user.id.eq(userId))) + .leftJoin(bookMarkInformation) + .on(bookMarkInformation.information.id.eq(information.id).and(bookMarkInformation.user.id.eq(userId))) .leftJoin(image).on(image.information.id.eq(information.id) .and(image.imageStatus.eq(ImageStatus.THUMBNAIL))) .leftJoin(greatInformation).on(greatInformation.information.id.eq(information.id)) @@ -271,12 +295,15 @@ public List getInformationLikeCountFromCreatedIn3(Long return from(information) .leftJoin(zoneCategoryChild).on(zoneCategoryChild.id.eq(information.zoneCategory.id)) .leftJoin(zoneCategoryParent).on(zoneCategoryParent.id.eq(zoneCategoryChild.parentZoneCategory.id)) - .leftJoin(bookMarkInformation).on(bookMarkInformation.information.id.eq(information.id).and(bookMarkInformation.user.id.eq(userId))) - .leftJoin(image).on(image.information.id.eq(information.id).and(image.imageStatus.eq(ImageStatus.THUMBNAIL))) + .leftJoin(bookMarkInformation) + .on(bookMarkInformation.information.id.eq(information.id).and(bookMarkInformation.user.id.eq(userId))) + .leftJoin(image) + .on(image.information.id.eq(information.id).and(image.imageStatus.eq(ImageStatus.THUMBNAIL))) .leftJoin(greatInformation).on(greatInformation.information.id.eq(information.id)) .leftJoin(category).on(category.id.eq(information.category.id)) .where(information.createdDate.after(LocalDateTime.now().minusMonths(3))) - .groupBy(information.id, information.title, zoneCategoryParent.name, zoneCategoryChild.name, bookMarkInformation.id, image.address) + .groupBy(information.id, information.title, zoneCategoryParent.name, zoneCategoryChild.name, + bookMarkInformation.id, image.address) .orderBy(greatInformation.information.id.count().desc()) .select(Projections.constructor( InformationMainResponse.class, @@ -294,11 +321,13 @@ public List getInformationLikeCountFromCreatedIn3(Long } @Override - public List getInformationRecommend(Long informationId, Long childCategoryId, Long userId) { + public List getInformationRecommend(Long informationId, Long childCategoryId, + Long userId) { return from(information) .join(zoneCategoryChild).on(zoneCategoryChild.id.eq(information.zoneCategory.id)) .leftJoin(zoneCategoryParent).on(zoneCategoryParent.id.eq(zoneCategoryChild.parentZoneCategory.id)) - .leftJoin(bookMarkInformation).on(bookMarkInformation.information.id.eq(information.id).and(bookMarkInformation.user.id.eq(userId))) + .leftJoin(bookMarkInformation) + .on(bookMarkInformation.information.id.eq(information.id).and(bookMarkInformation.user.id.eq(userId))) .leftJoin(image).on(image.information.id.eq(information.id) .and(image.imageStatus.eq(ImageStatus.THUMBNAIL))) .leftJoin(greatInformation).on(greatInformation.information.id.eq(information.id)) diff --git a/src/main/java/solitour_backend/solitour/information/service/InformationService.java b/src/main/java/solitour_backend/solitour/information/service/InformationService.java index 88193ee2..e9f0bded 100644 --- a/src/main/java/solitour_backend/solitour/information/service/InformationService.java +++ b/src/main/java/solitour_backend/solitour/information/service/InformationService.java @@ -1,5 +1,10 @@ package solitour_backend.solitour.information.service; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; import lombok.RequiredArgsConstructor; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; @@ -10,7 +15,6 @@ import solitour_backend.solitour.category.entity.Category; import solitour_backend.solitour.category.exception.CategoryNotExistsException; import solitour_backend.solitour.category.repository.CategoryRepository; -import solitour_backend.solitour.error.exception.RequestValidationFailedException; import solitour_backend.solitour.great_information.repository.GreatInformationRepository; import solitour_backend.solitour.image.dto.mapper.ImageMapper; import solitour_backend.solitour.image.dto.request.ImageDeleteRequest; @@ -27,7 +31,11 @@ import solitour_backend.solitour.information.dto.mapper.InformationMapper; import solitour_backend.solitour.information.dto.request.InformationModifyRequest; import solitour_backend.solitour.information.dto.request.InformationRegisterRequest; -import solitour_backend.solitour.information.dto.response.*; +import solitour_backend.solitour.information.dto.response.InformationBriefResponse; +import solitour_backend.solitour.information.dto.response.InformationDetailResponse; +import solitour_backend.solitour.information.dto.response.InformationMainResponse; +import solitour_backend.solitour.information.dto.response.InformationRankResponse; +import solitour_backend.solitour.information.dto.response.InformationResponse; import solitour_backend.solitour.information.entity.Information; import solitour_backend.solitour.information.exception.InformationNotExistsException; import solitour_backend.solitour.information.repository.InformationRepository; @@ -51,12 +59,6 @@ import solitour_backend.solitour.zone_category.exception.ZoneCategoryNotExistsException; import solitour_backend.solitour.zone_category.repository.ZoneCategoryRepository; -import java.time.LocalDate; -import java.time.LocalDateTime; -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; - @Service @Transactional(readOnly = true) @RequiredArgsConstructor @@ -84,7 +86,8 @@ public class InformationService { @Transactional - public InformationResponse registerInformation(InformationRegisterRequest informationRegisterRequest, MultipartFile thumbnail, List contentImages) { + public InformationResponse registerInformation(InformationRegisterRequest informationRegisterRequest, + MultipartFile thumbnail, List contentImages) { Category category = categoryRepository.findById(informationRegisterRequest.getCategoryId()) .orElseThrow( () -> new CategoryNotExistsException("해당하는 id의 category 가 없습니다")); @@ -175,7 +178,8 @@ public InformationDetailResponse getDetailInformation(Long userId, Long informat int likeCount = greatInformationRepository.countByInformationId(information.getId()); - List informationRecommend = informationRepository.getInformationRecommend(information.getId(), information.getCategory().getId(), userId); + List informationRecommend = informationRepository.getInformationRecommend( + information.getId(), information.getCategory().getId(), userId); return new InformationDetailResponse( information.getTitle(), @@ -194,7 +198,8 @@ public InformationDetailResponse getDetailInformation(Long userId, Long informat } @Transactional - public InformationResponse modifyInformation(Long id, InformationModifyRequest informationModifyRequest, MultipartFile thumbNail, List contentImages) { + public InformationResponse modifyInformation(Long id, InformationModifyRequest informationModifyRequest, + MultipartFile thumbNail, List contentImages) { Information information = informationRepository.findById(id) .orElseThrow( () -> new InformationNotExistsException("해당하는 id의 information이 존재하지 않습니다.")); @@ -217,11 +222,13 @@ public InformationResponse modifyInformation(Long id, InformationModifyRequest i () -> new CategoryNotExistsException("해당하는 cateogry Id 가 존재하지 않습니다.")); information.setCategory(categoryInformation); - ZoneCategory parentZoneCategory = zoneCategoryRepository.findByParentZoneCategoryIdAndName(null, informationModifyRequest.getZoneCategoryNameParent()) + ZoneCategory parentZoneCategory = zoneCategoryRepository.findByParentZoneCategoryIdAndName(null, + informationModifyRequest.getZoneCategoryNameParent()) .orElseThrow( () -> new ZoneCategoryNotExistsException("해당하는 name에 대한 zoneCategory가 존재하지 않습니다")); - ZoneCategory childZoneCategory = zoneCategoryRepository.findByParentZoneCategoryIdAndName(parentZoneCategory.getId(), informationModifyRequest.getZoneCategoryNameChild()) + ZoneCategory childZoneCategory = zoneCategoryRepository.findByParentZoneCategoryIdAndName( + parentZoneCategory.getId(), informationModifyRequest.getZoneCategoryNameChild()) .orElseThrow( () -> new ZoneCategoryNotExistsException("해당하는 name에 대한 zoneCategory가 존재하지 않습니다")); @@ -326,7 +333,10 @@ public void deleteInformation(Long id) { } //default - public Page getBriefInformationPageByParentCategoryFilterZoneCategory(Pageable pageable, Long parentCategoryId, Long userId, Long zoneCategoryId) { + public Page getBriefInformationPageByParentCategoryFilterZoneCategory(Pageable pageable, + Long parentCategoryId, + Long userId, + Long zoneCategoryId) { if (!categoryRepository.existsById(parentCategoryId)) { throw new CategoryNotExistsException("해당하는 id의 category는 없습니다"); } @@ -334,21 +344,27 @@ public Page getBriefInformationPageByParentCategoryFil throw new ZoneCategoryNotExistsException("해당하는 id의 zoneCategory는 없습니다"); } - return informationRepository.getInformationByParentCategoryFilterZoneCategory(pageable, parentCategoryId, userId, zoneCategoryId); + return informationRepository.getInformationByParentCategoryFilterZoneCategory(pageable, parentCategoryId, + userId, zoneCategoryId); } - public Page getBriefInformationPageByChildCategoryFilterZoneCategory(Pageable pageable, Long childCategoryId, Long userId, Long zoneCategoryId) { + public Page getBriefInformationPageByChildCategoryFilterZoneCategory(Pageable pageable, + Long childCategoryId, + Long userId, + Long zoneCategoryId) { if (!categoryRepository.existsById(childCategoryId)) { throw new CategoryNotExistsException("해당하는 id의 category는 없습니다"); } if (Objects.nonNull(zoneCategoryId) && !zoneCategoryRepository.existsById(zoneCategoryId)) { throw new ZoneCategoryNotExistsException("해당하는 id의 zoneCategory는 없습니다"); } - return informationRepository.getInformationByChildCategoryFilterZoneCategory(pageable, childCategoryId, userId, zoneCategoryId); + return informationRepository.getInformationByChildCategoryFilterZoneCategory(pageable, childCategoryId, userId, + zoneCategoryId); } //지역카테고리별 좋아요순 - public Page getBriefInformationPageByParentCategoryFilterZoneCategoryLikeCount(Pageable pageable, Long parentCategoryId, Long userId, Long zoneCategoryId) { + public Page getBriefInformationPageByParentCategoryFilterZoneCategoryLikeCount( + Pageable pageable, Long parentCategoryId, Long userId, Long zoneCategoryId) { if (!categoryRepository.existsById(parentCategoryId)) { throw new CategoryNotExistsException("해당하는 id의 category는 없습니다"); } @@ -356,10 +372,12 @@ public Page getBriefInformationPageByParentCategoryFil throw new ZoneCategoryNotExistsException("해당하는 id의 zoneCategory는 없습니다"); } - return informationRepository.getInformationByParentCategoryFilterZoneCategoryLikeCount(pageable, parentCategoryId, userId, zoneCategoryId); + return informationRepository.getInformationByParentCategoryFilterZoneCategoryLikeCount(pageable, + parentCategoryId, userId, zoneCategoryId); } - public Page getBriefInformationPageByChildCategoryFilterZoneCategoryLikeCount(Pageable pageable, Long childCategoryId, Long userId, Long zoneCategoryId) { + public Page getBriefInformationPageByChildCategoryFilterZoneCategoryLikeCount( + Pageable pageable, Long childCategoryId, Long userId, Long zoneCategoryId) { if (!categoryRepository.existsById(childCategoryId)) { throw new CategoryNotExistsException("해당하는 id의 category는 없습니다"); } @@ -367,11 +385,13 @@ public Page getBriefInformationPageByChildCategoryFilt throw new ZoneCategoryNotExistsException("해당하는 id의 zoneCategory는 없습니다"); } - return informationRepository.getInformationByChildCategoryFilterZoneCategoryLikeCount(pageable, childCategoryId, userId, zoneCategoryId); + return informationRepository.getInformationByChildCategoryFilterZoneCategoryLikeCount(pageable, childCategoryId, + userId, zoneCategoryId); } //지역카테고리별 조회순 - public Page getBriefInformationPageByParentCategoryFilterZoneCategoryViewCount(Pageable pageable, Long parentCategoryId, Long userId, Long zoneCategoryId) { + public Page getBriefInformationPageByParentCategoryFilterZoneCategoryViewCount( + Pageable pageable, Long parentCategoryId, Long userId, Long zoneCategoryId) { if (!categoryRepository.existsById(parentCategoryId)) { throw new CategoryNotExistsException("해당하는 id의 category는 없습니다"); } @@ -379,10 +399,12 @@ public Page getBriefInformationPageByParentCategoryFil throw new ZoneCategoryNotExistsException("해당하는 id의 zoneCategory는 없습니다"); } - return informationRepository.getInformationByParentCategoryFilterZoneCategoryViewCount(pageable, parentCategoryId, userId, zoneCategoryId); + return informationRepository.getInformationByParentCategoryFilterZoneCategoryViewCount(pageable, + parentCategoryId, userId, zoneCategoryId); } - public Page getBriefInformationPageByChildCategoryFilterZoneCategoryViewCount(Pageable pageable, Long childCategoryId, Long userId, Long zoneCategoryId) { + public Page getBriefInformationPageByChildCategoryFilterZoneCategoryViewCount( + Pageable pageable, Long childCategoryId, Long userId, Long zoneCategoryId) { if (!categoryRepository.existsById(childCategoryId)) { throw new CategoryNotExistsException("해당하는 id의 category는 없습니다"); } @@ -390,7 +412,8 @@ public Page getBriefInformationPageByChildCategoryFilt throw new ZoneCategoryNotExistsException("해당하는 id의 zoneCategory는 없습니다"); } - return informationRepository.getInformationByChildCategoryFilterZoneCategoryViewCount(pageable, childCategoryId, userId, zoneCategoryId); + return informationRepository.getInformationByChildCategoryFilterZoneCategoryViewCount(pageable, childCategoryId, + userId, zoneCategoryId); } public List getRankInformation() { diff --git a/src/main/java/solitour_backend/solitour/place/dto/request/PlaceModifyRequest.java b/src/main/java/solitour_backend/solitour/place/dto/request/PlaceModifyRequest.java index 1e2deb67..36c02f37 100644 --- a/src/main/java/solitour_backend/solitour/place/dto/request/PlaceModifyRequest.java +++ b/src/main/java/solitour_backend/solitour/place/dto/request/PlaceModifyRequest.java @@ -7,9 +7,7 @@ import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.Size; - import java.math.BigDecimal; - import lombok.Getter; import lombok.NoArgsConstructor; diff --git a/src/main/java/solitour_backend/solitour/place/dto/request/PlaceRegisterRequest.java b/src/main/java/solitour_backend/solitour/place/dto/request/PlaceRegisterRequest.java index 7b155282..ca9d4256 100644 --- a/src/main/java/solitour_backend/solitour/place/dto/request/PlaceRegisterRequest.java +++ b/src/main/java/solitour_backend/solitour/place/dto/request/PlaceRegisterRequest.java @@ -7,9 +7,7 @@ import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.Size; - import java.math.BigDecimal; - import lombok.AllArgsConstructor; import lombok.Getter; import lombok.NoArgsConstructor; diff --git a/src/main/java/solitour_backend/solitour/place/dto/response/PlaceResponse.java b/src/main/java/solitour_backend/solitour/place/dto/response/PlaceResponse.java index 3779914a..61e397a0 100644 --- a/src/main/java/solitour_backend/solitour/place/dto/response/PlaceResponse.java +++ b/src/main/java/solitour_backend/solitour/place/dto/response/PlaceResponse.java @@ -1,7 +1,6 @@ package solitour_backend.solitour.place.dto.response; import java.math.BigDecimal; - import lombok.AllArgsConstructor; import lombok.Getter; diff --git a/src/main/java/solitour_backend/solitour/place/entity/Place.java b/src/main/java/solitour_backend/solitour/place/entity/Place.java index 036196c0..8e54daa0 100644 --- a/src/main/java/solitour_backend/solitour/place/entity/Place.java +++ b/src/main/java/solitour_backend/solitour/place/entity/Place.java @@ -6,9 +6,7 @@ import jakarta.persistence.GenerationType; import jakarta.persistence.Id; import jakarta.persistence.Table; - import java.math.BigDecimal; - import lombok.AllArgsConstructor; import lombok.Getter; import lombok.NoArgsConstructor; diff --git a/src/main/java/solitour_backend/solitour/tag/dto/mapper/TagMapper.java b/src/main/java/solitour_backend/solitour/tag/dto/mapper/TagMapper.java index 3ab218ed..337e7a17 100644 --- a/src/main/java/solitour_backend/solitour/tag/dto/mapper/TagMapper.java +++ b/src/main/java/solitour_backend/solitour/tag/dto/mapper/TagMapper.java @@ -1,7 +1,6 @@ package solitour_backend.solitour.tag.dto.mapper; import java.util.List; - import org.mapstruct.Mapper; import org.mapstruct.Mapping; import org.mapstruct.ReportingPolicy; diff --git a/src/main/java/solitour_backend/solitour/user/controller/UserController.java b/src/main/java/solitour_backend/solitour/user/controller/UserController.java index 262df1df..f3295d66 100644 --- a/src/main/java/solitour_backend/solitour/user/controller/UserController.java +++ b/src/main/java/solitour_backend/solitour/user/controller/UserController.java @@ -1,15 +1,12 @@ package solitour_backend.solitour.user.controller; -import jakarta.servlet.http.HttpServletRequest; import lombok.RequiredArgsConstructor; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestHeader; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; @@ -17,7 +14,6 @@ import solitour_backend.solitour.auth.config.AuthenticationPrincipal; import solitour_backend.solitour.auth.service.OauthService; import solitour_backend.solitour.auth.service.TokenService; -import solitour_backend.solitour.auth.support.CookieExtractor; import solitour_backend.solitour.auth.support.google.GoogleConnector; import solitour_backend.solitour.auth.support.kakao.KakaoConnector; import solitour_backend.solitour.user.dto.UpdateAgeAndSex; @@ -48,7 +44,8 @@ public ResponseEntity retrieveUserInfo(@AuthenticationPrincipa @Authenticated @PutMapping("/nickname") - public ResponseEntity updateNickname(@AuthenticationPrincipal Long userId, @RequestBody UpdateNicknameRequest request) { + public ResponseEntity updateNickname(@AuthenticationPrincipal Long userId, + @RequestBody UpdateNicknameRequest request) { try { userService.updateNickname(userId, request.nickname()); return ResponseEntity.ok("Nickname updated successfully"); @@ -63,9 +60,10 @@ public ResponseEntity updateNickname(@AuthenticationPrincipal Long userI @Authenticated @PutMapping("/age-sex") - public ResponseEntity updateAgeAndSex(@AuthenticationPrincipal Long userId, @RequestBody UpdateAgeAndSex request) { + public ResponseEntity updateAgeAndSex(@AuthenticationPrincipal Long userId, + @RequestBody UpdateAgeAndSex request) { try { - userService.updateAgeAndSex(userId, request.age(),request.sex()); + userService.updateAgeAndSex(userId, request.age(), request.sex()); return ResponseEntity.ok("Age and Sex updated successfully"); } catch (UserNotExistsException e) { return ResponseEntity.status(HttpStatus.NOT_FOUND).body("User not found"); @@ -76,8 +74,9 @@ public ResponseEntity updateAgeAndSex(@AuthenticationPrincipal Long user @Authenticated @DeleteMapping() - public ResponseEntity deleteUser(@AuthenticationPrincipal Long id, @RequestParam String type, @RequestParam String code, @RequestParam String redirectUrl) { - String token = getOauthAccessToken(type,code,redirectUrl); + public ResponseEntity deleteUser(@AuthenticationPrincipal Long id, @RequestParam String type, + @RequestParam String code, @RequestParam String redirectUrl) { + String token = getOauthAccessToken(type, code, redirectUrl); try { oauthservice.revokeToken(token); @@ -91,7 +90,7 @@ public ResponseEntity deleteUser(@AuthenticationPrincipal Long id, @Requ } } - private String getOauthAccessToken(String type, String code, String redirectUrl){ + private String getOauthAccessToken(String type, String code, String redirectUrl) { String token = ""; switch (type) { case "kakao" -> { diff --git a/src/main/java/solitour_backend/solitour/user/dto/UpdateAgeAndSex.java b/src/main/java/solitour_backend/solitour/user/dto/UpdateAgeAndSex.java index b8b051b0..d6269927 100644 --- a/src/main/java/solitour_backend/solitour/user/dto/UpdateAgeAndSex.java +++ b/src/main/java/solitour_backend/solitour/user/dto/UpdateAgeAndSex.java @@ -1,4 +1,4 @@ package solitour_backend.solitour.user.dto; -public record UpdateAgeAndSex(String age,String sex) { +public record UpdateAgeAndSex(String age, String sex) { } diff --git a/src/main/java/solitour_backend/solitour/user/entity/User.java b/src/main/java/solitour_backend/solitour/user/entity/User.java index 28cc6909..ac16c20d 100644 --- a/src/main/java/solitour_backend/solitour/user/entity/User.java +++ b/src/main/java/solitour_backend/solitour/user/entity/User.java @@ -10,9 +10,7 @@ import jakarta.persistence.JoinColumn; import jakarta.persistence.OneToOne; import jakarta.persistence.Table; - import java.time.LocalDateTime; - import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Getter; @@ -84,7 +82,7 @@ public void updateNickname(String nickname) { public void updateAgeAndSex(String age, String sex) { this.age = Integer.parseInt(age); - this.sex= sex; + this.sex = sex; } public void deleteUser(Long userId) { diff --git a/src/main/java/solitour_backend/solitour/user/entity/UserRepository.java b/src/main/java/solitour_backend/solitour/user/entity/UserRepository.java index a6df04db..d60646e6 100644 --- a/src/main/java/solitour_backend/solitour/user/entity/UserRepository.java +++ b/src/main/java/solitour_backend/solitour/user/entity/UserRepository.java @@ -1,10 +1,8 @@ package solitour_backend.solitour.user.entity; import java.util.Optional; - import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; -import solitour_backend.solitour.user.user_status.UserStatus; public interface UserRepository extends JpaRepository { diff --git a/src/main/java/solitour_backend/solitour/user/service/UserService.java b/src/main/java/solitour_backend/solitour/user/service/UserService.java index 5f51e382..38b84f52 100644 --- a/src/main/java/solitour_backend/solitour/user/service/UserService.java +++ b/src/main/java/solitour_backend/solitour/user/service/UserService.java @@ -33,7 +33,7 @@ public void updateNickname(Long userId, String nickname) { @Transactional public void updateAgeAndSex(Long userId, String age, String sex) { User user = userRepository.findByUserId(userId); - user.updateAgeAndSex(age,sex); + user.updateAgeAndSex(age, sex); } diff --git a/src/main/java/solitour_backend/solitour/user/user_status/UserStatus.java b/src/main/java/solitour_backend/solitour/user/user_status/UserStatus.java index 5b57113a..957a8cb3 100644 --- a/src/main/java/solitour_backend/solitour/user/user_status/UserStatus.java +++ b/src/main/java/solitour_backend/solitour/user/user_status/UserStatus.java @@ -1,7 +1,6 @@ package solitour_backend.solitour.user.user_status; import java.util.Arrays; - import lombok.Getter; @Getter diff --git a/src/main/java/solitour_backend/solitour/user_image/entity/UserImage.java b/src/main/java/solitour_backend/solitour/user_image/entity/UserImage.java index 6bd5b15f..62062a56 100644 --- a/src/main/java/solitour_backend/solitour/user_image/entity/UserImage.java +++ b/src/main/java/solitour_backend/solitour/user_image/entity/UserImage.java @@ -6,9 +6,7 @@ import jakarta.persistence.GenerationType; import jakarta.persistence.Id; import jakarta.persistence.Table; - import java.time.LocalDate; - import lombok.Getter; import lombok.NoArgsConstructor; diff --git a/src/main/java/solitour_backend/solitour/user_image/service/UserImageService.java b/src/main/java/solitour_backend/solitour/user_image/service/UserImageService.java index 8af2cbca..a8de5fc2 100644 --- a/src/main/java/solitour_backend/solitour/user_image/service/UserImageService.java +++ b/src/main/java/solitour_backend/solitour/user_image/service/UserImageService.java @@ -1,7 +1,6 @@ package solitour_backend.solitour.user_image.service; import java.time.LocalDate; - import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; diff --git a/src/main/java/solitour_backend/solitour/util/TimeUtil.java b/src/main/java/solitour_backend/solitour/util/TimeUtil.java index 9ecf8b03..f5a41d01 100644 --- a/src/main/java/solitour_backend/solitour/util/TimeUtil.java +++ b/src/main/java/solitour_backend/solitour/util/TimeUtil.java @@ -1,11 +1,10 @@ package solitour_backend.solitour.util; -import org.springframework.stereotype.Component; - import java.time.Duration; import java.time.LocalTime; import java.time.ZoneId; import java.time.ZonedDateTime; +import org.springframework.stereotype.Component; @Component public class TimeUtil { diff --git a/src/main/java/solitour_backend/solitour/zone_category/controller/ZoneCategoryController.java b/src/main/java/solitour_backend/solitour/zone_category/controller/ZoneCategoryController.java index d6af5d19..fd0f1112 100644 --- a/src/main/java/solitour_backend/solitour/zone_category/controller/ZoneCategoryController.java +++ b/src/main/java/solitour_backend/solitour/zone_category/controller/ZoneCategoryController.java @@ -37,8 +37,9 @@ public ResponseEntity getZoneCategory(@PathVariable Long i } @PostMapping - public ResponseEntity registerZoneCategory(@Valid @RequestBody ZoneCategoryRegisterRequest zoneCategoryRegisterRequest, - BindingResult bindingResult) { + public ResponseEntity registerZoneCategory( + @Valid @RequestBody ZoneCategoryRegisterRequest zoneCategoryRegisterRequest, + BindingResult bindingResult) { if (bindingResult.hasErrors()) { throw new RequestValidationFailedException(bindingResult); } diff --git a/src/main/java/solitour_backend/solitour/zone_category/repository/ZoneCategoryRepository.java b/src/main/java/solitour_backend/solitour/zone_category/repository/ZoneCategoryRepository.java index ef854ddf..24e599c7 100644 --- a/src/main/java/solitour_backend/solitour/zone_category/repository/ZoneCategoryRepository.java +++ b/src/main/java/solitour_backend/solitour/zone_category/repository/ZoneCategoryRepository.java @@ -1,7 +1,6 @@ package solitour_backend.solitour.zone_category.repository; import java.util.Optional; - import org.springframework.data.jpa.repository.JpaRepository; import solitour_backend.solitour.zone_category.entity.ZoneCategory; diff --git a/src/main/java/solitour_backend/solitour/zone_category/service/ZoneCategoryService.java b/src/main/java/solitour_backend/solitour/zone_category/service/ZoneCategoryService.java index 5da296c9..4f808ab1 100644 --- a/src/main/java/solitour_backend/solitour/zone_category/service/ZoneCategoryService.java +++ b/src/main/java/solitour_backend/solitour/zone_category/service/ZoneCategoryService.java @@ -1,7 +1,6 @@ package solitour_backend.solitour.zone_category.service; import java.util.Objects; - import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; From 67a427ced5c8110ecc3177f06793db460c726343 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Wed, 7 Aug 2024 02:42:45 +0900 Subject: [PATCH 076/371] =?UTF-8?q?feat:=20gatheringApplicants=20=EA=B0=80?= =?UTF-8?q?=20=EC=9D=B4=EB=AF=B8=20=EC=A1=B4=EC=9E=AC=ED=95=9C=EB=8B=A4?= =?UTF-8?q?=EB=8A=94=20=EC=98=88=EC=99=B8=20=ED=81=B4=EB=9E=98=EC=8A=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../GatheringApplicantsAlreadyExistsException.java | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 src/main/java/solitour_backend/solitour/gathering_applicants/exception/GatheringApplicantsAlreadyExistsException.java diff --git a/src/main/java/solitour_backend/solitour/gathering_applicants/exception/GatheringApplicantsAlreadyExistsException.java b/src/main/java/solitour_backend/solitour/gathering_applicants/exception/GatheringApplicantsAlreadyExistsException.java new file mode 100644 index 00000000..84d77588 --- /dev/null +++ b/src/main/java/solitour_backend/solitour/gathering_applicants/exception/GatheringApplicantsAlreadyExistsException.java @@ -0,0 +1,7 @@ +package solitour_backend.solitour.gathering_applicants.exception; + +public class GatheringApplicantsAlreadyExistsException extends RuntimeException { + public GatheringApplicantsAlreadyExistsException(String message) { + super(message); + } +} From 03ad4ee9b15097dbb38b56a6ca6cbea2f332f6d6 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Wed, 7 Aug 2024 02:43:05 +0900 Subject: [PATCH 077/371] =?UTF-8?q?feat:=20gatheringApplicants=20=EA=B0=80?= =?UTF-8?q?=20=EC=A1=B4=EC=9E=AC=ED=95=98=EC=A7=80=20=EC=95=8A=EB=8A=94?= =?UTF-8?q?=EB=8B=A4=EB=8A=94=20=EC=98=88=EC=99=B8=20=ED=81=B4=EB=9E=98?= =?UTF-8?q?=EC=8A=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../exception/GatheringApplicantsNotExistsException.java | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 src/main/java/solitour_backend/solitour/gathering_applicants/exception/GatheringApplicantsNotExistsException.java diff --git a/src/main/java/solitour_backend/solitour/gathering_applicants/exception/GatheringApplicantsNotExistsException.java b/src/main/java/solitour_backend/solitour/gathering_applicants/exception/GatheringApplicantsNotExistsException.java new file mode 100644 index 00000000..a6595fd4 --- /dev/null +++ b/src/main/java/solitour_backend/solitour/gathering_applicants/exception/GatheringApplicantsNotExistsException.java @@ -0,0 +1,7 @@ +package solitour_backend.solitour.gathering_applicants.exception; + +public class GatheringApplicantsNotExistsException extends RuntimeException { + public GatheringApplicantsNotExistsException(String message) { + super(message); + } +} From 2309009317e0a54fb2a250d9297c6f4189ab0f7b Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Wed, 7 Aug 2024 02:43:29 +0900 Subject: [PATCH 078/371] =?UTF-8?q?feat:=20gathering=20=ED=97=88=EC=9A=A9?= =?UTF-8?q?=EC=9D=B8=EC=9B=90=EC=9D=B4=20=EC=9D=B4=EB=AF=B8=20=EB=8B=A4=20?= =?UTF-8?q?=EC=B0=BC=EB=8B=A4=EB=8A=94=20=EC=98=88=EC=99=B8=20=ED=81=B4?= =?UTF-8?q?=EB=9E=98=EC=8A=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../GatheringApplicantsAlreadyFullPeopleException.java | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 src/main/java/solitour_backend/solitour/gathering_applicants/exception/GatheringApplicantsAlreadyFullPeopleException.java diff --git a/src/main/java/solitour_backend/solitour/gathering_applicants/exception/GatheringApplicantsAlreadyFullPeopleException.java b/src/main/java/solitour_backend/solitour/gathering_applicants/exception/GatheringApplicantsAlreadyFullPeopleException.java new file mode 100644 index 00000000..27fe8fce --- /dev/null +++ b/src/main/java/solitour_backend/solitour/gathering_applicants/exception/GatheringApplicantsAlreadyFullPeopleException.java @@ -0,0 +1,7 @@ +package solitour_backend.solitour.gathering_applicants.exception; + +public class GatheringApplicantsAlreadyFullPeopleException extends RuntimeException { + public GatheringApplicantsAlreadyFullPeopleException(String message) { + super(message); + } +} From c92273c575dc50f6dd57578af8a8bc1711aa7d31 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Wed, 7 Aug 2024 02:43:51 +0900 Subject: [PATCH 079/371] =?UTF-8?q?feat:=20=EC=98=88=EC=99=B8=ED=81=B4?= =?UTF-8?q?=EB=9E=98=EC=8A=A4=20handler=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../solitour/error/GlobalControllerAdvice.java | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/main/java/solitour_backend/solitour/error/GlobalControllerAdvice.java b/src/main/java/solitour_backend/solitour/error/GlobalControllerAdvice.java index a9c6d7de..a67ad8af 100644 --- a/src/main/java/solitour_backend/solitour/error/GlobalControllerAdvice.java +++ b/src/main/java/solitour_backend/solitour/error/GlobalControllerAdvice.java @@ -8,6 +8,9 @@ import solitour_backend.solitour.error.exception.RequestValidationFailedException; import solitour_backend.solitour.gathering.exception.GatheringCategoryNotExistsException; import solitour_backend.solitour.gathering.exception.GatheringNotExistsException; +import solitour_backend.solitour.gathering_applicants.exception.GatheringApplicantsAlreadyExistsException; +import solitour_backend.solitour.gathering_applicants.exception.GatheringApplicantsAlreadyFullPeopleException; +import solitour_backend.solitour.gathering_applicants.exception.GatheringApplicantsNotExistsException; import solitour_backend.solitour.image.exception.ImageAlreadyExistsException; import solitour_backend.solitour.image.exception.ImageNotExistsException; import solitour_backend.solitour.image.exception.ImageRequestValidationFailedException; @@ -26,7 +29,12 @@ public ResponseEntity validationException(Exception exception) { .body(exception.getMessage()); } - @ExceptionHandler({ZoneCategoryAlreadyExistsException.class, ImageAlreadyExistsException.class}) + @ExceptionHandler({ + ZoneCategoryAlreadyExistsException.class, + ImageAlreadyExistsException.class, + GatheringApplicantsAlreadyExistsException.class, + GatheringApplicantsAlreadyFullPeopleException.class + }) public ResponseEntity conflictException(Exception exception) { return ResponseEntity .status(HttpStatus.CONFLICT) @@ -40,7 +48,9 @@ public ResponseEntity conflictException(Exception exception) { InformationNotExistsException.class, UserNotExistsException.class, GatheringCategoryNotExistsException.class, - GatheringNotExistsException.class}) + GatheringNotExistsException.class, + GatheringApplicantsNotExistsException.class + }) public ResponseEntity notFoundException(Exception exception) { return ResponseEntity .status(HttpStatus.NOT_FOUND) From 0a8017dbf0faed87c1af47d03f50d1a039c5840f Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Wed, 7 Aug 2024 02:44:42 +0900 Subject: [PATCH 080/371] =?UTF-8?q?feat:=20gathering=20id=20=EC=99=80=20us?= =?UTF-8?q?er=20id=20=EC=97=90=20=ED=95=B4=EB=8B=B9=ED=95=98=EB=8A=94=20ga?= =?UTF-8?q?theringapplicants=20=EA=B0=80=20=EC=9E=88=EB=8A=94=EC=A7=80=20,?= =?UTF-8?q?=20gathering=20id=EC=99=80=20user=20id=20=EC=97=90=20=ED=95=B4?= =?UTF-8?q?=EB=8B=B9=ED=95=98=EB=8A=94=20gatheringapplicants=20=EC=A1=B0?= =?UTF-8?q?=ED=9A=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../repository/GatheringApplicantsRepository.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/main/java/solitour_backend/solitour/gathering_applicants/repository/GatheringApplicantsRepository.java b/src/main/java/solitour_backend/solitour/gathering_applicants/repository/GatheringApplicantsRepository.java index 8ecb3d53..1432d310 100644 --- a/src/main/java/solitour_backend/solitour/gathering_applicants/repository/GatheringApplicantsRepository.java +++ b/src/main/java/solitour_backend/solitour/gathering_applicants/repository/GatheringApplicantsRepository.java @@ -5,9 +5,14 @@ import solitour_backend.solitour.gathering_applicants.entity.GatheringStatus; import java.util.List; +import java.util.Optional; public interface GatheringApplicantsRepository extends JpaRepository { List findAllByGathering_Id(Long id); int countAllByGathering_IdAndGatheringStatus(Long id, GatheringStatus gatheringStatus); + + boolean existsByGatheringIdAndUserId(Long gatheringId, Long userId); + + Optional findByGatheringIdAndUserId(Long gatheringId, Long userId); } From cdeee9291c4e60086a74315f661e22dce62ec0ed Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Wed, 7 Aug 2024 02:45:33 +0900 Subject: [PATCH 081/371] =?UTF-8?q?feat:=20=EB=8B=A4=EB=A5=B8=20=EC=9C=A0?= =?UTF-8?q?=EC=A0=80=EA=B0=80=20=ED=95=B4=EB=8B=B9=20=EB=AA=A8=EC=9E=84?= =?UTF-8?q?=EC=97=90=20=EC=B0=B8=EC=97=AC=20=ED=95=98=EB=8A=94=20service,?= =?UTF-8?q?=20=EC=B0=B8=EC=97=AC=ED=95=9C=EB=8B=A4=EB=8A=94=20=EB=8B=A4?= =?UTF-8?q?=EB=A5=B8=20=EC=9C=A0=EC=A0=80=EA=B0=80=20=ED=95=B4=EB=8B=B9=20?= =?UTF-8?q?=EB=AA=A8=EC=9E=84=EC=97=90=20=EC=B0=B8=EC=97=AC=ED=95=98?= =?UTF-8?q?=EC=A7=80=20=EC=95=8A=EB=8A=94=EB=8B=A4=EB=8A=94=20service?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/GatheringApplicantsService.java | 72 +++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 src/main/java/solitour_backend/solitour/gathering_applicants/service/GatheringApplicantsService.java diff --git a/src/main/java/solitour_backend/solitour/gathering_applicants/service/GatheringApplicantsService.java b/src/main/java/solitour_backend/solitour/gathering_applicants/service/GatheringApplicantsService.java new file mode 100644 index 00000000..8d82d7b0 --- /dev/null +++ b/src/main/java/solitour_backend/solitour/gathering_applicants/service/GatheringApplicantsService.java @@ -0,0 +1,72 @@ +package solitour_backend.solitour.gathering_applicants.service; + +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import solitour_backend.solitour.gathering.entity.Gathering; +import solitour_backend.solitour.gathering.exception.GatheringNotExistsException; +import solitour_backend.solitour.gathering.repository.GatheringRepository; +import solitour_backend.solitour.gathering_applicants.entity.GatheringApplicants; +import solitour_backend.solitour.gathering_applicants.entity.GatheringStatus; +import solitour_backend.solitour.gathering_applicants.exception.GatheringApplicantsAlreadyExistsException; +import solitour_backend.solitour.gathering_applicants.exception.GatheringApplicantsAlreadyFullPeopleException; +import solitour_backend.solitour.gathering_applicants.exception.GatheringApplicantsNotExistsException; +import solitour_backend.solitour.gathering_applicants.repository.GatheringApplicantsRepository; +import solitour_backend.solitour.user.entity.User; +import solitour_backend.solitour.user.entity.UserRepository; +import solitour_backend.solitour.user.exception.UserNotExistsException; + +@Service +@Transactional +@RequiredArgsConstructor +public class GatheringApplicantsService { + private final GatheringRepository gatheringRepository; + private final GatheringApplicantsRepository gatheringApplicantsRepository; + private final UserRepository userRepository; + + public void participateGatheringFromAnotherUser(Long userId, Long gatheringId) { + Gathering gathering = gatheringRepository.findById(gatheringId) + .orElseThrow( + () -> + new GatheringNotExistsException("해당하는 id의 gathering 이 존재 하지 않습니다")); + + User user = userRepository.findById(userId) + .orElseThrow( + () -> + new UserNotExistsException("해당하는 id의 user가 없습니다")); + + if (gatheringApplicantsRepository.existsByGatheringIdAndUserId(gathering.getId(), user.getId())) { + throw new GatheringApplicantsAlreadyExistsException("해당 유저는 이미 참여 해 있습니다."); + } + + Integer personCount = gathering.getPersonCount(); + int nowPersonCount = gatheringApplicantsRepository.countAllByGathering_IdAndGatheringStatus(gatheringId, GatheringStatus.CONSENT); + + if (personCount <= nowPersonCount) { + throw new GatheringApplicantsAlreadyFullPeopleException("이미 인원이 가득 찼습니다."); + } + + GatheringApplicants gatheringApplicants = new GatheringApplicants(gathering, user, GatheringStatus.WAIT); + + gatheringApplicantsRepository.save(gatheringApplicants); + } + + public void deleteGatheringApplicantsFromAnotherUser(Long userId, Long gatheringId) { + Gathering gathering = gatheringRepository.findById(gatheringId) + .orElseThrow( + () -> + new GatheringNotExistsException("해당하는 id의 gathering 이 존재 하지 않습니다")); + + User user = userRepository.findById(userId) + .orElseThrow( + () -> + new UserNotExistsException("해당하는 id의 user가 없습니다")); + + GatheringApplicants gatheringApplicants = gatheringApplicantsRepository.findByGatheringIdAndUserId(gathering.getId(), user.getId()) + .orElseThrow( + () -> + new GatheringApplicantsNotExistsException("해당하는 모임과 user의 gathering applicants가 없습니다.")); + + gatheringApplicantsRepository.delete(gatheringApplicants); + } +} From af5e32803df79679fe9a750112adac8a0cf6989f Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Wed, 7 Aug 2024 02:45:50 +0900 Subject: [PATCH 082/371] =?UTF-8?q?feat:=20=EB=8B=A4=EB=A5=B8=20=EC=9C=A0?= =?UTF-8?q?=EC=A0=80=EA=B0=80=20=ED=95=B4=EB=8B=B9=20=EB=AA=A8=EC=9E=84?= =?UTF-8?q?=EC=97=90=20=EC=B0=B8=EC=97=AC=20=ED=95=98=EB=8A=94=20api,=20?= =?UTF-8?q?=EC=B0=B8=EC=97=AC=ED=95=9C=EB=8B=A4=EB=8A=94=20=EB=8B=A4?= =?UTF-8?q?=EB=A5=B8=20=EC=9C=A0=EC=A0=80=EA=B0=80=20=ED=95=B4=EB=8B=B9=20?= =?UTF-8?q?=EB=AA=A8=EC=9E=84=EC=97=90=20=EC=B0=B8=EC=97=AC=ED=95=98?= =?UTF-8?q?=EC=A7=80=20=EC=95=8A=EB=8A=94=EB=8B=A4=EB=8A=94=20api=20contro?= =?UTF-8?q?ller?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../GatheringApplicantsController.java | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 src/main/java/solitour_backend/solitour/gathering_applicants/controller/GatheringApplicantsController.java diff --git a/src/main/java/solitour_backend/solitour/gathering_applicants/controller/GatheringApplicantsController.java b/src/main/java/solitour_backend/solitour/gathering_applicants/controller/GatheringApplicantsController.java new file mode 100644 index 00000000..550d6b74 --- /dev/null +++ b/src/main/java/solitour_backend/solitour/gathering_applicants/controller/GatheringApplicantsController.java @@ -0,0 +1,33 @@ +package solitour_backend.solitour.gathering_applicants.controller; + +import lombok.RequiredArgsConstructor; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; +import solitour_backend.solitour.auth.config.AuthenticationPrincipal; +import solitour_backend.solitour.gathering_applicants.service.GatheringApplicantsService; + +@RestController +@RequiredArgsConstructor +@RequestMapping("/api/gatherings/applicants") +public class GatheringApplicantsController { + private final GatheringApplicantsService gatheringApplicantsService; + + @PostMapping("/{gatheringId}") + public ResponseEntity participateGathering(@AuthenticationPrincipal Long userId, @PathVariable Long gatheringId) { + gatheringApplicantsService.participateGatheringFromAnotherUser(userId, gatheringId); + + return ResponseEntity + .status(HttpStatus.CREATED) + .build(); + } + + @DeleteMapping("/{gatheringId}") + public ResponseEntity deleteParticipateGathering(@AuthenticationPrincipal Long userId, @PathVariable Long gatheringId) { + gatheringApplicantsService.deleteGatheringApplicantsFromAnotherUser(userId, gatheringId); + + return ResponseEntity + .status(HttpStatus.NO_CONTENT) + .build(); + } +} From 4eb5af12d16a33534a2011ea1379e0e19b51a880 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Thu, 8 Aug 2024 02:04:59 +0900 Subject: [PATCH 083/371] =?UTF-8?q?feat:=20=EB=AA=A8=EC=9E=84=20=EC=8B=A0?= =?UTF-8?q?=EC=B2=AD=20=EC=88=98=EC=A0=95=20request=20dto?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../GatheringApplicantsModifyRequest.java | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 src/main/java/solitour_backend/solitour/gathering_applicants/dto/request/GatheringApplicantsModifyRequest.java diff --git a/src/main/java/solitour_backend/solitour/gathering_applicants/dto/request/GatheringApplicantsModifyRequest.java b/src/main/java/solitour_backend/solitour/gathering_applicants/dto/request/GatheringApplicantsModifyRequest.java new file mode 100644 index 00000000..0164e334 --- /dev/null +++ b/src/main/java/solitour_backend/solitour/gathering_applicants/dto/request/GatheringApplicantsModifyRequest.java @@ -0,0 +1,19 @@ +package solitour_backend.solitour.gathering_applicants.dto.request; + +import jakarta.validation.constraints.Min; +import jakarta.validation.constraints.NotNull; +import lombok.Getter; +import lombok.NoArgsConstructor; +import solitour_backend.solitour.gathering_applicants.entity.GatheringStatus; + +@Getter +@NoArgsConstructor +public class GatheringApplicantsModifyRequest { + + @Min(1) + @NotNull + private Long userId; + + @NotNull + private GatheringStatus gatheringStatus; +} From 875d765b3949dbe32baf95f7f3dd9cf351f0b7a5 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Thu, 8 Aug 2024 02:05:24 +0900 Subject: [PATCH 084/371] =?UTF-8?q?feat:=20=EC=9A=94=EC=B2=AD=EC=9D=84=20?= =?UTF-8?q?=EB=B3=B4=EB=82=B8=20user=20=EA=B0=80=20=ED=95=B4=EB=8B=B9=20?= =?UTF-8?q?=EB=AA=A8=EC=9E=84=EC=97=90=20=EB=8C=80=ED=95=9C=20=EA=B6=8C?= =?UTF-8?q?=ED=95=9C=EC=9D=B4=20=EC=97=86=EC=9D=84=EB=95=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../exception/GatheringNotManagerException.java | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 src/main/java/solitour_backend/solitour/gathering_applicants/exception/GatheringNotManagerException.java diff --git a/src/main/java/solitour_backend/solitour/gathering_applicants/exception/GatheringNotManagerException.java b/src/main/java/solitour_backend/solitour/gathering_applicants/exception/GatheringNotManagerException.java new file mode 100644 index 00000000..2d83e2ca --- /dev/null +++ b/src/main/java/solitour_backend/solitour/gathering_applicants/exception/GatheringNotManagerException.java @@ -0,0 +1,7 @@ +package solitour_backend.solitour.gathering_applicants.exception; + +public class GatheringNotManagerException extends RuntimeException { + public GatheringNotManagerException(String message) { + super(message); + } +} From 52ace03b049d90cef82989007ad2268c4ce2f64c Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Thu, 8 Aug 2024 02:05:37 +0900 Subject: [PATCH 085/371] =?UTF-8?q?feat:=20exception=20handler=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../solitour/error/GlobalControllerAdvice.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/main/java/solitour_backend/solitour/error/GlobalControllerAdvice.java b/src/main/java/solitour_backend/solitour/error/GlobalControllerAdvice.java index a67ad8af..eb4c8236 100644 --- a/src/main/java/solitour_backend/solitour/error/GlobalControllerAdvice.java +++ b/src/main/java/solitour_backend/solitour/error/GlobalControllerAdvice.java @@ -11,6 +11,7 @@ import solitour_backend.solitour.gathering_applicants.exception.GatheringApplicantsAlreadyExistsException; import solitour_backend.solitour.gathering_applicants.exception.GatheringApplicantsAlreadyFullPeopleException; import solitour_backend.solitour.gathering_applicants.exception.GatheringApplicantsNotExistsException; +import solitour_backend.solitour.gathering_applicants.exception.GatheringNotManagerException; import solitour_backend.solitour.image.exception.ImageAlreadyExistsException; import solitour_backend.solitour.image.exception.ImageNotExistsException; import solitour_backend.solitour.image.exception.ImageRequestValidationFailedException; @@ -56,4 +57,11 @@ public ResponseEntity notFoundException(Exception exception) { .status(HttpStatus.NOT_FOUND) .body(exception.getMessage()); } + + @ExceptionHandler({GatheringNotManagerException.class}) + public ResponseEntity forbiddenException(Exception exception) { + return ResponseEntity + .status(HttpStatus.FORBIDDEN) + .body(exception.getMessage()); + } } From 58adcdb5b176c9a2f7d7e880d0036f1191dd365f Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Thu, 8 Aug 2024 02:06:01 +0900 Subject: [PATCH 086/371] =?UTF-8?q?feat:=20=EB=AA=A8=EC=9E=84=20=EC=8B=A0?= =?UTF-8?q?=EC=B2=AD=20=EC=83=81=ED=83=9C=20=EC=88=98=EC=A0=95=20service?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/GatheringApplicantsService.java | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/src/main/java/solitour_backend/solitour/gathering_applicants/service/GatheringApplicantsService.java b/src/main/java/solitour_backend/solitour/gathering_applicants/service/GatheringApplicantsService.java index 8d82d7b0..5e214c6e 100644 --- a/src/main/java/solitour_backend/solitour/gathering_applicants/service/GatheringApplicantsService.java +++ b/src/main/java/solitour_backend/solitour/gathering_applicants/service/GatheringApplicantsService.java @@ -6,16 +6,20 @@ import solitour_backend.solitour.gathering.entity.Gathering; import solitour_backend.solitour.gathering.exception.GatheringNotExistsException; import solitour_backend.solitour.gathering.repository.GatheringRepository; +import solitour_backend.solitour.gathering_applicants.dto.request.GatheringApplicantsModifyRequest; import solitour_backend.solitour.gathering_applicants.entity.GatheringApplicants; import solitour_backend.solitour.gathering_applicants.entity.GatheringStatus; import solitour_backend.solitour.gathering_applicants.exception.GatheringApplicantsAlreadyExistsException; import solitour_backend.solitour.gathering_applicants.exception.GatheringApplicantsAlreadyFullPeopleException; import solitour_backend.solitour.gathering_applicants.exception.GatheringApplicantsNotExistsException; +import solitour_backend.solitour.gathering_applicants.exception.GatheringNotManagerException; import solitour_backend.solitour.gathering_applicants.repository.GatheringApplicantsRepository; import solitour_backend.solitour.user.entity.User; import solitour_backend.solitour.user.entity.UserRepository; import solitour_backend.solitour.user.exception.UserNotExistsException; +import java.util.Objects; + @Service @Transactional @RequiredArgsConstructor @@ -69,4 +73,33 @@ public void deleteGatheringApplicantsFromAnotherUser(Long userId, Long gathering gatheringApplicantsRepository.delete(gatheringApplicants); } + + public boolean updateGatheringApplicantsManagement(Long userId, Long gatheringId, GatheringApplicantsModifyRequest gatheringApplicantsModifyRequest) { + Gathering gathering = gatheringRepository.findById(gatheringId) + .orElseThrow( + () -> + new GatheringNotExistsException("해당하는 id의 gathering 이 존재 하지 않습니다")); + + User user = userRepository.findById(userId) + .orElseThrow( + () -> + new UserNotExistsException("해당하는 id의 user가 없습니다")); + + if (!Objects.equals(gathering.getUser(), user)) { + throw new GatheringNotManagerException("해당하는 user 가 해당 gathering 의 manage 가 아닙니다"); + } + + GatheringApplicants gatheringApplicants = gatheringApplicantsRepository.findByGatheringIdAndUserId(gathering.getId(), gatheringApplicantsModifyRequest.getUserId()) + .orElseThrow( + () -> + new GatheringApplicantsNotExistsException("해당하는 모임, user 의 applicants 가 없습니다") + ); + + if (Objects.equals(gatheringApplicants.getGatheringStatus(), gatheringApplicantsModifyRequest.getGatheringStatus())) { + return false; + } + + gatheringApplicants.setGatheringStatus(gatheringApplicantsModifyRequest.getGatheringStatus()); + return true; + } } From cd459f8483ae56b8943c8dfad621ac1e21578a97 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Thu, 8 Aug 2024 02:06:09 +0900 Subject: [PATCH 087/371] =?UTF-8?q?feat:=20=EB=AA=A8=EC=9E=84=20=EC=8B=A0?= =?UTF-8?q?=EC=B2=AD=20=EC=83=81=ED=83=9C=20=EC=88=98=EC=A0=95=20controlle?= =?UTF-8?q?r?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../GatheringApplicantsController.java | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/main/java/solitour_backend/solitour/gathering_applicants/controller/GatheringApplicantsController.java b/src/main/java/solitour_backend/solitour/gathering_applicants/controller/GatheringApplicantsController.java index 550d6b74..32ee93c2 100644 --- a/src/main/java/solitour_backend/solitour/gathering_applicants/controller/GatheringApplicantsController.java +++ b/src/main/java/solitour_backend/solitour/gathering_applicants/controller/GatheringApplicantsController.java @@ -1,10 +1,12 @@ package solitour_backend.solitour.gathering_applicants.controller; +import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; import solitour_backend.solitour.auth.config.AuthenticationPrincipal; +import solitour_backend.solitour.gathering_applicants.dto.request.GatheringApplicantsModifyRequest; import solitour_backend.solitour.gathering_applicants.service.GatheringApplicantsService; @RestController @@ -30,4 +32,22 @@ public ResponseEntity deleteParticipateGathering(@AuthenticationPrincipal .status(HttpStatus.NO_CONTENT) .build(); } + + @PutMapping("/{gatheringId}") + public ResponseEntity updateParticipateGatheringStatus(@AuthenticationPrincipal Long userId, + @PathVariable Long gatheringId, + @Valid @RequestBody GatheringApplicantsModifyRequest gatheringApplicantsModifyRequest) { + + boolean result = gatheringApplicantsService.updateGatheringApplicantsManagement(userId, gatheringId, gatheringApplicantsModifyRequest); + + if (result) { + return ResponseEntity + .status(HttpStatus.CREATED) + .build(); + } + + return ResponseEntity + .status(HttpStatus.NO_CONTENT) + .build(); + } } From 1ee8a546b60c3de0bd1eaa55696370b4d10974f2 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Thu, 8 Aug 2024 22:15:22 +0900 Subject: [PATCH 088/371] =?UTF-8?q?feat:=20=EB=AA=A8=EC=9E=84=20=EC=88=98?= =?UTF-8?q?=EC=A0=95=20request=20dto?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dto/request/GatheringModifyRequest.java | 67 +++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 src/main/java/solitour_backend/solitour/gathering/dto/request/GatheringModifyRequest.java diff --git a/src/main/java/solitour_backend/solitour/gathering/dto/request/GatheringModifyRequest.java b/src/main/java/solitour_backend/solitour/gathering/dto/request/GatheringModifyRequest.java new file mode 100644 index 00000000..65910c16 --- /dev/null +++ b/src/main/java/solitour_backend/solitour/gathering/dto/request/GatheringModifyRequest.java @@ -0,0 +1,67 @@ +package solitour_backend.solitour.gathering.dto.request; + +import com.fasterxml.jackson.annotation.JsonFormat; +import jakarta.validation.constraints.*; +import lombok.Getter; +import lombok.NoArgsConstructor; +import org.springframework.format.annotation.DateTimeFormat; +import solitour_backend.solitour.gathering.entity.AllowedSex; +import solitour_backend.solitour.place.dto.request.PlaceModifyRequest; +import solitour_backend.solitour.tag.dto.request.TagRegisterRequest; + +import java.time.LocalDateTime; +import java.util.List; + +@Getter +@NoArgsConstructor +public class GatheringModifyRequest { + @NotBlank + @Size(min = 1, max = 50) + private String title; + private String content; + + @NotNull + @Min(2) + @Max(10) + private Integer personCount; + + @JsonFormat(pattern = "yyyy-MM-dd HH:mm") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm") + private LocalDateTime scheduleStartDate; + + @JsonFormat(pattern = "yyyy-MM-dd HH:mm") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm") + private LocalDateTime scheduleEndDate; + + @JsonFormat(pattern = "yyyy-MM-dd HH:mm") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm") + private LocalDateTime deadline; + + @NotNull + private AllowedSex allowedSex; + + @NotNull + @Min(20) + private Integer startAge; + + @NotNull + @Min(20) + private Integer endAge; + + @NotNull + private PlaceModifyRequest placeModifyRequest; + + @NotNull + @Min(1) + private Long gatheringCategoryId; + + @NotBlank + @Size(min = 1, max = 20) + private String zoneCategoryNameParent; + + @NotBlank + @Size(min = 1, max = 20) + private String zoneCategoryNameChild; + + private List tagRegisterRequests; +} From 30830576eb21e5f93d2deb497505fd8ddb6da379 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Thu, 8 Aug 2024 22:15:43 +0900 Subject: [PATCH 089/371] =?UTF-8?q?feat:=20=EB=AA=A8=EC=9E=84=20entity=20s?= =?UTF-8?q?etter=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../solitour_backend/solitour/gathering/entity/Gathering.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/solitour_backend/solitour/gathering/entity/Gathering.java b/src/main/java/solitour_backend/solitour/gathering/entity/Gathering.java index fd7b0a75..5784ccd1 100644 --- a/src/main/java/solitour_backend/solitour/gathering/entity/Gathering.java +++ b/src/main/java/solitour_backend/solitour/gathering/entity/Gathering.java @@ -6,6 +6,7 @@ import lombok.Getter; import lombok.NoArgsConstructor; +import lombok.Setter; import org.springframework.data.annotation.CreatedDate; import org.springframework.data.annotation.LastModifiedDate; import org.springframework.data.jpa.domain.support.AuditingEntityListener; @@ -16,6 +17,7 @@ @Entity @Getter +@Setter @Table(name = "gathering") @NoArgsConstructor @EntityListeners(AuditingEntityListener.class) From 7c4439ac501c61cd73acdebdd5c458a4fa5ed84e Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Thu, 8 Aug 2024 22:19:26 +0900 Subject: [PATCH 090/371] =?UTF-8?q?feat:=20gathering=20tag=20repository=20?= =?UTF-8?q?=EB=AA=A8=EC=9E=84=20=EC=95=84=EC=9D=B4=EB=94=94=EC=97=90=20?= =?UTF-8?q?=ED=95=B4=EB=8B=B9=ED=95=98=EB=8A=94=20gatheringTag=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 --- .../gathering_tag/repository/GatheringTagRepository.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/solitour_backend/solitour/gathering_tag/repository/GatheringTagRepository.java b/src/main/java/solitour_backend/solitour/gathering_tag/repository/GatheringTagRepository.java index 96e08e2d..f1982424 100644 --- a/src/main/java/solitour_backend/solitour/gathering_tag/repository/GatheringTagRepository.java +++ b/src/main/java/solitour_backend/solitour/gathering_tag/repository/GatheringTagRepository.java @@ -7,4 +7,6 @@ public interface GatheringTagRepository extends JpaRepository { List findAllByGathering_Id(Long gatheringId); + + void deleteAllByGathering_Id(Long gatheringId); } From 1051ae16797a9b553038d6879d06e256cb578cb1 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Thu, 8 Aug 2024 22:19:49 +0900 Subject: [PATCH 091/371] =?UTF-8?q?style:=20import=20=EB=AC=B8=20=EC=A0=95?= =?UTF-8?q?=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../solitour/information/service/InformationService.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/solitour_backend/solitour/information/service/InformationService.java b/src/main/java/solitour_backend/solitour/information/service/InformationService.java index 2651f254..d25e24b9 100644 --- a/src/main/java/solitour_backend/solitour/information/service/InformationService.java +++ b/src/main/java/solitour_backend/solitour/information/service/InformationService.java @@ -10,7 +10,6 @@ import solitour_backend.solitour.category.entity.Category; import solitour_backend.solitour.category.exception.CategoryNotExistsException; import solitour_backend.solitour.category.repository.CategoryRepository; -import solitour_backend.solitour.error.exception.RequestValidationFailedException; import solitour_backend.solitour.great_information.repository.GreatInformationRepository; import solitour_backend.solitour.image.dto.mapper.ImageMapper; import solitour_backend.solitour.image.dto.request.ImageDeleteRequest; From 3f612606122a7b75693b82a19f4f06d322a5bbea Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Thu, 8 Aug 2024 22:20:06 +0900 Subject: [PATCH 092/371] =?UTF-8?q?style:=20gathering=20=EC=88=98=EC=A0=95?= =?UTF-8?q?=20service?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../gathering/service/GatheringService.java | 77 +++++++++++++++++++ 1 file changed, 77 insertions(+) diff --git a/src/main/java/solitour_backend/solitour/gathering/service/GatheringService.java b/src/main/java/solitour_backend/solitour/gathering/service/GatheringService.java index 9d10ad4d..5e203648 100644 --- a/src/main/java/solitour_backend/solitour/gathering/service/GatheringService.java +++ b/src/main/java/solitour_backend/solitour/gathering/service/GatheringService.java @@ -4,6 +4,7 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import solitour_backend.solitour.gathering.dto.mapper.GatheringMapper; +import solitour_backend.solitour.gathering.dto.request.GatheringModifyRequest; import solitour_backend.solitour.gathering.dto.request.GatheringRegisterRequest; import solitour_backend.solitour.gathering.dto.response.GatheringBriefResponse; import solitour_backend.solitour.gathering.dto.response.GatheringDetailResponse; @@ -15,6 +16,7 @@ import solitour_backend.solitour.gathering_applicants.dto.mapper.GatheringApplicantsMapper; import solitour_backend.solitour.gathering_applicants.dto.response.GatheringApplicantsResponse; import solitour_backend.solitour.gathering_applicants.entity.GatheringStatus; +import solitour_backend.solitour.gathering_applicants.exception.GatheringNotManagerException; import solitour_backend.solitour.gathering_applicants.repository.GatheringApplicantsRepository; import solitour_backend.solitour.gathering_category.entity.GatheringCategory; import solitour_backend.solitour.gathering_category.repository.GatheringCategoryRepository; @@ -22,6 +24,7 @@ import solitour_backend.solitour.gathering_tag.repository.GatheringTagRepository; import solitour_backend.solitour.great_gathering.repository.GreatGatheringRepository; import solitour_backend.solitour.place.dto.mapper.PlaceMapper; +import solitour_backend.solitour.place.dto.request.PlaceModifyRequest; import solitour_backend.solitour.place.dto.request.PlaceRegisterRequest; import solitour_backend.solitour.place.dto.response.PlaceResponse; import solitour_backend.solitour.place.entity.Place; @@ -43,6 +46,7 @@ import java.util.ArrayList; import java.util.List; +import java.util.Objects; @Service @Transactional(readOnly = true) @@ -177,5 +181,78 @@ public GatheringResponse registerGathering(Long userId, GatheringRegisterRequest return gatheringMapper.mapToGatheringResponse(saveGathering); } + @Transactional + public GatheringResponse modifyGathering(Long userId, Long gatheringId, GatheringModifyRequest gatheringModifyRequest) { + User user = userRepository.findById(userId) + .orElseThrow( + () -> new UserNotExistsException("해당하는 id의 User 가 없습니다")); + + Gathering gathering = gatheringRepository.findById(gatheringId) + .orElseThrow( + () -> new GatheringNotExistsException("해당하는 id의 gathering 이 존재 하지 않습니다")); + + if (!Objects.equals(user, gathering.getUser())) { + throw new GatheringNotManagerException("해당 유저는 권한이 없습니다"); + } + + GatheringCategory gatheringCategory = gatheringCategoryRepository.findById(gatheringModifyRequest.getGatheringCategoryId()).orElseThrow(); + ZoneCategory parentZoneCategory = zoneCategoryRepository.findByParentZoneCategoryIdAndName(null, gatheringModifyRequest.getZoneCategoryNameParent()).orElseThrow(); + ZoneCategory childZoneCategory = zoneCategoryRepository.findByParentZoneCategoryIdAndName(parentZoneCategory.getId(), gatheringModifyRequest.getZoneCategoryNameChild()).orElseThrow(); + + + Place place = gathering.getPlace(); + PlaceModifyRequest placeModifyRequest = gatheringModifyRequest.getPlaceModifyRequest(); + place.setSearchId(placeModifyRequest.getSearchId()); + place.setName(placeModifyRequest.getName()); + place.setXaxis(placeModifyRequest.getXAxis()); + place.setYaxis(placeModifyRequest.getYAxis()); + place.setAddress(placeModifyRequest.getAddress()); + + gathering.setTitle(gatheringModifyRequest.getTitle()); + gathering.setContent(gatheringModifyRequest.getContent()); + + gathering.setPersonCount(gatheringModifyRequest.getPersonCount()); + gathering.setScheduleStartDate(gatheringModifyRequest.getScheduleStartDate()); + gathering.setScheduleEndDate(gatheringModifyRequest.getScheduleEndDate()); + gathering.setDeadline(gatheringModifyRequest.getDeadline()); + gathering.setAllowedSex(gatheringModifyRequest.getAllowedSex()); + gathering.setStartAge(gatheringModifyRequest.getStartAge()); + gathering.setEndAge(gatheringModifyRequest.getEndAge()); + gathering.setGatheringCategory(gatheringCategory); + gathering.setZoneCategory(childZoneCategory); + + List gatheringTags = gatheringTagRepository.findAllByGathering_Id(gathering.getId()); + + gatheringTagRepository.deleteAllByGathering_Id(gathering.getId()); + + for (GatheringTag gatheringTag : gatheringTags) { + tagRepository.deleteById(gatheringTag.getTag().getTagId()); + } + + List saveTags = tagRepository.saveAll(tagMapper.mapToTags(gatheringModifyRequest.getTagRegisterRequests())); + + for (Tag tag : saveTags) { + gatheringTagRepository.save(new GatheringTag(tag, gathering)); + } + + return gatheringMapper.mapToGatheringResponse(gathering); + } + } + + + + + + + + + + + + + + + + From 23f675b1b9150cc62fe78931cf831d2b5211d404 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Thu, 8 Aug 2024 22:20:46 +0900 Subject: [PATCH 093/371] =?UTF-8?q?style:=20gathering=20=EC=88=98=EC=A0=95?= =?UTF-8?q?=20controller?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/GatheringController.java | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/src/main/java/solitour_backend/solitour/gathering/controller/GatheringController.java b/src/main/java/solitour_backend/solitour/gathering/controller/GatheringController.java index c0891100..997bb773 100644 --- a/src/main/java/solitour_backend/solitour/gathering/controller/GatheringController.java +++ b/src/main/java/solitour_backend/solitour/gathering/controller/GatheringController.java @@ -12,6 +12,7 @@ import solitour_backend.solitour.auth.support.JwtTokenProvider; import solitour_backend.solitour.error.Utils; import solitour_backend.solitour.error.exception.RequestValidationFailedException; +import solitour_backend.solitour.gathering.dto.request.GatheringModifyRequest; import solitour_backend.solitour.gathering.dto.request.GatheringRegisterRequest; import solitour_backend.solitour.gathering.dto.response.GatheringDetailResponse; import solitour_backend.solitour.gathering.dto.response.GatheringResponse; @@ -62,6 +63,30 @@ public ResponseEntity getGatheringDetail(@PathVariable .body(gatheringDetail); } + @PutMapping("/{gatheringId}") + public ResponseEntity updateGathering(@PathVariable Long gatheringId, + @Valid @RequestBody GatheringModifyRequest gatheringModifyRequest, + HttpServletRequest request) { + + Long userId = findUser(request); + + if (gatheringModifyRequest.getEndAge() > gatheringModifyRequest.getStartAge()) { + throw new RequestValidationFailedException("시작 나이 연도가 끝 나이 연도 보다 앞에 있네요"); + } + if (gatheringModifyRequest.getScheduleStartDate().isAfter(gatheringModifyRequest.getScheduleEndDate())) { + throw new RequestValidationFailedException("시작 날짜는 종료 날짜보다 앞에 있어야 합니다."); + } + + if (gatheringModifyRequest.getDeadline().isBefore(LocalDateTime.now())) { + throw new RequestValidationFailedException("마감일은 현재 시간보다 이후여야 합니다."); + } + GatheringResponse gatheringResponse = gatheringService.modifyGathering(userId, gatheringId, gatheringModifyRequest); + + return ResponseEntity + .status(HttpStatus.CREATED) + .body(gatheringResponse); + } + private Long findUser(HttpServletRequest request) { String token = CookieExtractor.findToken("access_token", request.getCookies()); From 46fe3410f67bc1fd6d94a910e33abbd072a3750d Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Thu, 8 Aug 2024 22:24:00 +0900 Subject: [PATCH 094/371] =?UTF-8?q?refactor:=20user=20=EC=9D=B8=EC=A6=9D?= =?UTF-8?q?=20=EC=B2=B4=ED=81=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../solitour/gathering/controller/GatheringController.java | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/main/java/solitour_backend/solitour/gathering/controller/GatheringController.java b/src/main/java/solitour_backend/solitour/gathering/controller/GatheringController.java index 997bb773..6c61a769 100644 --- a/src/main/java/solitour_backend/solitour/gathering/controller/GatheringController.java +++ b/src/main/java/solitour_backend/solitour/gathering/controller/GatheringController.java @@ -64,11 +64,10 @@ public ResponseEntity getGatheringDetail(@PathVariable } @PutMapping("/{gatheringId}") - public ResponseEntity updateGathering(@PathVariable Long gatheringId, - @Valid @RequestBody GatheringModifyRequest gatheringModifyRequest, - HttpServletRequest request) { + public ResponseEntity updateGathering(@AuthenticationPrincipal Long userId, + @PathVariable Long gatheringId, + @Valid @RequestBody GatheringModifyRequest gatheringModifyRequest) { - Long userId = findUser(request); if (gatheringModifyRequest.getEndAge() > gatheringModifyRequest.getStartAge()) { throw new RequestValidationFailedException("시작 나이 연도가 끝 나이 연도 보다 앞에 있네요"); From 33337fcfb2ede6cba4e5b8331a0debd7fdf364a2 Mon Sep 17 00:00:00 2001 From: Donghun Won Date: Sat, 10 Aug 2024 18:08:22 +0900 Subject: [PATCH 095/371] =?UTF-8?q?Feat=20:=20=EC=B9=B4=EC=B9=B4=EC=98=A4?= =?UTF-8?q?=20=ED=9A=8C=EC=9B=90=ED=83=88=ED=87=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../solitour/auth/service/OauthService.java | 11 ++++++-- .../auth/support/google/GoogleConnector.java | 6 ++-- .../auth/support/kakao/KakaoConnector.java | 28 +++++++++++++++++++ .../auth/support/kakao/KakaoProvider.java | 4 +++ .../user/controller/UserController.java | 2 +- 5 files changed, 44 insertions(+), 7 deletions(-) diff --git a/src/main/java/solitour_backend/solitour/auth/service/OauthService.java b/src/main/java/solitour_backend/solitour/auth/service/OauthService.java index a8cc5eed..f7b00022 100644 --- a/src/main/java/solitour_backend/solitour/auth/service/OauthService.java +++ b/src/main/java/solitour_backend/solitour/auth/service/OauthService.java @@ -180,9 +180,13 @@ public void logout(Long userId) { tokenService.deleteByMemberId(userId); } - public void revokeToken(String token) throws IOException { - - HttpStatusCode responseCode = googleConnector.requestRevoke(token); + public void revokeToken(Long userId,String type, String token) throws IOException { + HttpStatusCode responseCode; + switch (type) { + case "kakao" -> responseCode = kakaoConnector.requestRevoke(userId,token); + case "google" -> responseCode = googleConnector.requestRevoke(token); + default -> throw new RuntimeException("Unsupported oauth type"); + } if (responseCode.is2xxSuccessful()) { System.out.println("Token successfully revoked"); @@ -191,4 +195,5 @@ public void revokeToken(String token) throws IOException { throw new RuntimeException("Failed to revoke token"); } } + } diff --git a/src/main/java/solitour_backend/solitour/auth/support/google/GoogleConnector.java b/src/main/java/solitour_backend/solitour/auth/support/google/GoogleConnector.java index 0355f882..decb3703 100644 --- a/src/main/java/solitour_backend/solitour/auth/support/google/GoogleConnector.java +++ b/src/main/java/solitour_backend/solitour/auth/support/google/GoogleConnector.java @@ -54,7 +54,7 @@ public String requestAccessToken(String code, String redirectUrl) { public HttpStatusCode requestRevoke(String token) throws IOException { HttpEntity> entity = new HttpEntity<>( - createLogoutBody(token), createLogoutHeaders()); + createRevokeBody(token), createRevokeHeaders()); ResponseEntity response = REST_TEMPLATE.postForEntity(provider.getRevokeUrl(), entity, Void.class); @@ -78,13 +78,13 @@ private MultiValueMap createLoginBody(String code, String redire return body; } - private HttpHeaders createLogoutHeaders() { + private HttpHeaders createRevokeHeaders() { HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED); return headers; } - private MultiValueMap createLogoutBody(String token) { + private MultiValueMap createRevokeBody(String token) { MultiValueMap body = new LinkedMultiValueMap<>(); body.add("token", token); return body; diff --git a/src/main/java/solitour_backend/solitour/auth/support/kakao/KakaoConnector.java b/src/main/java/solitour_backend/solitour/auth/support/kakao/KakaoConnector.java index bcfe0708..ab9801a2 100644 --- a/src/main/java/solitour_backend/solitour/auth/support/kakao/KakaoConnector.java +++ b/src/main/java/solitour_backend/solitour/auth/support/kakao/KakaoConnector.java @@ -1,13 +1,18 @@ package solitour_backend.solitour.auth.support.kakao; +import java.io.IOException; import java.util.Collections; +import java.util.HashMap; +import java.util.Map; import java.util.Optional; +import java.util.stream.Collectors; import lombok.Getter; import lombok.RequiredArgsConstructor; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; +import org.springframework.http.HttpStatusCode; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Component; @@ -72,4 +77,27 @@ private String extractAccessToken(ResponseEntity responseEnt return response.getAccessToken(); } + + public HttpStatusCode requestRevoke(Long userId, String token) throws IOException { + HttpEntity> entity = new HttpEntity<>( + createRevokeBody(userId), createRevokeHeaders(token)); + + ResponseEntity response = REST_TEMPLATE.postForEntity(provider.getRevokeUrl(), entity, Void.class); + + return response.getStatusCode(); + } + + private HttpHeaders createRevokeHeaders(String token) { + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED); + headers.set("Authorization", "KakaoAK "+ token); + return headers; + } + + private MultiValueMap createRevokeBody(Long userId) { + MultiValueMap body = new LinkedMultiValueMap<>(); + body.add("user_id", userId.toString()); + body.add("referrer_type", "UNLINK_FROM_APPS"); + return body; + } } diff --git a/src/main/java/solitour_backend/solitour/auth/support/kakao/KakaoProvider.java b/src/main/java/solitour_backend/solitour/auth/support/kakao/KakaoProvider.java index 4b4975a1..38af039f 100644 --- a/src/main/java/solitour_backend/solitour/auth/support/kakao/KakaoProvider.java +++ b/src/main/java/solitour_backend/solitour/auth/support/kakao/KakaoProvider.java @@ -17,15 +17,18 @@ public class KakaoProvider { private final String accessTokenUrl; private final String userInfoUrl; private final String grantType; + private final String revokeUrl; private final String scope; + public KakaoProvider(@Value("${oauth2.kakao.client.id}") String clientId, @Value("${oauth2.kakao.client.secret}") String clientSecret, @Value("${oauth2.kakao.url.auth}") String authUrl, @Value("${oauth2.kakao.url.token}") String accessTokenUrl, @Value("${oauth2.kakao.url.userinfo}") String userInfoUrl, @Value("${oauth2.kakao.grant-type}") String grantType, + @Value("${oauth2.kakao.url.revoke}") String revokeUrl, @Value("${oauth2.kakao.scope}") String scope) { this.clientId = clientId; this.clientSecret = clientSecret; @@ -33,6 +36,7 @@ public KakaoProvider(@Value("${oauth2.kakao.client.id}") String clientId, this.accessTokenUrl = accessTokenUrl; this.userInfoUrl = userInfoUrl; this.grantType = grantType; + this.revokeUrl = revokeUrl; this.scope = scope; } diff --git a/src/main/java/solitour_backend/solitour/user/controller/UserController.java b/src/main/java/solitour_backend/solitour/user/controller/UserController.java index f3295d66..797a9594 100644 --- a/src/main/java/solitour_backend/solitour/user/controller/UserController.java +++ b/src/main/java/solitour_backend/solitour/user/controller/UserController.java @@ -79,7 +79,7 @@ public ResponseEntity deleteUser(@AuthenticationPrincipal Long id, @Requ String token = getOauthAccessToken(type, code, redirectUrl); try { - oauthservice.revokeToken(token); + oauthservice.revokeToken(id,type,token); userService.deleteUser(id); oauthservice.logout(id); From 949fda17bae50e88e294861b06d17a57928d51b9 Mon Sep 17 00:00:00 2001 From: Donghun Won Date: Sat, 10 Aug 2024 19:16:00 +0900 Subject: [PATCH 096/371] =?UTF-8?q?Refactor=20:=20=EC=B9=B4=EC=B9=B4?= =?UTF-8?q?=EC=98=A4=20=ED=9A=8C=EC=9B=90=ED=83=88=ED=87=B4=20=EB=A1=9C?= =?UTF-8?q?=EC=A7=81=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../solitour/auth/service/OauthService.java | 4 ++-- .../auth/support/kakao/KakaoConnector.java | 15 ++++----------- .../solitour/user/controller/UserController.java | 4 ++-- 3 files changed, 8 insertions(+), 15 deletions(-) diff --git a/src/main/java/solitour_backend/solitour/auth/service/OauthService.java b/src/main/java/solitour_backend/solitour/auth/service/OauthService.java index f7b00022..3ce4474d 100644 --- a/src/main/java/solitour_backend/solitour/auth/service/OauthService.java +++ b/src/main/java/solitour_backend/solitour/auth/service/OauthService.java @@ -180,10 +180,10 @@ public void logout(Long userId) { tokenService.deleteByMemberId(userId); } - public void revokeToken(Long userId,String type, String token) throws IOException { + public void revokeToken(String type, String token) throws IOException { HttpStatusCode responseCode; switch (type) { - case "kakao" -> responseCode = kakaoConnector.requestRevoke(userId,token); + case "kakao" -> responseCode = kakaoConnector.requestRevoke(token); case "google" -> responseCode = googleConnector.requestRevoke(token); default -> throw new RuntimeException("Unsupported oauth type"); } diff --git a/src/main/java/solitour_backend/solitour/auth/support/kakao/KakaoConnector.java b/src/main/java/solitour_backend/solitour/auth/support/kakao/KakaoConnector.java index ab9801a2..1b3a3327 100644 --- a/src/main/java/solitour_backend/solitour/auth/support/kakao/KakaoConnector.java +++ b/src/main/java/solitour_backend/solitour/auth/support/kakao/KakaoConnector.java @@ -78,11 +78,10 @@ private String extractAccessToken(ResponseEntity responseEnt return response.getAccessToken(); } - public HttpStatusCode requestRevoke(Long userId, String token) throws IOException { - HttpEntity> entity = new HttpEntity<>( - createRevokeBody(userId), createRevokeHeaders(token)); + public HttpStatusCode requestRevoke(String token) throws IOException { + HttpEntity> entity = new HttpEntity<>(createRevokeHeaders(token)); - ResponseEntity response = REST_TEMPLATE.postForEntity(provider.getRevokeUrl(), entity, Void.class); + ResponseEntity response = REST_TEMPLATE.postForEntity(provider.getRevokeUrl(), entity, String.class); return response.getStatusCode(); } @@ -90,14 +89,8 @@ public HttpStatusCode requestRevoke(Long userId, String token) throws IOExceptio private HttpHeaders createRevokeHeaders(String token) { HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED); - headers.set("Authorization", "KakaoAK "+ token); + headers.set("Authorization", String.join(" ", BEARER_TYPE, token)); return headers; } - private MultiValueMap createRevokeBody(Long userId) { - MultiValueMap body = new LinkedMultiValueMap<>(); - body.add("user_id", userId.toString()); - body.add("referrer_type", "UNLINK_FROM_APPS"); - return body; - } } diff --git a/src/main/java/solitour_backend/solitour/user/controller/UserController.java b/src/main/java/solitour_backend/solitour/user/controller/UserController.java index 797a9594..f08faf7b 100644 --- a/src/main/java/solitour_backend/solitour/user/controller/UserController.java +++ b/src/main/java/solitour_backend/solitour/user/controller/UserController.java @@ -79,10 +79,10 @@ public ResponseEntity deleteUser(@AuthenticationPrincipal Long id, @Requ String token = getOauthAccessToken(type, code, redirectUrl); try { - oauthservice.revokeToken(id,type,token); + oauthservice.revokeToken(type,token); - userService.deleteUser(id); oauthservice.logout(id); + userService.deleteUser(id); return ResponseEntity.ok("User deleted successfully"); } catch (Exception e) { From 29233061dd00eb37096132845f2cc878108e8570 Mon Sep 17 00:00:00 2001 From: Donghun Won Date: Sat, 10 Aug 2024 19:17:04 +0900 Subject: [PATCH 097/371] =?UTF-8?q?Style=20:=20=EC=BD=94=EB=93=9C=20?= =?UTF-8?q?=ED=8F=AC=EB=A7=B7=ED=8C=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dto/mapper/GatheringCategoryMapper.java | 2 +- .../service/GatheringCategoryService.java | 4 +-- .../solitour/auth/service/OauthService.java | 2 +- .../auth/support/kakao/KakaoConnector.java | 3 -- .../auth/support/kakao/KakaoProvider.java | 1 - .../controller/GatheringController.java | 17 +++++---- .../dto/request/GatheringModifyRequest.java | 11 +++--- .../dto/request/GatheringRegisterRequest.java | 11 +++--- .../dto/response/GatheringBriefResponse.java | 3 +- .../dto/response/GatheringDetailResponse.java | 5 ++- .../solitour/gathering/entity/AllowedSex.java | 3 +- .../solitour/gathering/entity/Gathering.java | 19 +++++++--- .../repository/GatheringRepositoryCustom.java | 3 +- .../repository/GatheringRepositoryImpl.java | 9 ++--- .../gathering/service/GatheringService.java | 35 +++++++++++-------- .../GatheringApplicantsController.java | 17 ++++++--- .../dto/mapper/GatheringApplicantsMapper.java | 3 +- .../entity/GatheringApplicants.java | 11 +++++- .../entity/GatheringStatus.java | 3 +- .../GatheringApplicantsRepository.java | 5 ++- .../service/GatheringApplicantsService.java | 21 ++++++----- .../repository/GatheringTagRepository.java | 3 +- .../user/controller/UserController.java | 2 +- 23 files changed, 117 insertions(+), 76 deletions(-) diff --git a/src/main/java/solitour_backend/solitour/admin/dto/mapper/GatheringCategoryMapper.java b/src/main/java/solitour_backend/solitour/admin/dto/mapper/GatheringCategoryMapper.java index b49e9eed..07838841 100644 --- a/src/main/java/solitour_backend/solitour/admin/dto/mapper/GatheringCategoryMapper.java +++ b/src/main/java/solitour_backend/solitour/admin/dto/mapper/GatheringCategoryMapper.java @@ -3,8 +3,8 @@ import java.util.List; import org.mapstruct.Mapper; import org.mapstruct.ReportingPolicy; -import solitour_backend.solitour.gathering_category.entity.GatheringCategory; import solitour_backend.solitour.category.dto.response.CategoryResponse; +import solitour_backend.solitour.gathering_category.entity.GatheringCategory; @Mapper(componentModel = "spring", unmappedTargetPolicy = ReportingPolicy.ERROR) public interface GatheringCategoryMapper { diff --git a/src/main/java/solitour_backend/solitour/admin/service/GatheringCategoryService.java b/src/main/java/solitour_backend/solitour/admin/service/GatheringCategoryService.java index 4dcbbfab..58b50f9c 100644 --- a/src/main/java/solitour_backend/solitour/admin/service/GatheringCategoryService.java +++ b/src/main/java/solitour_backend/solitour/admin/service/GatheringCategoryService.java @@ -7,13 +7,13 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import solitour_backend.solitour.admin.dto.mapper.GatheringCategoryMapper; -import solitour_backend.solitour.gathering_category.entity.GatheringCategory; -import solitour_backend.solitour.gathering_category.repository.GatheringCategoryRepository; import solitour_backend.solitour.category.dto.request.CategoryModifyRequest; import solitour_backend.solitour.category.dto.request.CategoryRegisterRequest; import solitour_backend.solitour.category.dto.response.CategoryGetResponse; import solitour_backend.solitour.category.dto.response.CategoryResponse; import solitour_backend.solitour.category.exception.CategoryNotExistsException; +import solitour_backend.solitour.gathering_category.entity.GatheringCategory; +import solitour_backend.solitour.gathering_category.repository.GatheringCategoryRepository; @Service @Transactional(readOnly = true) diff --git a/src/main/java/solitour_backend/solitour/auth/service/OauthService.java b/src/main/java/solitour_backend/solitour/auth/service/OauthService.java index 3ce4474d..9c2ad915 100644 --- a/src/main/java/solitour_backend/solitour/auth/service/OauthService.java +++ b/src/main/java/solitour_backend/solitour/auth/service/OauthService.java @@ -183,7 +183,7 @@ public void logout(Long userId) { public void revokeToken(String type, String token) throws IOException { HttpStatusCode responseCode; switch (type) { - case "kakao" -> responseCode = kakaoConnector.requestRevoke(token); + case "kakao" -> responseCode = kakaoConnector.requestRevoke(token); case "google" -> responseCode = googleConnector.requestRevoke(token); default -> throw new RuntimeException("Unsupported oauth type"); } diff --git a/src/main/java/solitour_backend/solitour/auth/support/kakao/KakaoConnector.java b/src/main/java/solitour_backend/solitour/auth/support/kakao/KakaoConnector.java index 1b3a3327..a690fcc3 100644 --- a/src/main/java/solitour_backend/solitour/auth/support/kakao/KakaoConnector.java +++ b/src/main/java/solitour_backend/solitour/auth/support/kakao/KakaoConnector.java @@ -3,10 +3,7 @@ import java.io.IOException; import java.util.Collections; -import java.util.HashMap; -import java.util.Map; import java.util.Optional; -import java.util.stream.Collectors; import lombok.Getter; import lombok.RequiredArgsConstructor; import org.springframework.http.HttpEntity; diff --git a/src/main/java/solitour_backend/solitour/auth/support/kakao/KakaoProvider.java b/src/main/java/solitour_backend/solitour/auth/support/kakao/KakaoProvider.java index 38af039f..bfbb1ad8 100644 --- a/src/main/java/solitour_backend/solitour/auth/support/kakao/KakaoProvider.java +++ b/src/main/java/solitour_backend/solitour/auth/support/kakao/KakaoProvider.java @@ -21,7 +21,6 @@ public class KakaoProvider { private final String scope; - public KakaoProvider(@Value("${oauth2.kakao.client.id}") String clientId, @Value("${oauth2.kakao.client.secret}") String clientSecret, @Value("${oauth2.kakao.url.auth}") String authUrl, diff --git a/src/main/java/solitour_backend/solitour/gathering/controller/GatheringController.java b/src/main/java/solitour_backend/solitour/gathering/controller/GatheringController.java index 6c61a769..5f75bd2d 100644 --- a/src/main/java/solitour_backend/solitour/gathering/controller/GatheringController.java +++ b/src/main/java/solitour_backend/solitour/gathering/controller/GatheringController.java @@ -2,11 +2,19 @@ import jakarta.servlet.http.HttpServletRequest; import jakarta.validation.Valid; +import java.time.LocalDateTime; +import java.util.Objects; import lombok.RequiredArgsConstructor; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.validation.BindingResult; -import org.springframework.web.bind.annotation.*; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; import solitour_backend.solitour.auth.config.AuthenticationPrincipal; import solitour_backend.solitour.auth.support.CookieExtractor; import solitour_backend.solitour.auth.support.JwtTokenProvider; @@ -18,9 +26,6 @@ import solitour_backend.solitour.gathering.dto.response.GatheringResponse; import solitour_backend.solitour.gathering.service.GatheringService; -import java.time.LocalDateTime; -import java.util.Objects; - @RestController @RequiredArgsConstructor @RequestMapping("/api/gatherings") @@ -68,7 +73,6 @@ public ResponseEntity updateGathering(@AuthenticationPrincipa @PathVariable Long gatheringId, @Valid @RequestBody GatheringModifyRequest gatheringModifyRequest) { - if (gatheringModifyRequest.getEndAge() > gatheringModifyRequest.getStartAge()) { throw new RequestValidationFailedException("시작 나이 연도가 끝 나이 연도 보다 앞에 있네요"); } @@ -79,7 +83,8 @@ public ResponseEntity updateGathering(@AuthenticationPrincipa if (gatheringModifyRequest.getDeadline().isBefore(LocalDateTime.now())) { throw new RequestValidationFailedException("마감일은 현재 시간보다 이후여야 합니다."); } - GatheringResponse gatheringResponse = gatheringService.modifyGathering(userId, gatheringId, gatheringModifyRequest); + GatheringResponse gatheringResponse = gatheringService.modifyGathering(userId, gatheringId, + gatheringModifyRequest); return ResponseEntity .status(HttpStatus.CREATED) diff --git a/src/main/java/solitour_backend/solitour/gathering/dto/request/GatheringModifyRequest.java b/src/main/java/solitour_backend/solitour/gathering/dto/request/GatheringModifyRequest.java index 65910c16..366e042f 100644 --- a/src/main/java/solitour_backend/solitour/gathering/dto/request/GatheringModifyRequest.java +++ b/src/main/java/solitour_backend/solitour/gathering/dto/request/GatheringModifyRequest.java @@ -1,7 +1,13 @@ package solitour_backend.solitour.gathering.dto.request; import com.fasterxml.jackson.annotation.JsonFormat; -import jakarta.validation.constraints.*; +import jakarta.validation.constraints.Max; +import jakarta.validation.constraints.Min; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; +import java.time.LocalDateTime; +import java.util.List; import lombok.Getter; import lombok.NoArgsConstructor; import org.springframework.format.annotation.DateTimeFormat; @@ -9,9 +15,6 @@ import solitour_backend.solitour.place.dto.request.PlaceModifyRequest; import solitour_backend.solitour.tag.dto.request.TagRegisterRequest; -import java.time.LocalDateTime; -import java.util.List; - @Getter @NoArgsConstructor public class GatheringModifyRequest { diff --git a/src/main/java/solitour_backend/solitour/gathering/dto/request/GatheringRegisterRequest.java b/src/main/java/solitour_backend/solitour/gathering/dto/request/GatheringRegisterRequest.java index f4832d35..c3815d9c 100644 --- a/src/main/java/solitour_backend/solitour/gathering/dto/request/GatheringRegisterRequest.java +++ b/src/main/java/solitour_backend/solitour/gathering/dto/request/GatheringRegisterRequest.java @@ -1,7 +1,13 @@ package solitour_backend.solitour.gathering.dto.request; import com.fasterxml.jackson.annotation.JsonFormat; -import jakarta.validation.constraints.*; +import jakarta.validation.constraints.Max; +import jakarta.validation.constraints.Min; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; +import java.time.LocalDateTime; +import java.util.List; import lombok.Getter; import lombok.NoArgsConstructor; import org.springframework.format.annotation.DateTimeFormat; @@ -9,9 +15,6 @@ import solitour_backend.solitour.place.dto.request.PlaceRegisterRequest; import solitour_backend.solitour.tag.dto.request.TagRegisterRequest; -import java.time.LocalDateTime; -import java.util.List; - @Getter @NoArgsConstructor public class GatheringRegisterRequest { diff --git a/src/main/java/solitour_backend/solitour/gathering/dto/response/GatheringBriefResponse.java b/src/main/java/solitour_backend/solitour/gathering/dto/response/GatheringBriefResponse.java index 72f033f9..00c5c788 100644 --- a/src/main/java/solitour_backend/solitour/gathering/dto/response/GatheringBriefResponse.java +++ b/src/main/java/solitour_backend/solitour/gathering/dto/response/GatheringBriefResponse.java @@ -1,11 +1,10 @@ package solitour_backend.solitour.gathering.dto.response; +import java.time.LocalDateTime; import lombok.AllArgsConstructor; import lombok.Getter; import solitour_backend.solitour.gathering.entity.AllowedSex; -import java.time.LocalDateTime; - @Getter @AllArgsConstructor public class GatheringBriefResponse { diff --git a/src/main/java/solitour_backend/solitour/gathering/dto/response/GatheringDetailResponse.java b/src/main/java/solitour_backend/solitour/gathering/dto/response/GatheringDetailResponse.java index 492b08ed..3e7601d5 100644 --- a/src/main/java/solitour_backend/solitour/gathering/dto/response/GatheringDetailResponse.java +++ b/src/main/java/solitour_backend/solitour/gathering/dto/response/GatheringDetailResponse.java @@ -1,5 +1,7 @@ package solitour_backend.solitour.gathering.dto.response; +import java.time.LocalDateTime; +import java.util.List; import lombok.AllArgsConstructor; import lombok.Getter; import solitour_backend.solitour.gathering.entity.AllowedSex; @@ -9,9 +11,6 @@ import solitour_backend.solitour.user.dto.UserPostingResponse; import solitour_backend.solitour.zone_category.dto.response.ZoneCategoryResponse; -import java.time.LocalDateTime; -import java.util.List; - @Getter @AllArgsConstructor public class GatheringDetailResponse { diff --git a/src/main/java/solitour_backend/solitour/gathering/entity/AllowedSex.java b/src/main/java/solitour_backend/solitour/gathering/entity/AllowedSex.java index 73252417..0dee7cc6 100644 --- a/src/main/java/solitour_backend/solitour/gathering/entity/AllowedSex.java +++ b/src/main/java/solitour_backend/solitour/gathering/entity/AllowedSex.java @@ -1,8 +1,7 @@ package solitour_backend.solitour.gathering.entity; -import lombok.Getter; - import java.util.Arrays; +import lombok.Getter; @Getter public enum AllowedSex { diff --git a/src/main/java/solitour_backend/solitour/gathering/entity/Gathering.java b/src/main/java/solitour_backend/solitour/gathering/entity/Gathering.java index 5784ccd1..384302c7 100644 --- a/src/main/java/solitour_backend/solitour/gathering/entity/Gathering.java +++ b/src/main/java/solitour_backend/solitour/gathering/entity/Gathering.java @@ -1,9 +1,17 @@ package solitour_backend.solitour.gathering.entity; -import jakarta.persistence.*; - +import jakarta.persistence.Column; +import jakarta.persistence.Convert; +import jakarta.persistence.Entity; +import jakarta.persistence.EntityListeners; +import jakarta.persistence.FetchType; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.ManyToOne; +import jakarta.persistence.Table; import java.time.LocalDateTime; - import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; @@ -86,7 +94,10 @@ public class Gathering { @Column(name = "gathering_end_age") private Integer endAge; - public Gathering(User user, ZoneCategory zoneCategory, GatheringCategory gatheringCategory, Place place, String title, String content, Integer personCount, Integer viewCount, LocalDateTime scheduleStartDate, LocalDateTime scheduleEndDate, Boolean isFinish, LocalDateTime deadline, AllowedSex allowedSex, Integer startAge, Integer endAge) { + public Gathering(User user, ZoneCategory zoneCategory, GatheringCategory gatheringCategory, Place place, + String title, String content, Integer personCount, Integer viewCount, + LocalDateTime scheduleStartDate, LocalDateTime scheduleEndDate, Boolean isFinish, + LocalDateTime deadline, AllowedSex allowedSex, Integer startAge, Integer endAge) { this.user = user; this.zoneCategory = zoneCategory; this.gatheringCategory = gatheringCategory; diff --git a/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryCustom.java b/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryCustom.java index def6f2d9..2f66d69c 100644 --- a/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryCustom.java +++ b/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryCustom.java @@ -1,10 +1,9 @@ package solitour_backend.solitour.gathering.repository; +import java.util.List; import org.springframework.data.repository.NoRepositoryBean; import solitour_backend.solitour.gathering.dto.response.GatheringBriefResponse; -import java.util.List; - @NoRepositoryBean public interface GatheringRepositoryCustom { List getGatheringRecommend(Long informationId, Long gatheringCategoryId, Long userId); diff --git a/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryImpl.java b/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryImpl.java index 4336dfd1..aa0d74a8 100644 --- a/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryImpl.java +++ b/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryImpl.java @@ -1,6 +1,7 @@ package solitour_backend.solitour.gathering.repository; import com.querydsl.core.types.Projections; +import java.util.List; import org.springframework.data.jpa.repository.support.QuerydslRepositorySupport; import solitour_backend.solitour.book_mark_gathering.entity.QBookMarkGathering; import solitour_backend.solitour.gathering.dto.response.GatheringBriefResponse; @@ -12,8 +13,6 @@ import solitour_backend.solitour.great_gathering.entity.QGreatGathering; import solitour_backend.solitour.zone_category.entity.QZoneCategory; -import java.util.List; - public class GatheringRepositoryImpl extends QuerydslRepositorySupport implements GatheringRepositoryCustom { public GatheringRepositoryImpl() { super(Gathering.class); @@ -33,14 +32,16 @@ public List getGatheringRecommend(Long gatheringId, Long return from(gathering) .join(zoneCategoryChild).on(zoneCategoryChild.id.eq(gathering.zoneCategory.id)) .leftJoin(zoneCategoryParent).on(zoneCategoryParent.id.eq(zoneCategoryChild.parentZoneCategory.id)) - .leftJoin(bookMarkGathering).on(bookMarkGathering.gathering.id.eq(gathering.id).and(bookMarkGathering.user.id.eq(userId))) + .leftJoin(bookMarkGathering) + .on(bookMarkGathering.gathering.id.eq(gathering.id).and(bookMarkGathering.user.id.eq(userId))) .leftJoin(greatGathering).on(greatGathering.gathering.id.eq(gathering.id)) .leftJoin(category).on(category.id.eq(gathering.gatheringCategory.id)) .leftJoin(gatheringApplicants).on(gatheringApplicants.gathering.id.eq(gathering.id)) .where(gathering.isFinish.eq(Boolean.FALSE) .and(gathering.gatheringCategory.id.eq(gatheringCategoryId)) .and(gathering.id.ne(gatheringId)) - .and(gatheringApplicants.gatheringStatus.eq(GatheringStatus.CONSENT).or(gatheringApplicants.gatheringStatus.isNull())) + .and(gatheringApplicants.gatheringStatus.eq(GatheringStatus.CONSENT) + .or(gatheringApplicants.gatheringStatus.isNull())) ) .groupBy(gathering.id, zoneCategoryChild.id, zoneCategoryParent.id, category.id) .orderBy(gathering.createdAt.desc()) diff --git a/src/main/java/solitour_backend/solitour/gathering/service/GatheringService.java b/src/main/java/solitour_backend/solitour/gathering/service/GatheringService.java index 5e203648..1ca3ede8 100644 --- a/src/main/java/solitour_backend/solitour/gathering/service/GatheringService.java +++ b/src/main/java/solitour_backend/solitour/gathering/service/GatheringService.java @@ -1,5 +1,8 @@ package solitour_backend.solitour.gathering.service; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -44,10 +47,6 @@ import solitour_backend.solitour.zone_category.exception.ZoneCategoryNotExistsException; import solitour_backend.solitour.zone_category.repository.ZoneCategoryRepository; -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; - @Service @Transactional(readOnly = true) @RequiredArgsConstructor @@ -87,15 +86,19 @@ public GatheringDetailResponse getGatheringDetail(Long userId, Long gatheringId) PlaceResponse placeResponse = placeMapper.mapToPlaceResponse(gathering.getPlace()); - ZoneCategoryResponse zoneCategoryResponse = zoneCategoryMapper.mapToZoneCategoryResponse(gathering.getZoneCategory()); + ZoneCategoryResponse zoneCategoryResponse = zoneCategoryMapper.mapToZoneCategoryResponse( + gathering.getZoneCategory()); int likeCount = greatGatheringRepository.countByGatheringId(gathering.getId()); - List gatheringApplicantsResponses = gatheringApplicantsMapper.mapToGatheringApplicantsResponses(gatheringApplicantsRepository.findAllByGathering_Id(gathering.getId())); + List gatheringApplicantsResponses = gatheringApplicantsMapper.mapToGatheringApplicantsResponses( + gatheringApplicantsRepository.findAllByGathering_Id(gathering.getId())); - int nowPersonCount = gatheringApplicantsRepository.countAllByGathering_IdAndGatheringStatus(gathering.getId(), GatheringStatus.CONSENT); + int nowPersonCount = gatheringApplicantsRepository.countAllByGathering_IdAndGatheringStatus(gathering.getId(), + GatheringStatus.CONSENT); - List gatheringRecommend = gatheringRepository.getGatheringRecommend(gathering.getId(), gathering.getGatheringCategory().getId(), userId); + List gatheringRecommend = gatheringRepository.getGatheringRecommend(gathering.getId(), + gathering.getGatheringCategory().getId(), userId); return new GatheringDetailResponse( gathering.getTitle(), @@ -182,7 +185,8 @@ public GatheringResponse registerGathering(Long userId, GatheringRegisterRequest } @Transactional - public GatheringResponse modifyGathering(Long userId, Long gatheringId, GatheringModifyRequest gatheringModifyRequest) { + public GatheringResponse modifyGathering(Long userId, Long gatheringId, + GatheringModifyRequest gatheringModifyRequest) { User user = userRepository.findById(userId) .orElseThrow( () -> new UserNotExistsException("해당하는 id의 User 가 없습니다")); @@ -195,10 +199,12 @@ public GatheringResponse modifyGathering(Long userId, Long gatheringId, Gatherin throw new GatheringNotManagerException("해당 유저는 권한이 없습니다"); } - GatheringCategory gatheringCategory = gatheringCategoryRepository.findById(gatheringModifyRequest.getGatheringCategoryId()).orElseThrow(); - ZoneCategory parentZoneCategory = zoneCategoryRepository.findByParentZoneCategoryIdAndName(null, gatheringModifyRequest.getZoneCategoryNameParent()).orElseThrow(); - ZoneCategory childZoneCategory = zoneCategoryRepository.findByParentZoneCategoryIdAndName(parentZoneCategory.getId(), gatheringModifyRequest.getZoneCategoryNameChild()).orElseThrow(); - + GatheringCategory gatheringCategory = gatheringCategoryRepository.findById( + gatheringModifyRequest.getGatheringCategoryId()).orElseThrow(); + ZoneCategory parentZoneCategory = zoneCategoryRepository.findByParentZoneCategoryIdAndName(null, + gatheringModifyRequest.getZoneCategoryNameParent()).orElseThrow(); + ZoneCategory childZoneCategory = zoneCategoryRepository.findByParentZoneCategoryIdAndName( + parentZoneCategory.getId(), gatheringModifyRequest.getZoneCategoryNameChild()).orElseThrow(); Place place = gathering.getPlace(); PlaceModifyRequest placeModifyRequest = gatheringModifyRequest.getPlaceModifyRequest(); @@ -229,7 +235,8 @@ public GatheringResponse modifyGathering(Long userId, Long gatheringId, Gatherin tagRepository.deleteById(gatheringTag.getTag().getTagId()); } - List saveTags = tagRepository.saveAll(tagMapper.mapToTags(gatheringModifyRequest.getTagRegisterRequests())); + List saveTags = tagRepository.saveAll( + tagMapper.mapToTags(gatheringModifyRequest.getTagRegisterRequests())); for (Tag tag : saveTags) { gatheringTagRepository.save(new GatheringTag(tag, gathering)); diff --git a/src/main/java/solitour_backend/solitour/gathering_applicants/controller/GatheringApplicantsController.java b/src/main/java/solitour_backend/solitour/gathering_applicants/controller/GatheringApplicantsController.java index 32ee93c2..2b73d214 100644 --- a/src/main/java/solitour_backend/solitour/gathering_applicants/controller/GatheringApplicantsController.java +++ b/src/main/java/solitour_backend/solitour/gathering_applicants/controller/GatheringApplicantsController.java @@ -4,7 +4,13 @@ import lombok.RequiredArgsConstructor; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.*; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; import solitour_backend.solitour.auth.config.AuthenticationPrincipal; import solitour_backend.solitour.gathering_applicants.dto.request.GatheringApplicantsModifyRequest; import solitour_backend.solitour.gathering_applicants.service.GatheringApplicantsService; @@ -16,7 +22,8 @@ public class GatheringApplicantsController { private final GatheringApplicantsService gatheringApplicantsService; @PostMapping("/{gatheringId}") - public ResponseEntity participateGathering(@AuthenticationPrincipal Long userId, @PathVariable Long gatheringId) { + public ResponseEntity participateGathering(@AuthenticationPrincipal Long userId, + @PathVariable Long gatheringId) { gatheringApplicantsService.participateGatheringFromAnotherUser(userId, gatheringId); return ResponseEntity @@ -25,7 +32,8 @@ public ResponseEntity participateGathering(@AuthenticationPrincipal Long u } @DeleteMapping("/{gatheringId}") - public ResponseEntity deleteParticipateGathering(@AuthenticationPrincipal Long userId, @PathVariable Long gatheringId) { + public ResponseEntity deleteParticipateGathering(@AuthenticationPrincipal Long userId, + @PathVariable Long gatheringId) { gatheringApplicantsService.deleteGatheringApplicantsFromAnotherUser(userId, gatheringId); return ResponseEntity @@ -38,7 +46,8 @@ public ResponseEntity updateParticipateGatheringStatus(@AuthenticationPrin @PathVariable Long gatheringId, @Valid @RequestBody GatheringApplicantsModifyRequest gatheringApplicantsModifyRequest) { - boolean result = gatheringApplicantsService.updateGatheringApplicantsManagement(userId, gatheringId, gatheringApplicantsModifyRequest); + boolean result = gatheringApplicantsService.updateGatheringApplicantsManagement(userId, gatheringId, + gatheringApplicantsModifyRequest); if (result) { return ResponseEntity diff --git a/src/main/java/solitour_backend/solitour/gathering_applicants/dto/mapper/GatheringApplicantsMapper.java b/src/main/java/solitour_backend/solitour/gathering_applicants/dto/mapper/GatheringApplicantsMapper.java index f02f72ae..c34a9234 100644 --- a/src/main/java/solitour_backend/solitour/gathering_applicants/dto/mapper/GatheringApplicantsMapper.java +++ b/src/main/java/solitour_backend/solitour/gathering_applicants/dto/mapper/GatheringApplicantsMapper.java @@ -1,5 +1,6 @@ package solitour_backend.solitour.gathering_applicants.dto.mapper; +import java.util.List; import org.mapstruct.Mapper; import org.mapstruct.Mapping; import org.mapstruct.ReportingPolicy; @@ -7,8 +8,6 @@ import solitour_backend.solitour.gathering_applicants.entity.GatheringApplicants; import solitour_backend.solitour.user.dto.mapper.UserMapper; -import java.util.List; - @Mapper(componentModel = "spring", unmappedTargetPolicy = ReportingPolicy.ERROR, uses = UserMapper.class) public interface GatheringApplicantsMapper { diff --git a/src/main/java/solitour_backend/solitour/gathering_applicants/entity/GatheringApplicants.java b/src/main/java/solitour_backend/solitour/gathering_applicants/entity/GatheringApplicants.java index c8d300f5..b2dddc2f 100644 --- a/src/main/java/solitour_backend/solitour/gathering_applicants/entity/GatheringApplicants.java +++ b/src/main/java/solitour_backend/solitour/gathering_applicants/entity/GatheringApplicants.java @@ -1,6 +1,15 @@ package solitour_backend.solitour.gathering_applicants.entity; -import jakarta.persistence.*; +import jakarta.persistence.Column; +import jakarta.persistence.Convert; +import jakarta.persistence.Entity; +import jakarta.persistence.FetchType; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.ManyToOne; +import jakarta.persistence.Table; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; diff --git a/src/main/java/solitour_backend/solitour/gathering_applicants/entity/GatheringStatus.java b/src/main/java/solitour_backend/solitour/gathering_applicants/entity/GatheringStatus.java index 403b4c36..288f6aec 100644 --- a/src/main/java/solitour_backend/solitour/gathering_applicants/entity/GatheringStatus.java +++ b/src/main/java/solitour_backend/solitour/gathering_applicants/entity/GatheringStatus.java @@ -1,8 +1,7 @@ package solitour_backend.solitour.gathering_applicants.entity; -import lombok.Getter; - import java.util.Arrays; +import lombok.Getter; @Getter public enum GatheringStatus { diff --git a/src/main/java/solitour_backend/solitour/gathering_applicants/repository/GatheringApplicantsRepository.java b/src/main/java/solitour_backend/solitour/gathering_applicants/repository/GatheringApplicantsRepository.java index 1432d310..d3399046 100644 --- a/src/main/java/solitour_backend/solitour/gathering_applicants/repository/GatheringApplicantsRepository.java +++ b/src/main/java/solitour_backend/solitour/gathering_applicants/repository/GatheringApplicantsRepository.java @@ -1,12 +1,11 @@ package solitour_backend.solitour.gathering_applicants.repository; +import java.util.List; +import java.util.Optional; import org.springframework.data.jpa.repository.JpaRepository; import solitour_backend.solitour.gathering_applicants.entity.GatheringApplicants; import solitour_backend.solitour.gathering_applicants.entity.GatheringStatus; -import java.util.List; -import java.util.Optional; - public interface GatheringApplicantsRepository extends JpaRepository { List findAllByGathering_Id(Long id); diff --git a/src/main/java/solitour_backend/solitour/gathering_applicants/service/GatheringApplicantsService.java b/src/main/java/solitour_backend/solitour/gathering_applicants/service/GatheringApplicantsService.java index 5e214c6e..18de534a 100644 --- a/src/main/java/solitour_backend/solitour/gathering_applicants/service/GatheringApplicantsService.java +++ b/src/main/java/solitour_backend/solitour/gathering_applicants/service/GatheringApplicantsService.java @@ -1,5 +1,6 @@ package solitour_backend.solitour.gathering_applicants.service; +import java.util.Objects; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -18,8 +19,6 @@ import solitour_backend.solitour.user.entity.UserRepository; import solitour_backend.solitour.user.exception.UserNotExistsException; -import java.util.Objects; - @Service @Transactional @RequiredArgsConstructor @@ -44,7 +43,8 @@ public void participateGatheringFromAnotherUser(Long userId, Long gatheringId) { } Integer personCount = gathering.getPersonCount(); - int nowPersonCount = gatheringApplicantsRepository.countAllByGathering_IdAndGatheringStatus(gatheringId, GatheringStatus.CONSENT); + int nowPersonCount = gatheringApplicantsRepository.countAllByGathering_IdAndGatheringStatus(gatheringId, + GatheringStatus.CONSENT); if (personCount <= nowPersonCount) { throw new GatheringApplicantsAlreadyFullPeopleException("이미 인원이 가득 찼습니다."); @@ -66,15 +66,18 @@ public void deleteGatheringApplicantsFromAnotherUser(Long userId, Long gathering () -> new UserNotExistsException("해당하는 id의 user가 없습니다")); - GatheringApplicants gatheringApplicants = gatheringApplicantsRepository.findByGatheringIdAndUserId(gathering.getId(), user.getId()) + GatheringApplicants gatheringApplicants = gatheringApplicantsRepository.findByGatheringIdAndUserId( + gathering.getId(), user.getId()) .orElseThrow( () -> - new GatheringApplicantsNotExistsException("해당하는 모임과 user의 gathering applicants가 없습니다.")); + new GatheringApplicantsNotExistsException( + "해당하는 모임과 user의 gathering applicants가 없습니다.")); gatheringApplicantsRepository.delete(gatheringApplicants); } - public boolean updateGatheringApplicantsManagement(Long userId, Long gatheringId, GatheringApplicantsModifyRequest gatheringApplicantsModifyRequest) { + public boolean updateGatheringApplicantsManagement(Long userId, Long gatheringId, + GatheringApplicantsModifyRequest gatheringApplicantsModifyRequest) { Gathering gathering = gatheringRepository.findById(gatheringId) .orElseThrow( () -> @@ -89,13 +92,15 @@ public boolean updateGatheringApplicantsManagement(Long userId, Long gatheringId throw new GatheringNotManagerException("해당하는 user 가 해당 gathering 의 manage 가 아닙니다"); } - GatheringApplicants gatheringApplicants = gatheringApplicantsRepository.findByGatheringIdAndUserId(gathering.getId(), gatheringApplicantsModifyRequest.getUserId()) + GatheringApplicants gatheringApplicants = gatheringApplicantsRepository.findByGatheringIdAndUserId( + gathering.getId(), gatheringApplicantsModifyRequest.getUserId()) .orElseThrow( () -> new GatheringApplicantsNotExistsException("해당하는 모임, user 의 applicants 가 없습니다") ); - if (Objects.equals(gatheringApplicants.getGatheringStatus(), gatheringApplicantsModifyRequest.getGatheringStatus())) { + if (Objects.equals(gatheringApplicants.getGatheringStatus(), + gatheringApplicantsModifyRequest.getGatheringStatus())) { return false; } diff --git a/src/main/java/solitour_backend/solitour/gathering_tag/repository/GatheringTagRepository.java b/src/main/java/solitour_backend/solitour/gathering_tag/repository/GatheringTagRepository.java index f1982424..ed2aa051 100644 --- a/src/main/java/solitour_backend/solitour/gathering_tag/repository/GatheringTagRepository.java +++ b/src/main/java/solitour_backend/solitour/gathering_tag/repository/GatheringTagRepository.java @@ -1,10 +1,9 @@ package solitour_backend.solitour.gathering_tag.repository; +import java.util.List; import org.springframework.data.jpa.repository.JpaRepository; import solitour_backend.solitour.gathering_tag.entity.GatheringTag; -import java.util.List; - public interface GatheringTagRepository extends JpaRepository { List findAllByGathering_Id(Long gatheringId); diff --git a/src/main/java/solitour_backend/solitour/user/controller/UserController.java b/src/main/java/solitour_backend/solitour/user/controller/UserController.java index f08faf7b..4ad5cea9 100644 --- a/src/main/java/solitour_backend/solitour/user/controller/UserController.java +++ b/src/main/java/solitour_backend/solitour/user/controller/UserController.java @@ -79,7 +79,7 @@ public ResponseEntity deleteUser(@AuthenticationPrincipal Long id, @Requ String token = getOauthAccessToken(type, code, redirectUrl); try { - oauthservice.revokeToken(type,token); + oauthservice.revokeToken(type, token); oauthservice.logout(id); userService.deleteUser(id); From 160c98e97cab895ca9d699301363bef6521e495f Mon Sep 17 00:00:00 2001 From: Donghun Won Date: Sat, 10 Aug 2024 19:19:00 +0900 Subject: [PATCH 098/371] =?UTF-8?q?Feat(62)=20:=20=EC=B9=B4=EC=B9=B4?= =?UTF-8?q?=EC=98=A4=20=EB=A1=9C=EA=B7=B8=EC=9D=B8=20=ED=83=88=ED=87=B4=20?= =?UTF-8?q?(#74)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Feat : 회원탈퇴 * Style : 코드 포맷팅 * Feat : 카카오 회원탈퇴 * Refactor : 카카오 회원탈퇴 로직 수정 * Style : 코드 포맷팅 --- .../admin/controller/AdminController.java | 3 +- .../admin/controller/BannerController.java | 8 +- .../GatheringCategoryController.java | 43 ++++---- .../admin/dto/UserListResponseDTO.java | 9 +- .../solitour/admin/dto/UserListWithPage.java | 7 +- .../dto/mapper/GatheringCategoryMapper.java | 5 +- .../solitour/admin/entity/Banner.java | 7 +- .../admin/repository/BannerRepository.java | 3 +- .../solitour/admin/service/AdminService.java | 3 +- .../solitour/admin/service/BannerService.java | 11 +- .../service/GatheringCategoryService.java | 29 +++-- .../auth/config/AuthConfiguration.java | 3 +- .../solitour/auth/config/AuthInterceptor.java | 2 - .../solitour/auth/config/TokenResolver.java | 3 +- .../auth/controller/OauthController.java | 10 +- .../solitour/auth/entity/TokenRepository.java | 1 - .../solitour/auth/service/OauthService.java | 25 ++++- .../auth/support/JwtTokenProvider.java | 2 - .../auth/support/google/GoogleConnector.java | 32 +++++- .../auth/support/google/GoogleProvider.java | 4 +- .../google/dto/GoogleUserResponse.java | 2 - .../auth/support/kakao/KakaoConnector.java | 21 +++- .../auth/support/kakao/KakaoProvider.java | 4 +- .../support/kakao/dto/KakaoUserResponse.java | 2 - .../entity/BookMarkInformationRepository.java | 1 - .../service/BookMarkInformationService.java | 2 - .../controller/CategoryController.java | 14 +-- .../category/dto/mapper/CategoryMapper.java | 1 - .../dto/response/CategoryGetResponse.java | 1 - .../repository/CategoryRepository.java | 1 - .../category/service/CategoryService.java | 1 - .../RequestValidationFailedException.java | 2 - .../controller/GatheringController.java | 17 ++- .../dto/request/GatheringModifyRequest.java | 11 +- .../dto/request/GatheringRegisterRequest.java | 11 +- .../dto/response/GatheringBriefResponse.java | 3 +- .../dto/response/GatheringDetailResponse.java | 5 +- .../solitour/gathering/entity/AllowedSex.java | 3 +- .../solitour/gathering/entity/Gathering.java | 19 +++- .../repository/GatheringRepositoryCustom.java | 3 +- .../repository/GatheringRepositoryImpl.java | 9 +- .../gathering/service/GatheringService.java | 35 +++--- .../GatheringApplicantsController.java | 17 ++- .../dto/mapper/GatheringApplicantsMapper.java | 3 +- .../entity/GatheringApplicants.java | 11 +- .../entity/GatheringStatus.java | 3 +- .../GatheringApplicantsRepository.java | 5 +- .../service/GatheringApplicantsService.java | 21 ++-- .../entity/GatheringCategory.java | 10 +- .../GatheringCategoryRepository.java | 3 +- .../repository/GatheringTagRepository.java | 3 +- .../GreatInformationRepository.java | 1 - .../image/dto/mapper/ImageMapper.java | 1 - .../solitour/image/entity/Image.java | 2 - .../image/image_status/ImageStatus.java | 1 - .../image/repository/ImageRepository.java | 1 - .../solitour/image/s3/S3Uploader.java | 2 - .../repository/InfoTagRepository.java | 1 - .../controller/InformationController.java | 104 +++++++++++------- .../dto/request/InformationModifyRequest.java | 3 +- .../request/InformationRegisterRequest.java | 2 - .../response/InformationDetailResponse.java | 1 - .../information/entity/Information.java | 14 ++- .../InformationRepositoryCustom.java | 41 ++++--- .../repository/InformationRepositoryImpl.java | 73 ++++++++---- .../service/InformationService.java | 72 ++++++++---- .../place/dto/request/PlaceModifyRequest.java | 2 - .../dto/request/PlaceRegisterRequest.java | 2 - .../place/dto/response/PlaceResponse.java | 1 - .../solitour/place/entity/Place.java | 2 - .../solitour/tag/dto/mapper/TagMapper.java | 1 - .../user/controller/UserController.java | 85 +++++++++++++- .../solitour/user/dto/UpdateAgeAndSex.java | 4 + .../user/dto/UpdateNicknameRequest.java | 4 + .../solitour/user/entity/User.java | 16 ++- .../solitour/user/entity/UserRepository.java | 7 +- .../NicknameAlreadyExistsException.java | 7 ++ .../solitour/user/service/UserService.java | 22 ++++ .../solitour/user/user_status/UserStatus.java | 1 - .../solitour/user_image/entity/UserImage.java | 2 - .../user_image/service/UserImageService.java | 1 - .../solitour/util/TimeUtil.java | 3 +- .../controller/ZoneCategoryController.java | 5 +- .../repository/ZoneCategoryRepository.java | 1 - .../service/ZoneCategoryService.java | 1 - 85 files changed, 627 insertions(+), 313 deletions(-) create mode 100644 src/main/java/solitour_backend/solitour/user/dto/UpdateAgeAndSex.java create mode 100644 src/main/java/solitour_backend/solitour/user/dto/UpdateNicknameRequest.java create mode 100644 src/main/java/solitour_backend/solitour/user/exception/NicknameAlreadyExistsException.java diff --git a/src/main/java/solitour_backend/solitour/admin/controller/AdminController.java b/src/main/java/solitour_backend/solitour/admin/controller/AdminController.java index 7890b0ef..5e43e2bf 100644 --- a/src/main/java/solitour_backend/solitour/admin/controller/AdminController.java +++ b/src/main/java/solitour_backend/solitour/admin/controller/AdminController.java @@ -17,7 +17,8 @@ public class AdminController { private final AdminService adminService; @GetMapping("/user/list") - public ResponseEntity getUserInfoList(@RequestParam(defaultValue = "1") int page, @RequestParam(defaultValue = "") String nickname) { + public ResponseEntity getUserInfoList(@RequestParam(defaultValue = "1") int page, + @RequestParam(defaultValue = "") String nickname) { UserListWithPage response = adminService.getUserInfoList(nickname, page); return ResponseEntity.ok(response); } diff --git a/src/main/java/solitour_backend/solitour/admin/controller/BannerController.java b/src/main/java/solitour_backend/solitour/admin/controller/BannerController.java index 339a8b5f..2aa5e245 100644 --- a/src/main/java/solitour_backend/solitour/admin/controller/BannerController.java +++ b/src/main/java/solitour_backend/solitour/admin/controller/BannerController.java @@ -3,7 +3,11 @@ import lombok.RequiredArgsConstructor; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.*; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RequestPart; +import org.springframework.web.bind.annotation.RestController; import org.springframework.web.multipart.MultipartFile; import solitour_backend.solitour.admin.entity.Banner; import solitour_backend.solitour.admin.service.BannerService; @@ -17,7 +21,7 @@ public class BannerController { @RequestMapping(method = RequestMethod.POST) public ResponseEntity createBanner(@RequestPart("imageFile") MultipartFile imageFile, @RequestPart("directory") String directory) { - Banner banner = bannerService.createBanner(imageFile,directory); + Banner banner = bannerService.createBanner(imageFile, directory); return ResponseEntity .status(HttpStatus.OK) .body(banner); diff --git a/src/main/java/solitour_backend/solitour/admin/controller/GatheringCategoryController.java b/src/main/java/solitour_backend/solitour/admin/controller/GatheringCategoryController.java index d687ad4d..9a2e822c 100644 --- a/src/main/java/solitour_backend/solitour/admin/controller/GatheringCategoryController.java +++ b/src/main/java/solitour_backend/solitour/admin/controller/GatheringCategoryController.java @@ -1,11 +1,18 @@ package solitour_backend.solitour.admin.controller; import jakarta.validation.Valid; +import java.util.List; import lombok.RequiredArgsConstructor; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.validation.BindingResult; -import org.springframework.web.bind.annotation.*; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; import solitour_backend.solitour.admin.service.GatheringCategoryService; import solitour_backend.solitour.category.dto.request.CategoryModifyRequest; import solitour_backend.solitour.category.dto.request.CategoryRegisterRequest; @@ -13,22 +20,20 @@ import solitour_backend.solitour.category.dto.response.CategoryResponse; import solitour_backend.solitour.error.exception.RequestValidationFailedException; -import java.util.List; - @RestController @RequiredArgsConstructor @RequestMapping("/api/categories/gathering") public class GatheringCategoryController { private final GatheringCategoryService gatheringCategoryService; - + @GetMapping public ResponseEntity> getAllCategories() { List parentCategories = gatheringCategoryService.getParentCategories(); return ResponseEntity - .status(HttpStatus.OK) - .body(parentCategories); + .status(HttpStatus.OK) + .body(parentCategories); } @GetMapping("/{id}") @@ -36,39 +41,39 @@ public ResponseEntity getCategory(@PathVariable Long id) { CategoryResponse category = gatheringCategoryService.getCategory(id); return ResponseEntity - .status(HttpStatus.OK) - .body(category); + .status(HttpStatus.OK) + .body(category); } @PostMapping public ResponseEntity registerCategory( - @Valid @RequestBody CategoryRegisterRequest categoryRegisterRequest, - BindingResult bindingResult) { + @Valid @RequestBody CategoryRegisterRequest categoryRegisterRequest, + BindingResult bindingResult) { if (bindingResult.hasErrors()) { throw new RequestValidationFailedException(bindingResult); } CategoryResponse categoryResponse = gatheringCategoryService.registerCategory( - categoryRegisterRequest); + categoryRegisterRequest); return ResponseEntity - .status(HttpStatus.CREATED) - .body(categoryResponse); + .status(HttpStatus.CREATED) + .body(categoryResponse); } @PutMapping("/{id}") public ResponseEntity modifyCategory( - @Valid @RequestBody CategoryModifyRequest categoryModifyRequest, - BindingResult bindingResult, - @PathVariable Long id) { + @Valid @RequestBody CategoryModifyRequest categoryModifyRequest, + BindingResult bindingResult, + @PathVariable Long id) { if (bindingResult.hasErrors()) { throw new RequestValidationFailedException(bindingResult); } CategoryResponse categoryResponse = gatheringCategoryService.modifyCategory(id, - categoryModifyRequest); + categoryModifyRequest); return ResponseEntity - .status(HttpStatus.CREATED) - .body(categoryResponse); + .status(HttpStatus.CREATED) + .body(categoryResponse); } diff --git a/src/main/java/solitour_backend/solitour/admin/dto/UserListResponseDTO.java b/src/main/java/solitour_backend/solitour/admin/dto/UserListResponseDTO.java index 21d689fa..ec325fdd 100644 --- a/src/main/java/solitour_backend/solitour/admin/dto/UserListResponseDTO.java +++ b/src/main/java/solitour_backend/solitour/admin/dto/UserListResponseDTO.java @@ -1,9 +1,12 @@ package solitour_backend.solitour.admin.dto; -import lombok.*; -import solitour_backend.solitour.user.user_status.UserStatus; - import java.time.LocalDateTime; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import solitour_backend.solitour.user.user_status.UserStatus; @Getter diff --git a/src/main/java/solitour_backend/solitour/admin/dto/UserListWithPage.java b/src/main/java/solitour_backend/solitour/admin/dto/UserListWithPage.java index 1ba166ad..b62e6c67 100644 --- a/src/main/java/solitour_backend/solitour/admin/dto/UserListWithPage.java +++ b/src/main/java/solitour_backend/solitour/admin/dto/UserListWithPage.java @@ -1,8 +1,11 @@ package solitour_backend.solitour.admin.dto; -import lombok.*; - import java.util.List; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; @Getter @NoArgsConstructor diff --git a/src/main/java/solitour_backend/solitour/admin/dto/mapper/GatheringCategoryMapper.java b/src/main/java/solitour_backend/solitour/admin/dto/mapper/GatheringCategoryMapper.java index 65df0793..07838841 100644 --- a/src/main/java/solitour_backend/solitour/admin/dto/mapper/GatheringCategoryMapper.java +++ b/src/main/java/solitour_backend/solitour/admin/dto/mapper/GatheringCategoryMapper.java @@ -1,11 +1,10 @@ package solitour_backend.solitour.admin.dto.mapper; +import java.util.List; import org.mapstruct.Mapper; import org.mapstruct.ReportingPolicy; -import solitour_backend.solitour.gathering_category.entity.GatheringCategory; import solitour_backend.solitour.category.dto.response.CategoryResponse; - -import java.util.List; +import solitour_backend.solitour.gathering_category.entity.GatheringCategory; @Mapper(componentModel = "spring", unmappedTargetPolicy = ReportingPolicy.ERROR) public interface GatheringCategoryMapper { diff --git a/src/main/java/solitour_backend/solitour/admin/entity/Banner.java b/src/main/java/solitour_backend/solitour/admin/entity/Banner.java index 46ddd687..62fed976 100644 --- a/src/main/java/solitour_backend/solitour/admin/entity/Banner.java +++ b/src/main/java/solitour_backend/solitour/admin/entity/Banner.java @@ -1,6 +1,11 @@ package solitour_backend.solitour.admin.entity; -import jakarta.persistence.*; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.Table; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Getter; diff --git a/src/main/java/solitour_backend/solitour/admin/repository/BannerRepository.java b/src/main/java/solitour_backend/solitour/admin/repository/BannerRepository.java index 979b1c22..acc57843 100644 --- a/src/main/java/solitour_backend/solitour/admin/repository/BannerRepository.java +++ b/src/main/java/solitour_backend/solitour/admin/repository/BannerRepository.java @@ -1,10 +1,9 @@ package solitour_backend.solitour.admin.repository; +import java.util.List; import org.springframework.data.jpa.repository.JpaRepository; import solitour_backend.solitour.admin.entity.Banner; -import java.util.List; - public interface BannerRepository extends JpaRepository { diff --git a/src/main/java/solitour_backend/solitour/admin/service/AdminService.java b/src/main/java/solitour_backend/solitour/admin/service/AdminService.java index bf0821ab..6c0f2bd0 100644 --- a/src/main/java/solitour_backend/solitour/admin/service/AdminService.java +++ b/src/main/java/solitour_backend/solitour/admin/service/AdminService.java @@ -1,5 +1,6 @@ package solitour_backend.solitour.admin.service; +import java.util.List; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.data.domain.Page; @@ -12,8 +13,6 @@ import solitour_backend.solitour.admin.repository.AdminRepository; import solitour_backend.solitour.user.entity.User; -import java.util.List; - @Service @Slf4j @RequiredArgsConstructor diff --git a/src/main/java/solitour_backend/solitour/admin/service/BannerService.java b/src/main/java/solitour_backend/solitour/admin/service/BannerService.java index 6096dafc..b9c77dad 100644 --- a/src/main/java/solitour_backend/solitour/admin/service/BannerService.java +++ b/src/main/java/solitour_backend/solitour/admin/service/BannerService.java @@ -3,6 +3,10 @@ import com.amazonaws.services.s3.AmazonS3Client; import com.amazonaws.services.s3.model.ObjectMetadata; import com.amazonaws.services.s3.model.PutObjectRequest; +import java.io.IOException; +import java.util.Date; +import java.util.List; +import java.util.UUID; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; @@ -16,11 +20,6 @@ import solitour_backend.solitour.admin.repository.BannerRepository; import solitour_backend.solitour.util.TimeUtil; -import java.io.IOException; -import java.util.Date; -import java.util.List; -import java.util.UUID; - @Service @Slf4j @RequiredArgsConstructor @@ -36,7 +35,7 @@ public class BannerService { public ResponseEntity getBannerList() { List banners = bannerRepository.findAllByOrderById(); HttpHeaders headers = new HttpHeaders(); - headers.setCacheControl("max-age="+timeUtil.getSecondsUntilMidnightInKST()); + headers.setCacheControl("max-age=" + timeUtil.getSecondsUntilMidnightInKST()); return new ResponseEntity<>(banners, HttpStatus.OK); } diff --git a/src/main/java/solitour_backend/solitour/admin/service/GatheringCategoryService.java b/src/main/java/solitour_backend/solitour/admin/service/GatheringCategoryService.java index 2023a12a..58b50f9c 100644 --- a/src/main/java/solitour_backend/solitour/admin/service/GatheringCategoryService.java +++ b/src/main/java/solitour_backend/solitour/admin/service/GatheringCategoryService.java @@ -1,20 +1,19 @@ package solitour_backend.solitour.admin.service; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import solitour_backend.solitour.admin.dto.mapper.GatheringCategoryMapper; -import solitour_backend.solitour.gathering_category.entity.GatheringCategory; -import solitour_backend.solitour.gathering_category.repository.GatheringCategoryRepository; import solitour_backend.solitour.category.dto.request.CategoryModifyRequest; import solitour_backend.solitour.category.dto.request.CategoryRegisterRequest; import solitour_backend.solitour.category.dto.response.CategoryGetResponse; import solitour_backend.solitour.category.dto.response.CategoryResponse; import solitour_backend.solitour.category.exception.CategoryNotExistsException; - -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; +import solitour_backend.solitour.gathering_category.entity.GatheringCategory; +import solitour_backend.solitour.gathering_category.repository.GatheringCategoryRepository; @Service @Transactional(readOnly = true) @@ -31,9 +30,9 @@ public CategoryResponse registerCategory(CategoryRegisterRequest categoryRegiste parentCategoryEntity = null; } else { parentCategoryEntity = gatheringCategoryRepository.findById( - categoryRegisterRequest.getParentCategory()) - .orElseThrow( - () -> new CategoryNotExistsException("Parent category not found")); + categoryRegisterRequest.getParentCategory()) + .orElseThrow( + () -> new CategoryNotExistsException("Parent category not found")); } GatheringCategory category = new GatheringCategory(parentCategoryEntity, categoryRegisterRequest.getName()); @@ -45,8 +44,8 @@ public CategoryResponse registerCategory(CategoryRegisterRequest categoryRegiste public CategoryResponse getCategory(Long id) { GatheringCategory category = gatheringCategoryRepository.findById(id) - .orElseThrow( - () -> new CategoryNotExistsException("category not found")); + .orElseThrow( + () -> new CategoryNotExistsException("category not found")); return gatheringCategoryMapper.mapToCategoryResponse(category); } @@ -65,7 +64,7 @@ public List getParentCategories() { for (GatheringCategory category : parentCategories) { List childrenCategories = getChildrenCategories(category.getId()); categoryGetResponses.add( - new CategoryGetResponse(category.getId(), category.getName(), childrenCategories)); + new CategoryGetResponse(category.getId(), category.getName(), childrenCategories)); } return categoryGetResponses; @@ -78,9 +77,9 @@ public CategoryResponse modifyCategory(Long id, CategoryModifyRequest categoryMo parentCategoryEntity = null; } else { parentCategoryEntity = gatheringCategoryRepository.findById( - categoryModifyRequest.getParentCategory()) - .orElseThrow( - () -> new CategoryNotExistsException("Parent category not found")); + categoryModifyRequest.getParentCategory()) + .orElseThrow( + () -> new CategoryNotExistsException("Parent category not found")); } GatheringCategory category = gatheringCategoryRepository.findById(id).orElseThrow(); diff --git a/src/main/java/solitour_backend/solitour/auth/config/AuthConfiguration.java b/src/main/java/solitour_backend/solitour/auth/config/AuthConfiguration.java index 318198c2..f522392b 100644 --- a/src/main/java/solitour_backend/solitour/auth/config/AuthConfiguration.java +++ b/src/main/java/solitour_backend/solitour/auth/config/AuthConfiguration.java @@ -1,5 +1,6 @@ package solitour_backend.solitour.auth.config; +import java.util.List; import lombok.RequiredArgsConstructor; import org.springframework.context.annotation.Configuration; import org.springframework.web.method.support.HandlerMethodArgumentResolver; @@ -10,8 +11,6 @@ import solitour_backend.solitour.auth.entity.TokenRepository; import solitour_backend.solitour.auth.support.JwtTokenProvider; -import java.util.List; - @RequiredArgsConstructor @Configuration public class AuthConfiguration implements WebMvcConfigurer { diff --git a/src/main/java/solitour_backend/solitour/auth/config/AuthInterceptor.java b/src/main/java/solitour_backend/solitour/auth/config/AuthInterceptor.java index 6796d8c0..eea6b2c8 100644 --- a/src/main/java/solitour_backend/solitour/auth/config/AuthInterceptor.java +++ b/src/main/java/solitour_backend/solitour/auth/config/AuthInterceptor.java @@ -3,10 +3,8 @@ import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; - import java.lang.annotation.Annotation; import java.util.Optional; - import lombok.RequiredArgsConstructor; import org.springframework.web.cors.CorsUtils; import org.springframework.web.method.HandlerMethod; diff --git a/src/main/java/solitour_backend/solitour/auth/config/TokenResolver.java b/src/main/java/solitour_backend/solitour/auth/config/TokenResolver.java index e6a1340b..440b2779 100644 --- a/src/main/java/solitour_backend/solitour/auth/config/TokenResolver.java +++ b/src/main/java/solitour_backend/solitour/auth/config/TokenResolver.java @@ -25,7 +25,8 @@ public boolean supportsParameter(MethodParameter parameter) { } @Override - public Long resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) { + public Long resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, + NativeWebRequest webRequest, WebDataBinderFactory binderFactory) { String token = ""; HttpServletRequest request = webRequest.getNativeRequest(HttpServletRequest.class); diff --git a/src/main/java/solitour_backend/solitour/auth/controller/OauthController.java b/src/main/java/solitour_backend/solitour/auth/controller/OauthController.java index 89eb8a60..fbc48ea3 100644 --- a/src/main/java/solitour_backend/solitour/auth/controller/OauthController.java +++ b/src/main/java/solitour_backend/solitour/auth/controller/OauthController.java @@ -10,7 +10,6 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; -import solitour_backend.solitour.auth.config.Authenticated; import solitour_backend.solitour.auth.config.AuthenticationPrincipal; import solitour_backend.solitour.auth.config.AuthenticationRefreshPrincipal; import solitour_backend.solitour.auth.service.OauthService; @@ -33,7 +32,8 @@ public ResponseEntity access(@RequestParam String type, @Requ } @GetMapping(value = "/login", params = {"type", "code", "redirectUrl"}) - public ResponseEntity login(HttpServletResponse response, @RequestParam String type, @RequestParam String code, @RequestParam String redirectUrl) { + public ResponseEntity login(HttpServletResponse response, @RequestParam String type, + @RequestParam String code, @RequestParam String redirectUrl) { LoginResponse loginResponse = oauthService.requestAccessToken(type, code, redirectUrl); String accessCookieHeader = setCookieHeader(loginResponse.getAccessToken()); @@ -45,7 +45,6 @@ public ResponseEntity login(HttpServletResponse response, @Reques return ResponseEntity.ok().build(); } - @Authenticated @PostMapping("/logout") public ResponseEntity logout(@AuthenticationPrincipal Long memberId) { oauthService.logout(memberId); @@ -55,7 +54,8 @@ public ResponseEntity logout(@AuthenticationPrincipal Long memberId) { @PostMapping("/token/refresh") - public ResponseEntity reissueAccessToken(HttpServletResponse response, @AuthenticationRefreshPrincipal Long memberId) { + public ResponseEntity reissueAccessToken(HttpServletResponse response, + @AuthenticationRefreshPrincipal Long memberId) { AccessTokenResponse accessToken = oauthService.reissueAccessToken(memberId); String accessCookieHeader = setCookieHeader(accessToken.getAccessToken()); @@ -66,6 +66,6 @@ public ResponseEntity reissueAccessToken(HttpServletResponse response, @Au private String setCookieHeader(Cookie cookie) { return String.format("%s=%s; Path=%s; Max-Age=%d;Secure; HttpOnly; SameSite=Lax", - cookie.getName(), cookie.getValue(), cookie.getPath(),cookie.getMaxAge()); + cookie.getName(), cookie.getValue(), cookie.getPath(), cookie.getMaxAge()); } } diff --git a/src/main/java/solitour_backend/solitour/auth/entity/TokenRepository.java b/src/main/java/solitour_backend/solitour/auth/entity/TokenRepository.java index 03b6f5d0..d020ddf0 100644 --- a/src/main/java/solitour_backend/solitour/auth/entity/TokenRepository.java +++ b/src/main/java/solitour_backend/solitour/auth/entity/TokenRepository.java @@ -1,7 +1,6 @@ package solitour_backend.solitour.auth.entity; import java.util.Optional; - import org.springframework.data.jpa.repository.Modifying; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.Repository; diff --git a/src/main/java/solitour_backend/solitour/auth/service/OauthService.java b/src/main/java/solitour_backend/solitour/auth/service/OauthService.java index c487826b..9c2ad915 100644 --- a/src/main/java/solitour_backend/solitour/auth/service/OauthService.java +++ b/src/main/java/solitour_backend/solitour/auth/service/OauthService.java @@ -2,12 +2,12 @@ import jakarta.servlet.http.Cookie; - +import java.io.IOException; import java.time.LocalDateTime; import java.util.Objects; import java.util.concurrent.TimeUnit; - import lombok.RequiredArgsConstructor; +import org.springframework.http.HttpStatusCode; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import solitour_backend.solitour.auth.service.dto.response.AccessTokenResponse; @@ -176,7 +176,24 @@ public AccessTokenResponse reissueAccessToken(Long userId) { } @Transactional - public void logout(Long memberId) { - tokenService.deleteByMemberId(memberId); + public void logout(Long userId) { + tokenService.deleteByMemberId(userId); } + + public void revokeToken(String type, String token) throws IOException { + HttpStatusCode responseCode; + switch (type) { + case "kakao" -> responseCode = kakaoConnector.requestRevoke(token); + case "google" -> responseCode = googleConnector.requestRevoke(token); + default -> throw new RuntimeException("Unsupported oauth type"); + } + + if (responseCode.is2xxSuccessful()) { + System.out.println("Token successfully revoked"); + } else { + System.out.println("Failed to revoke token, response code: " + responseCode); + throw new RuntimeException("Failed to revoke token"); + } + } + } diff --git a/src/main/java/solitour_backend/solitour/auth/support/JwtTokenProvider.java b/src/main/java/solitour_backend/solitour/auth/support/JwtTokenProvider.java index fe18d5b9..cbd79737 100644 --- a/src/main/java/solitour_backend/solitour/auth/support/JwtTokenProvider.java +++ b/src/main/java/solitour_backend/solitour/auth/support/JwtTokenProvider.java @@ -7,10 +7,8 @@ import io.jsonwebtoken.Jwts; import io.jsonwebtoken.io.Decoders; import io.jsonwebtoken.security.Keys; - import java.util.Date; import javax.crypto.SecretKey; - import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; diff --git a/src/main/java/solitour_backend/solitour/auth/support/google/GoogleConnector.java b/src/main/java/solitour_backend/solitour/auth/support/google/GoogleConnector.java index 5e4d7028..decb3703 100644 --- a/src/main/java/solitour_backend/solitour/auth/support/google/GoogleConnector.java +++ b/src/main/java/solitour_backend/solitour/auth/support/google/GoogleConnector.java @@ -1,14 +1,15 @@ package solitour_backend.solitour.auth.support.google; +import java.io.IOException; import java.util.Collections; import java.util.Optional; - import lombok.Getter; import lombok.RequiredArgsConstructor; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; +import org.springframework.http.HttpStatusCode; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Component; @@ -40,9 +41,9 @@ public ResponseEntity requestGoogleUserInfo(String code, Str GoogleUserResponse.class); } - private String requestAccessToken(String code, String redirectUrl) { + public String requestAccessToken(String code, String redirectUrl) { HttpEntity> entity = new HttpEntity<>( - createBody(code, redirectUrl), createHeaders()); + createLoginBody(code, redirectUrl), createLoginHeaders()); ResponseEntity response = REST_TEMPLATE.postForEntity( provider.getAccessTokenUrl(), @@ -51,14 +52,23 @@ private String requestAccessToken(String code, String redirectUrl) { return extractAccessToken(response); } - private HttpHeaders createHeaders() { + public HttpStatusCode requestRevoke(String token) throws IOException { + HttpEntity> entity = new HttpEntity<>( + createRevokeBody(token), createRevokeHeaders()); + + ResponseEntity response = REST_TEMPLATE.postForEntity(provider.getRevokeUrl(), entity, Void.class); + + return response.getStatusCode(); + } + + private HttpHeaders createLoginHeaders() { HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED); headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON)); return headers; } - private MultiValueMap createBody(String code, String redirectUrl) { + private MultiValueMap createLoginBody(String code, String redirectUrl) { MultiValueMap body = new LinkedMultiValueMap<>(); body.add("code", code); body.add("client_id", provider.getClientId()); @@ -68,6 +78,18 @@ private MultiValueMap createBody(String code, String redirectUrl return body; } + private HttpHeaders createRevokeHeaders() { + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED); + return headers; + } + + private MultiValueMap createRevokeBody(String token) { + MultiValueMap body = new LinkedMultiValueMap<>(); + body.add("token", token); + return body; + } + private String extractAccessToken(ResponseEntity responseEntity) { GoogleTokenResponse response = Optional.ofNullable(responseEntity.getBody()) .orElseThrow(() -> new RuntimeException("구글 토큰을 가져오는데 실패했습니다.")); diff --git a/src/main/java/solitour_backend/solitour/auth/support/google/GoogleProvider.java b/src/main/java/solitour_backend/solitour/auth/support/google/GoogleProvider.java index 683b9a11..c11140db 100644 --- a/src/main/java/solitour_backend/solitour/auth/support/google/GoogleProvider.java +++ b/src/main/java/solitour_backend/solitour/auth/support/google/GoogleProvider.java @@ -3,7 +3,6 @@ import java.util.HashMap; import java.util.Map; import java.util.stream.Collectors; - import lombok.Getter; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; @@ -17,6 +16,7 @@ public class GoogleProvider { private final String authUrl; private final String accessTokenUrl; private final String userInfoUrl; + private final String revokeUrl; private final String grantType; private final String scope; @@ -25,6 +25,7 @@ public GoogleProvider(@Value("${oauth2.google.client.id}") String clientId, @Value("${oauth2.google.url.auth}") String authUrl, @Value("${oauth2.google.url.token}") String accessTokenUrl, @Value("${oauth2.google.url.userinfo}") String userInfoUrl, + @Value("${oauth2.google.url.revoke}") String revokeUrl, @Value("${oauth2.google.grant-type}") String grantType, @Value("${oauth2.google.scope}") String scope) { this.clientId = clientId; @@ -32,6 +33,7 @@ public GoogleProvider(@Value("${oauth2.google.client.id}") String clientId, this.authUrl = authUrl; this.accessTokenUrl = accessTokenUrl; this.userInfoUrl = userInfoUrl; + this.revokeUrl = revokeUrl; this.grantType = grantType; this.scope = scope; } diff --git a/src/main/java/solitour_backend/solitour/auth/support/google/dto/GoogleUserResponse.java b/src/main/java/solitour_backend/solitour/auth/support/google/dto/GoogleUserResponse.java index 29984b49..65425753 100644 --- a/src/main/java/solitour_backend/solitour/auth/support/google/dto/GoogleUserResponse.java +++ b/src/main/java/solitour_backend/solitour/auth/support/google/dto/GoogleUserResponse.java @@ -1,9 +1,7 @@ package solitour_backend.solitour.auth.support.google.dto; import com.fasterxml.jackson.annotation.JsonProperty; - import java.util.List; - import lombok.AllArgsConstructor; import lombok.Data; import lombok.Getter; diff --git a/src/main/java/solitour_backend/solitour/auth/support/kakao/KakaoConnector.java b/src/main/java/solitour_backend/solitour/auth/support/kakao/KakaoConnector.java index 0eba1c48..a690fcc3 100644 --- a/src/main/java/solitour_backend/solitour/auth/support/kakao/KakaoConnector.java +++ b/src/main/java/solitour_backend/solitour/auth/support/kakao/KakaoConnector.java @@ -1,14 +1,15 @@ package solitour_backend.solitour.auth.support.kakao; +import java.io.IOException; import java.util.Collections; import java.util.Optional; - import lombok.Getter; import lombok.RequiredArgsConstructor; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; +import org.springframework.http.HttpStatusCode; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Component; @@ -39,7 +40,7 @@ public ResponseEntity requestKakaoUserInfo(String code, Strin KakaoUserResponse.class); } - private String requestAccessToken(String code, String redirectUrl) { + public String requestAccessToken(String code, String redirectUrl) { HttpEntity> entity = new HttpEntity<>( createBody(code, redirectUrl), createHeaders()); @@ -73,4 +74,20 @@ private String extractAccessToken(ResponseEntity responseEnt return response.getAccessToken(); } + + public HttpStatusCode requestRevoke(String token) throws IOException { + HttpEntity> entity = new HttpEntity<>(createRevokeHeaders(token)); + + ResponseEntity response = REST_TEMPLATE.postForEntity(provider.getRevokeUrl(), entity, String.class); + + return response.getStatusCode(); + } + + private HttpHeaders createRevokeHeaders(String token) { + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED); + headers.set("Authorization", String.join(" ", BEARER_TYPE, token)); + return headers; + } + } diff --git a/src/main/java/solitour_backend/solitour/auth/support/kakao/KakaoProvider.java b/src/main/java/solitour_backend/solitour/auth/support/kakao/KakaoProvider.java index 4c9353df..bfbb1ad8 100644 --- a/src/main/java/solitour_backend/solitour/auth/support/kakao/KakaoProvider.java +++ b/src/main/java/solitour_backend/solitour/auth/support/kakao/KakaoProvider.java @@ -3,7 +3,6 @@ import java.util.HashMap; import java.util.Map; import java.util.stream.Collectors; - import lombok.Getter; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; @@ -18,6 +17,7 @@ public class KakaoProvider { private final String accessTokenUrl; private final String userInfoUrl; private final String grantType; + private final String revokeUrl; private final String scope; @@ -27,6 +27,7 @@ public KakaoProvider(@Value("${oauth2.kakao.client.id}") String clientId, @Value("${oauth2.kakao.url.token}") String accessTokenUrl, @Value("${oauth2.kakao.url.userinfo}") String userInfoUrl, @Value("${oauth2.kakao.grant-type}") String grantType, + @Value("${oauth2.kakao.url.revoke}") String revokeUrl, @Value("${oauth2.kakao.scope}") String scope) { this.clientId = clientId; this.clientSecret = clientSecret; @@ -34,6 +35,7 @@ public KakaoProvider(@Value("${oauth2.kakao.client.id}") String clientId, this.accessTokenUrl = accessTokenUrl; this.userInfoUrl = userInfoUrl; this.grantType = grantType; + this.revokeUrl = revokeUrl; this.scope = scope; } diff --git a/src/main/java/solitour_backend/solitour/auth/support/kakao/dto/KakaoUserResponse.java b/src/main/java/solitour_backend/solitour/auth/support/kakao/dto/KakaoUserResponse.java index 2f5bb124..af3b0ab5 100644 --- a/src/main/java/solitour_backend/solitour/auth/support/kakao/dto/KakaoUserResponse.java +++ b/src/main/java/solitour_backend/solitour/auth/support/kakao/dto/KakaoUserResponse.java @@ -2,10 +2,8 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; - import java.util.Date; import java.util.HashMap; - import lombok.Getter; import lombok.NoArgsConstructor; diff --git a/src/main/java/solitour_backend/solitour/book_mark_information/entity/BookMarkInformationRepository.java b/src/main/java/solitour_backend/solitour/book_mark_information/entity/BookMarkInformationRepository.java index efe21532..cbc5d85a 100644 --- a/src/main/java/solitour_backend/solitour/book_mark_information/entity/BookMarkInformationRepository.java +++ b/src/main/java/solitour_backend/solitour/book_mark_information/entity/BookMarkInformationRepository.java @@ -2,7 +2,6 @@ import java.util.List; import java.util.Optional; - import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; diff --git a/src/main/java/solitour_backend/solitour/book_mark_information/service/BookMarkInformationService.java b/src/main/java/solitour_backend/solitour/book_mark_information/service/BookMarkInformationService.java index e2dbfccd..34666823 100644 --- a/src/main/java/solitour_backend/solitour/book_mark_information/service/BookMarkInformationService.java +++ b/src/main/java/solitour_backend/solitour/book_mark_information/service/BookMarkInformationService.java @@ -1,9 +1,7 @@ package solitour_backend.solitour.book_mark_information.service; import jakarta.persistence.EntityNotFoundException; - import java.util.List; - import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; diff --git a/src/main/java/solitour_backend/solitour/category/controller/CategoryController.java b/src/main/java/solitour_backend/solitour/category/controller/CategoryController.java index d5fa0e6f..e7216be0 100644 --- a/src/main/java/solitour_backend/solitour/category/controller/CategoryController.java +++ b/src/main/java/solitour_backend/solitour/category/controller/CategoryController.java @@ -1,9 +1,7 @@ package solitour_backend.solitour.category.controller; import jakarta.validation.Valid; - import java.util.List; - import lombok.RequiredArgsConstructor; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -48,8 +46,9 @@ public ResponseEntity getCategory(@PathVariable Long id) { } @PostMapping - public ResponseEntity registerCategory(@Valid @RequestBody CategoryRegisterRequest categoryRegisterRequest, - BindingResult bindingResult) { + public ResponseEntity registerCategory( + @Valid @RequestBody CategoryRegisterRequest categoryRegisterRequest, + BindingResult bindingResult) { if (bindingResult.hasErrors()) { throw new RequestValidationFailedException(bindingResult); } @@ -62,9 +61,10 @@ public ResponseEntity registerCategory(@Valid @RequestBody Cat } @PutMapping("/{id}") - public ResponseEntity modifyCategory(@Valid @RequestBody CategoryModifyRequest categoryModifyRequest, - BindingResult bindingResult, - @PathVariable Long id) { + public ResponseEntity modifyCategory( + @Valid @RequestBody CategoryModifyRequest categoryModifyRequest, + BindingResult bindingResult, + @PathVariable Long id) { if (bindingResult.hasErrors()) { throw new RequestValidationFailedException(bindingResult); } diff --git a/src/main/java/solitour_backend/solitour/category/dto/mapper/CategoryMapper.java b/src/main/java/solitour_backend/solitour/category/dto/mapper/CategoryMapper.java index e0e8f3d0..4f9c294a 100644 --- a/src/main/java/solitour_backend/solitour/category/dto/mapper/CategoryMapper.java +++ b/src/main/java/solitour_backend/solitour/category/dto/mapper/CategoryMapper.java @@ -1,7 +1,6 @@ package solitour_backend.solitour.category.dto.mapper; import java.util.List; - import org.mapstruct.Mapper; import org.mapstruct.ReportingPolicy; import solitour_backend.solitour.category.dto.response.CategoryResponse; diff --git a/src/main/java/solitour_backend/solitour/category/dto/response/CategoryGetResponse.java b/src/main/java/solitour_backend/solitour/category/dto/response/CategoryGetResponse.java index 4d0ff101..f4fb2c1d 100644 --- a/src/main/java/solitour_backend/solitour/category/dto/response/CategoryGetResponse.java +++ b/src/main/java/solitour_backend/solitour/category/dto/response/CategoryGetResponse.java @@ -1,7 +1,6 @@ package solitour_backend.solitour.category.dto.response; import java.util.List; - import lombok.AllArgsConstructor; import lombok.Getter; diff --git a/src/main/java/solitour_backend/solitour/category/repository/CategoryRepository.java b/src/main/java/solitour_backend/solitour/category/repository/CategoryRepository.java index d51394ea..2600c43b 100644 --- a/src/main/java/solitour_backend/solitour/category/repository/CategoryRepository.java +++ b/src/main/java/solitour_backend/solitour/category/repository/CategoryRepository.java @@ -1,7 +1,6 @@ package solitour_backend.solitour.category.repository; import java.util.List; - import org.springframework.data.jpa.repository.JpaRepository; import solitour_backend.solitour.category.entity.Category; diff --git a/src/main/java/solitour_backend/solitour/category/service/CategoryService.java b/src/main/java/solitour_backend/solitour/category/service/CategoryService.java index 91163cd2..68667240 100644 --- a/src/main/java/solitour_backend/solitour/category/service/CategoryService.java +++ b/src/main/java/solitour_backend/solitour/category/service/CategoryService.java @@ -3,7 +3,6 @@ import java.util.ArrayList; import java.util.List; import java.util.Objects; - import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; diff --git a/src/main/java/solitour_backend/solitour/error/exception/RequestValidationFailedException.java b/src/main/java/solitour_backend/solitour/error/exception/RequestValidationFailedException.java index 8bfb679a..81bfc786 100644 --- a/src/main/java/solitour_backend/solitour/error/exception/RequestValidationFailedException.java +++ b/src/main/java/solitour_backend/solitour/error/exception/RequestValidationFailedException.java @@ -1,9 +1,7 @@ package solitour_backend.solitour.error.exception; import jakarta.validation.ValidationException; - import java.util.stream.Collectors; - import org.springframework.validation.BindingResult; public class RequestValidationFailedException extends ValidationException { diff --git a/src/main/java/solitour_backend/solitour/gathering/controller/GatheringController.java b/src/main/java/solitour_backend/solitour/gathering/controller/GatheringController.java index 6c61a769..5f75bd2d 100644 --- a/src/main/java/solitour_backend/solitour/gathering/controller/GatheringController.java +++ b/src/main/java/solitour_backend/solitour/gathering/controller/GatheringController.java @@ -2,11 +2,19 @@ import jakarta.servlet.http.HttpServletRequest; import jakarta.validation.Valid; +import java.time.LocalDateTime; +import java.util.Objects; import lombok.RequiredArgsConstructor; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.validation.BindingResult; -import org.springframework.web.bind.annotation.*; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; import solitour_backend.solitour.auth.config.AuthenticationPrincipal; import solitour_backend.solitour.auth.support.CookieExtractor; import solitour_backend.solitour.auth.support.JwtTokenProvider; @@ -18,9 +26,6 @@ import solitour_backend.solitour.gathering.dto.response.GatheringResponse; import solitour_backend.solitour.gathering.service.GatheringService; -import java.time.LocalDateTime; -import java.util.Objects; - @RestController @RequiredArgsConstructor @RequestMapping("/api/gatherings") @@ -68,7 +73,6 @@ public ResponseEntity updateGathering(@AuthenticationPrincipa @PathVariable Long gatheringId, @Valid @RequestBody GatheringModifyRequest gatheringModifyRequest) { - if (gatheringModifyRequest.getEndAge() > gatheringModifyRequest.getStartAge()) { throw new RequestValidationFailedException("시작 나이 연도가 끝 나이 연도 보다 앞에 있네요"); } @@ -79,7 +83,8 @@ public ResponseEntity updateGathering(@AuthenticationPrincipa if (gatheringModifyRequest.getDeadline().isBefore(LocalDateTime.now())) { throw new RequestValidationFailedException("마감일은 현재 시간보다 이후여야 합니다."); } - GatheringResponse gatheringResponse = gatheringService.modifyGathering(userId, gatheringId, gatheringModifyRequest); + GatheringResponse gatheringResponse = gatheringService.modifyGathering(userId, gatheringId, + gatheringModifyRequest); return ResponseEntity .status(HttpStatus.CREATED) diff --git a/src/main/java/solitour_backend/solitour/gathering/dto/request/GatheringModifyRequest.java b/src/main/java/solitour_backend/solitour/gathering/dto/request/GatheringModifyRequest.java index 65910c16..366e042f 100644 --- a/src/main/java/solitour_backend/solitour/gathering/dto/request/GatheringModifyRequest.java +++ b/src/main/java/solitour_backend/solitour/gathering/dto/request/GatheringModifyRequest.java @@ -1,7 +1,13 @@ package solitour_backend.solitour.gathering.dto.request; import com.fasterxml.jackson.annotation.JsonFormat; -import jakarta.validation.constraints.*; +import jakarta.validation.constraints.Max; +import jakarta.validation.constraints.Min; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; +import java.time.LocalDateTime; +import java.util.List; import lombok.Getter; import lombok.NoArgsConstructor; import org.springframework.format.annotation.DateTimeFormat; @@ -9,9 +15,6 @@ import solitour_backend.solitour.place.dto.request.PlaceModifyRequest; import solitour_backend.solitour.tag.dto.request.TagRegisterRequest; -import java.time.LocalDateTime; -import java.util.List; - @Getter @NoArgsConstructor public class GatheringModifyRequest { diff --git a/src/main/java/solitour_backend/solitour/gathering/dto/request/GatheringRegisterRequest.java b/src/main/java/solitour_backend/solitour/gathering/dto/request/GatheringRegisterRequest.java index f4832d35..c3815d9c 100644 --- a/src/main/java/solitour_backend/solitour/gathering/dto/request/GatheringRegisterRequest.java +++ b/src/main/java/solitour_backend/solitour/gathering/dto/request/GatheringRegisterRequest.java @@ -1,7 +1,13 @@ package solitour_backend.solitour.gathering.dto.request; import com.fasterxml.jackson.annotation.JsonFormat; -import jakarta.validation.constraints.*; +import jakarta.validation.constraints.Max; +import jakarta.validation.constraints.Min; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; +import java.time.LocalDateTime; +import java.util.List; import lombok.Getter; import lombok.NoArgsConstructor; import org.springframework.format.annotation.DateTimeFormat; @@ -9,9 +15,6 @@ import solitour_backend.solitour.place.dto.request.PlaceRegisterRequest; import solitour_backend.solitour.tag.dto.request.TagRegisterRequest; -import java.time.LocalDateTime; -import java.util.List; - @Getter @NoArgsConstructor public class GatheringRegisterRequest { diff --git a/src/main/java/solitour_backend/solitour/gathering/dto/response/GatheringBriefResponse.java b/src/main/java/solitour_backend/solitour/gathering/dto/response/GatheringBriefResponse.java index 72f033f9..00c5c788 100644 --- a/src/main/java/solitour_backend/solitour/gathering/dto/response/GatheringBriefResponse.java +++ b/src/main/java/solitour_backend/solitour/gathering/dto/response/GatheringBriefResponse.java @@ -1,11 +1,10 @@ package solitour_backend.solitour.gathering.dto.response; +import java.time.LocalDateTime; import lombok.AllArgsConstructor; import lombok.Getter; import solitour_backend.solitour.gathering.entity.AllowedSex; -import java.time.LocalDateTime; - @Getter @AllArgsConstructor public class GatheringBriefResponse { diff --git a/src/main/java/solitour_backend/solitour/gathering/dto/response/GatheringDetailResponse.java b/src/main/java/solitour_backend/solitour/gathering/dto/response/GatheringDetailResponse.java index 492b08ed..3e7601d5 100644 --- a/src/main/java/solitour_backend/solitour/gathering/dto/response/GatheringDetailResponse.java +++ b/src/main/java/solitour_backend/solitour/gathering/dto/response/GatheringDetailResponse.java @@ -1,5 +1,7 @@ package solitour_backend.solitour.gathering.dto.response; +import java.time.LocalDateTime; +import java.util.List; import lombok.AllArgsConstructor; import lombok.Getter; import solitour_backend.solitour.gathering.entity.AllowedSex; @@ -9,9 +11,6 @@ import solitour_backend.solitour.user.dto.UserPostingResponse; import solitour_backend.solitour.zone_category.dto.response.ZoneCategoryResponse; -import java.time.LocalDateTime; -import java.util.List; - @Getter @AllArgsConstructor public class GatheringDetailResponse { diff --git a/src/main/java/solitour_backend/solitour/gathering/entity/AllowedSex.java b/src/main/java/solitour_backend/solitour/gathering/entity/AllowedSex.java index 73252417..0dee7cc6 100644 --- a/src/main/java/solitour_backend/solitour/gathering/entity/AllowedSex.java +++ b/src/main/java/solitour_backend/solitour/gathering/entity/AllowedSex.java @@ -1,8 +1,7 @@ package solitour_backend.solitour.gathering.entity; -import lombok.Getter; - import java.util.Arrays; +import lombok.Getter; @Getter public enum AllowedSex { diff --git a/src/main/java/solitour_backend/solitour/gathering/entity/Gathering.java b/src/main/java/solitour_backend/solitour/gathering/entity/Gathering.java index 5784ccd1..384302c7 100644 --- a/src/main/java/solitour_backend/solitour/gathering/entity/Gathering.java +++ b/src/main/java/solitour_backend/solitour/gathering/entity/Gathering.java @@ -1,9 +1,17 @@ package solitour_backend.solitour.gathering.entity; -import jakarta.persistence.*; - +import jakarta.persistence.Column; +import jakarta.persistence.Convert; +import jakarta.persistence.Entity; +import jakarta.persistence.EntityListeners; +import jakarta.persistence.FetchType; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.ManyToOne; +import jakarta.persistence.Table; import java.time.LocalDateTime; - import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; @@ -86,7 +94,10 @@ public class Gathering { @Column(name = "gathering_end_age") private Integer endAge; - public Gathering(User user, ZoneCategory zoneCategory, GatheringCategory gatheringCategory, Place place, String title, String content, Integer personCount, Integer viewCount, LocalDateTime scheduleStartDate, LocalDateTime scheduleEndDate, Boolean isFinish, LocalDateTime deadline, AllowedSex allowedSex, Integer startAge, Integer endAge) { + public Gathering(User user, ZoneCategory zoneCategory, GatheringCategory gatheringCategory, Place place, + String title, String content, Integer personCount, Integer viewCount, + LocalDateTime scheduleStartDate, LocalDateTime scheduleEndDate, Boolean isFinish, + LocalDateTime deadline, AllowedSex allowedSex, Integer startAge, Integer endAge) { this.user = user; this.zoneCategory = zoneCategory; this.gatheringCategory = gatheringCategory; diff --git a/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryCustom.java b/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryCustom.java index def6f2d9..2f66d69c 100644 --- a/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryCustom.java +++ b/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryCustom.java @@ -1,10 +1,9 @@ package solitour_backend.solitour.gathering.repository; +import java.util.List; import org.springframework.data.repository.NoRepositoryBean; import solitour_backend.solitour.gathering.dto.response.GatheringBriefResponse; -import java.util.List; - @NoRepositoryBean public interface GatheringRepositoryCustom { List getGatheringRecommend(Long informationId, Long gatheringCategoryId, Long userId); diff --git a/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryImpl.java b/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryImpl.java index 4336dfd1..aa0d74a8 100644 --- a/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryImpl.java +++ b/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryImpl.java @@ -1,6 +1,7 @@ package solitour_backend.solitour.gathering.repository; import com.querydsl.core.types.Projections; +import java.util.List; import org.springframework.data.jpa.repository.support.QuerydslRepositorySupport; import solitour_backend.solitour.book_mark_gathering.entity.QBookMarkGathering; import solitour_backend.solitour.gathering.dto.response.GatheringBriefResponse; @@ -12,8 +13,6 @@ import solitour_backend.solitour.great_gathering.entity.QGreatGathering; import solitour_backend.solitour.zone_category.entity.QZoneCategory; -import java.util.List; - public class GatheringRepositoryImpl extends QuerydslRepositorySupport implements GatheringRepositoryCustom { public GatheringRepositoryImpl() { super(Gathering.class); @@ -33,14 +32,16 @@ public List getGatheringRecommend(Long gatheringId, Long return from(gathering) .join(zoneCategoryChild).on(zoneCategoryChild.id.eq(gathering.zoneCategory.id)) .leftJoin(zoneCategoryParent).on(zoneCategoryParent.id.eq(zoneCategoryChild.parentZoneCategory.id)) - .leftJoin(bookMarkGathering).on(bookMarkGathering.gathering.id.eq(gathering.id).and(bookMarkGathering.user.id.eq(userId))) + .leftJoin(bookMarkGathering) + .on(bookMarkGathering.gathering.id.eq(gathering.id).and(bookMarkGathering.user.id.eq(userId))) .leftJoin(greatGathering).on(greatGathering.gathering.id.eq(gathering.id)) .leftJoin(category).on(category.id.eq(gathering.gatheringCategory.id)) .leftJoin(gatheringApplicants).on(gatheringApplicants.gathering.id.eq(gathering.id)) .where(gathering.isFinish.eq(Boolean.FALSE) .and(gathering.gatheringCategory.id.eq(gatheringCategoryId)) .and(gathering.id.ne(gatheringId)) - .and(gatheringApplicants.gatheringStatus.eq(GatheringStatus.CONSENT).or(gatheringApplicants.gatheringStatus.isNull())) + .and(gatheringApplicants.gatheringStatus.eq(GatheringStatus.CONSENT) + .or(gatheringApplicants.gatheringStatus.isNull())) ) .groupBy(gathering.id, zoneCategoryChild.id, zoneCategoryParent.id, category.id) .orderBy(gathering.createdAt.desc()) diff --git a/src/main/java/solitour_backend/solitour/gathering/service/GatheringService.java b/src/main/java/solitour_backend/solitour/gathering/service/GatheringService.java index 5e203648..1ca3ede8 100644 --- a/src/main/java/solitour_backend/solitour/gathering/service/GatheringService.java +++ b/src/main/java/solitour_backend/solitour/gathering/service/GatheringService.java @@ -1,5 +1,8 @@ package solitour_backend.solitour.gathering.service; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -44,10 +47,6 @@ import solitour_backend.solitour.zone_category.exception.ZoneCategoryNotExistsException; import solitour_backend.solitour.zone_category.repository.ZoneCategoryRepository; -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; - @Service @Transactional(readOnly = true) @RequiredArgsConstructor @@ -87,15 +86,19 @@ public GatheringDetailResponse getGatheringDetail(Long userId, Long gatheringId) PlaceResponse placeResponse = placeMapper.mapToPlaceResponse(gathering.getPlace()); - ZoneCategoryResponse zoneCategoryResponse = zoneCategoryMapper.mapToZoneCategoryResponse(gathering.getZoneCategory()); + ZoneCategoryResponse zoneCategoryResponse = zoneCategoryMapper.mapToZoneCategoryResponse( + gathering.getZoneCategory()); int likeCount = greatGatheringRepository.countByGatheringId(gathering.getId()); - List gatheringApplicantsResponses = gatheringApplicantsMapper.mapToGatheringApplicantsResponses(gatheringApplicantsRepository.findAllByGathering_Id(gathering.getId())); + List gatheringApplicantsResponses = gatheringApplicantsMapper.mapToGatheringApplicantsResponses( + gatheringApplicantsRepository.findAllByGathering_Id(gathering.getId())); - int nowPersonCount = gatheringApplicantsRepository.countAllByGathering_IdAndGatheringStatus(gathering.getId(), GatheringStatus.CONSENT); + int nowPersonCount = gatheringApplicantsRepository.countAllByGathering_IdAndGatheringStatus(gathering.getId(), + GatheringStatus.CONSENT); - List gatheringRecommend = gatheringRepository.getGatheringRecommend(gathering.getId(), gathering.getGatheringCategory().getId(), userId); + List gatheringRecommend = gatheringRepository.getGatheringRecommend(gathering.getId(), + gathering.getGatheringCategory().getId(), userId); return new GatheringDetailResponse( gathering.getTitle(), @@ -182,7 +185,8 @@ public GatheringResponse registerGathering(Long userId, GatheringRegisterRequest } @Transactional - public GatheringResponse modifyGathering(Long userId, Long gatheringId, GatheringModifyRequest gatheringModifyRequest) { + public GatheringResponse modifyGathering(Long userId, Long gatheringId, + GatheringModifyRequest gatheringModifyRequest) { User user = userRepository.findById(userId) .orElseThrow( () -> new UserNotExistsException("해당하는 id의 User 가 없습니다")); @@ -195,10 +199,12 @@ public GatheringResponse modifyGathering(Long userId, Long gatheringId, Gatherin throw new GatheringNotManagerException("해당 유저는 권한이 없습니다"); } - GatheringCategory gatheringCategory = gatheringCategoryRepository.findById(gatheringModifyRequest.getGatheringCategoryId()).orElseThrow(); - ZoneCategory parentZoneCategory = zoneCategoryRepository.findByParentZoneCategoryIdAndName(null, gatheringModifyRequest.getZoneCategoryNameParent()).orElseThrow(); - ZoneCategory childZoneCategory = zoneCategoryRepository.findByParentZoneCategoryIdAndName(parentZoneCategory.getId(), gatheringModifyRequest.getZoneCategoryNameChild()).orElseThrow(); - + GatheringCategory gatheringCategory = gatheringCategoryRepository.findById( + gatheringModifyRequest.getGatheringCategoryId()).orElseThrow(); + ZoneCategory parentZoneCategory = zoneCategoryRepository.findByParentZoneCategoryIdAndName(null, + gatheringModifyRequest.getZoneCategoryNameParent()).orElseThrow(); + ZoneCategory childZoneCategory = zoneCategoryRepository.findByParentZoneCategoryIdAndName( + parentZoneCategory.getId(), gatheringModifyRequest.getZoneCategoryNameChild()).orElseThrow(); Place place = gathering.getPlace(); PlaceModifyRequest placeModifyRequest = gatheringModifyRequest.getPlaceModifyRequest(); @@ -229,7 +235,8 @@ public GatheringResponse modifyGathering(Long userId, Long gatheringId, Gatherin tagRepository.deleteById(gatheringTag.getTag().getTagId()); } - List saveTags = tagRepository.saveAll(tagMapper.mapToTags(gatheringModifyRequest.getTagRegisterRequests())); + List saveTags = tagRepository.saveAll( + tagMapper.mapToTags(gatheringModifyRequest.getTagRegisterRequests())); for (Tag tag : saveTags) { gatheringTagRepository.save(new GatheringTag(tag, gathering)); diff --git a/src/main/java/solitour_backend/solitour/gathering_applicants/controller/GatheringApplicantsController.java b/src/main/java/solitour_backend/solitour/gathering_applicants/controller/GatheringApplicantsController.java index 32ee93c2..2b73d214 100644 --- a/src/main/java/solitour_backend/solitour/gathering_applicants/controller/GatheringApplicantsController.java +++ b/src/main/java/solitour_backend/solitour/gathering_applicants/controller/GatheringApplicantsController.java @@ -4,7 +4,13 @@ import lombok.RequiredArgsConstructor; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.*; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; import solitour_backend.solitour.auth.config.AuthenticationPrincipal; import solitour_backend.solitour.gathering_applicants.dto.request.GatheringApplicantsModifyRequest; import solitour_backend.solitour.gathering_applicants.service.GatheringApplicantsService; @@ -16,7 +22,8 @@ public class GatheringApplicantsController { private final GatheringApplicantsService gatheringApplicantsService; @PostMapping("/{gatheringId}") - public ResponseEntity participateGathering(@AuthenticationPrincipal Long userId, @PathVariable Long gatheringId) { + public ResponseEntity participateGathering(@AuthenticationPrincipal Long userId, + @PathVariable Long gatheringId) { gatheringApplicantsService.participateGatheringFromAnotherUser(userId, gatheringId); return ResponseEntity @@ -25,7 +32,8 @@ public ResponseEntity participateGathering(@AuthenticationPrincipal Long u } @DeleteMapping("/{gatheringId}") - public ResponseEntity deleteParticipateGathering(@AuthenticationPrincipal Long userId, @PathVariable Long gatheringId) { + public ResponseEntity deleteParticipateGathering(@AuthenticationPrincipal Long userId, + @PathVariable Long gatheringId) { gatheringApplicantsService.deleteGatheringApplicantsFromAnotherUser(userId, gatheringId); return ResponseEntity @@ -38,7 +46,8 @@ public ResponseEntity updateParticipateGatheringStatus(@AuthenticationPrin @PathVariable Long gatheringId, @Valid @RequestBody GatheringApplicantsModifyRequest gatheringApplicantsModifyRequest) { - boolean result = gatheringApplicantsService.updateGatheringApplicantsManagement(userId, gatheringId, gatheringApplicantsModifyRequest); + boolean result = gatheringApplicantsService.updateGatheringApplicantsManagement(userId, gatheringId, + gatheringApplicantsModifyRequest); if (result) { return ResponseEntity diff --git a/src/main/java/solitour_backend/solitour/gathering_applicants/dto/mapper/GatheringApplicantsMapper.java b/src/main/java/solitour_backend/solitour/gathering_applicants/dto/mapper/GatheringApplicantsMapper.java index f02f72ae..c34a9234 100644 --- a/src/main/java/solitour_backend/solitour/gathering_applicants/dto/mapper/GatheringApplicantsMapper.java +++ b/src/main/java/solitour_backend/solitour/gathering_applicants/dto/mapper/GatheringApplicantsMapper.java @@ -1,5 +1,6 @@ package solitour_backend.solitour.gathering_applicants.dto.mapper; +import java.util.List; import org.mapstruct.Mapper; import org.mapstruct.Mapping; import org.mapstruct.ReportingPolicy; @@ -7,8 +8,6 @@ import solitour_backend.solitour.gathering_applicants.entity.GatheringApplicants; import solitour_backend.solitour.user.dto.mapper.UserMapper; -import java.util.List; - @Mapper(componentModel = "spring", unmappedTargetPolicy = ReportingPolicy.ERROR, uses = UserMapper.class) public interface GatheringApplicantsMapper { diff --git a/src/main/java/solitour_backend/solitour/gathering_applicants/entity/GatheringApplicants.java b/src/main/java/solitour_backend/solitour/gathering_applicants/entity/GatheringApplicants.java index c8d300f5..b2dddc2f 100644 --- a/src/main/java/solitour_backend/solitour/gathering_applicants/entity/GatheringApplicants.java +++ b/src/main/java/solitour_backend/solitour/gathering_applicants/entity/GatheringApplicants.java @@ -1,6 +1,15 @@ package solitour_backend.solitour.gathering_applicants.entity; -import jakarta.persistence.*; +import jakarta.persistence.Column; +import jakarta.persistence.Convert; +import jakarta.persistence.Entity; +import jakarta.persistence.FetchType; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.ManyToOne; +import jakarta.persistence.Table; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; diff --git a/src/main/java/solitour_backend/solitour/gathering_applicants/entity/GatheringStatus.java b/src/main/java/solitour_backend/solitour/gathering_applicants/entity/GatheringStatus.java index 403b4c36..288f6aec 100644 --- a/src/main/java/solitour_backend/solitour/gathering_applicants/entity/GatheringStatus.java +++ b/src/main/java/solitour_backend/solitour/gathering_applicants/entity/GatheringStatus.java @@ -1,8 +1,7 @@ package solitour_backend.solitour.gathering_applicants.entity; -import lombok.Getter; - import java.util.Arrays; +import lombok.Getter; @Getter public enum GatheringStatus { diff --git a/src/main/java/solitour_backend/solitour/gathering_applicants/repository/GatheringApplicantsRepository.java b/src/main/java/solitour_backend/solitour/gathering_applicants/repository/GatheringApplicantsRepository.java index 1432d310..d3399046 100644 --- a/src/main/java/solitour_backend/solitour/gathering_applicants/repository/GatheringApplicantsRepository.java +++ b/src/main/java/solitour_backend/solitour/gathering_applicants/repository/GatheringApplicantsRepository.java @@ -1,12 +1,11 @@ package solitour_backend.solitour.gathering_applicants.repository; +import java.util.List; +import java.util.Optional; import org.springframework.data.jpa.repository.JpaRepository; import solitour_backend.solitour.gathering_applicants.entity.GatheringApplicants; import solitour_backend.solitour.gathering_applicants.entity.GatheringStatus; -import java.util.List; -import java.util.Optional; - public interface GatheringApplicantsRepository extends JpaRepository { List findAllByGathering_Id(Long id); diff --git a/src/main/java/solitour_backend/solitour/gathering_applicants/service/GatheringApplicantsService.java b/src/main/java/solitour_backend/solitour/gathering_applicants/service/GatheringApplicantsService.java index 5e214c6e..18de534a 100644 --- a/src/main/java/solitour_backend/solitour/gathering_applicants/service/GatheringApplicantsService.java +++ b/src/main/java/solitour_backend/solitour/gathering_applicants/service/GatheringApplicantsService.java @@ -1,5 +1,6 @@ package solitour_backend.solitour.gathering_applicants.service; +import java.util.Objects; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -18,8 +19,6 @@ import solitour_backend.solitour.user.entity.UserRepository; import solitour_backend.solitour.user.exception.UserNotExistsException; -import java.util.Objects; - @Service @Transactional @RequiredArgsConstructor @@ -44,7 +43,8 @@ public void participateGatheringFromAnotherUser(Long userId, Long gatheringId) { } Integer personCount = gathering.getPersonCount(); - int nowPersonCount = gatheringApplicantsRepository.countAllByGathering_IdAndGatheringStatus(gatheringId, GatheringStatus.CONSENT); + int nowPersonCount = gatheringApplicantsRepository.countAllByGathering_IdAndGatheringStatus(gatheringId, + GatheringStatus.CONSENT); if (personCount <= nowPersonCount) { throw new GatheringApplicantsAlreadyFullPeopleException("이미 인원이 가득 찼습니다."); @@ -66,15 +66,18 @@ public void deleteGatheringApplicantsFromAnotherUser(Long userId, Long gathering () -> new UserNotExistsException("해당하는 id의 user가 없습니다")); - GatheringApplicants gatheringApplicants = gatheringApplicantsRepository.findByGatheringIdAndUserId(gathering.getId(), user.getId()) + GatheringApplicants gatheringApplicants = gatheringApplicantsRepository.findByGatheringIdAndUserId( + gathering.getId(), user.getId()) .orElseThrow( () -> - new GatheringApplicantsNotExistsException("해당하는 모임과 user의 gathering applicants가 없습니다.")); + new GatheringApplicantsNotExistsException( + "해당하는 모임과 user의 gathering applicants가 없습니다.")); gatheringApplicantsRepository.delete(gatheringApplicants); } - public boolean updateGatheringApplicantsManagement(Long userId, Long gatheringId, GatheringApplicantsModifyRequest gatheringApplicantsModifyRequest) { + public boolean updateGatheringApplicantsManagement(Long userId, Long gatheringId, + GatheringApplicantsModifyRequest gatheringApplicantsModifyRequest) { Gathering gathering = gatheringRepository.findById(gatheringId) .orElseThrow( () -> @@ -89,13 +92,15 @@ public boolean updateGatheringApplicantsManagement(Long userId, Long gatheringId throw new GatheringNotManagerException("해당하는 user 가 해당 gathering 의 manage 가 아닙니다"); } - GatheringApplicants gatheringApplicants = gatheringApplicantsRepository.findByGatheringIdAndUserId(gathering.getId(), gatheringApplicantsModifyRequest.getUserId()) + GatheringApplicants gatheringApplicants = gatheringApplicantsRepository.findByGatheringIdAndUserId( + gathering.getId(), gatheringApplicantsModifyRequest.getUserId()) .orElseThrow( () -> new GatheringApplicantsNotExistsException("해당하는 모임, user 의 applicants 가 없습니다") ); - if (Objects.equals(gatheringApplicants.getGatheringStatus(), gatheringApplicantsModifyRequest.getGatheringStatus())) { + if (Objects.equals(gatheringApplicants.getGatheringStatus(), + gatheringApplicantsModifyRequest.getGatheringStatus())) { return false; } diff --git a/src/main/java/solitour_backend/solitour/gathering_category/entity/GatheringCategory.java b/src/main/java/solitour_backend/solitour/gathering_category/entity/GatheringCategory.java index a828d338..8ad8b714 100644 --- a/src/main/java/solitour_backend/solitour/gathering_category/entity/GatheringCategory.java +++ b/src/main/java/solitour_backend/solitour/gathering_category/entity/GatheringCategory.java @@ -1,6 +1,14 @@ package solitour_backend.solitour.gathering_category.entity; -import jakarta.persistence.*; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.FetchType; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.ManyToOne; +import jakarta.persistence.Table; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; diff --git a/src/main/java/solitour_backend/solitour/gathering_category/repository/GatheringCategoryRepository.java b/src/main/java/solitour_backend/solitour/gathering_category/repository/GatheringCategoryRepository.java index 650eb290..c68fdde3 100644 --- a/src/main/java/solitour_backend/solitour/gathering_category/repository/GatheringCategoryRepository.java +++ b/src/main/java/solitour_backend/solitour/gathering_category/repository/GatheringCategoryRepository.java @@ -1,10 +1,9 @@ package solitour_backend.solitour.gathering_category.repository; +import java.util.List; import org.springframework.data.jpa.repository.JpaRepository; import solitour_backend.solitour.gathering_category.entity.GatheringCategory; -import java.util.List; - public interface GatheringCategoryRepository extends JpaRepository { List findAllByParentCategoryId(Long parentCategoryId); diff --git a/src/main/java/solitour_backend/solitour/gathering_tag/repository/GatheringTagRepository.java b/src/main/java/solitour_backend/solitour/gathering_tag/repository/GatheringTagRepository.java index f1982424..ed2aa051 100644 --- a/src/main/java/solitour_backend/solitour/gathering_tag/repository/GatheringTagRepository.java +++ b/src/main/java/solitour_backend/solitour/gathering_tag/repository/GatheringTagRepository.java @@ -1,10 +1,9 @@ package solitour_backend.solitour.gathering_tag.repository; +import java.util.List; import org.springframework.data.jpa.repository.JpaRepository; import solitour_backend.solitour.gathering_tag.entity.GatheringTag; -import java.util.List; - public interface GatheringTagRepository extends JpaRepository { List findAllByGathering_Id(Long gatheringId); diff --git a/src/main/java/solitour_backend/solitour/great_information/repository/GreatInformationRepository.java b/src/main/java/solitour_backend/solitour/great_information/repository/GreatInformationRepository.java index 7bf38e06..60d6448c 100644 --- a/src/main/java/solitour_backend/solitour/great_information/repository/GreatInformationRepository.java +++ b/src/main/java/solitour_backend/solitour/great_information/repository/GreatInformationRepository.java @@ -1,7 +1,6 @@ package solitour_backend.solitour.great_information.repository; import java.util.Optional; - import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; import solitour_backend.solitour.great_information.entity.GreatInformation; diff --git a/src/main/java/solitour_backend/solitour/image/dto/mapper/ImageMapper.java b/src/main/java/solitour_backend/solitour/image/dto/mapper/ImageMapper.java index 7398c584..b961d950 100644 --- a/src/main/java/solitour_backend/solitour/image/dto/mapper/ImageMapper.java +++ b/src/main/java/solitour_backend/solitour/image/dto/mapper/ImageMapper.java @@ -1,7 +1,6 @@ package solitour_backend.solitour.image.dto.mapper; import java.util.List; - import org.mapstruct.Mapper; import org.mapstruct.Mapping; import org.mapstruct.Named; diff --git a/src/main/java/solitour_backend/solitour/image/entity/Image.java b/src/main/java/solitour_backend/solitour/image/entity/Image.java index 457e6b24..5c77f5a9 100644 --- a/src/main/java/solitour_backend/solitour/image/entity/Image.java +++ b/src/main/java/solitour_backend/solitour/image/entity/Image.java @@ -10,9 +10,7 @@ import jakarta.persistence.JoinColumn; import jakarta.persistence.ManyToOne; import jakarta.persistence.Table; - import java.time.LocalDate; - import lombok.Getter; import lombok.NoArgsConstructor; import solitour_backend.solitour.image.image_status.ImageStatus; diff --git a/src/main/java/solitour_backend/solitour/image/image_status/ImageStatus.java b/src/main/java/solitour_backend/solitour/image/image_status/ImageStatus.java index 725f9ecc..3c8541b7 100644 --- a/src/main/java/solitour_backend/solitour/image/image_status/ImageStatus.java +++ b/src/main/java/solitour_backend/solitour/image/image_status/ImageStatus.java @@ -1,7 +1,6 @@ package solitour_backend.solitour.image.image_status; import java.util.Arrays; - import lombok.Getter; @Getter diff --git a/src/main/java/solitour_backend/solitour/image/repository/ImageRepository.java b/src/main/java/solitour_backend/solitour/image/repository/ImageRepository.java index 790014fc..7e04a88c 100644 --- a/src/main/java/solitour_backend/solitour/image/repository/ImageRepository.java +++ b/src/main/java/solitour_backend/solitour/image/repository/ImageRepository.java @@ -1,7 +1,6 @@ package solitour_backend.solitour.image.repository; import java.util.List; - import org.springframework.data.jpa.repository.JpaRepository; import solitour_backend.solitour.image.entity.Image; import solitour_backend.solitour.image.image_status.ImageStatus; diff --git a/src/main/java/solitour_backend/solitour/image/s3/S3Uploader.java b/src/main/java/solitour_backend/solitour/image/s3/S3Uploader.java index fbb3cc0a..69a74f5e 100644 --- a/src/main/java/solitour_backend/solitour/image/s3/S3Uploader.java +++ b/src/main/java/solitour_backend/solitour/image/s3/S3Uploader.java @@ -4,11 +4,9 @@ import com.amazonaws.services.s3.model.DeleteObjectRequest; import com.amazonaws.services.s3.model.ObjectMetadata; import com.amazonaws.services.s3.model.PutObjectRequest; - import java.io.IOException; import java.io.InputStream; import java.util.UUID; - import lombok.RequiredArgsConstructor; import org.springframework.beans.factory.annotation.Value; import org.springframework.http.HttpStatus; diff --git a/src/main/java/solitour_backend/solitour/info_tag/repository/InfoTagRepository.java b/src/main/java/solitour_backend/solitour/info_tag/repository/InfoTagRepository.java index 9ec0216c..3dc611c9 100644 --- a/src/main/java/solitour_backend/solitour/info_tag/repository/InfoTagRepository.java +++ b/src/main/java/solitour_backend/solitour/info_tag/repository/InfoTagRepository.java @@ -1,7 +1,6 @@ package solitour_backend.solitour.info_tag.repository; import java.util.List; - import org.springframework.data.jpa.repository.JpaRepository; import solitour_backend.solitour.info_tag.entity.InfoTag; diff --git a/src/main/java/solitour_backend/solitour/information/controller/InformationController.java b/src/main/java/solitour_backend/solitour/information/controller/InformationController.java index ec25678b..5e642038 100644 --- a/src/main/java/solitour_backend/solitour/information/controller/InformationController.java +++ b/src/main/java/solitour_backend/solitour/information/controller/InformationController.java @@ -3,10 +3,8 @@ import jakarta.servlet.http.HttpServletRequest; import jakarta.validation.Valid; - import java.util.List; import java.util.Objects; - import lombok.RequiredArgsConstructor; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; @@ -14,15 +12,27 @@ import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.validation.BindingResult; -import org.springframework.web.bind.annotation.*; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RequestPart; +import org.springframework.web.bind.annotation.RestController; import org.springframework.web.multipart.MultipartFile; +import solitour_backend.solitour.auth.config.Authenticated; import solitour_backend.solitour.auth.support.CookieExtractor; import solitour_backend.solitour.auth.support.JwtTokenProvider; -import solitour_backend.solitour.auth.config.Authenticated; import solitour_backend.solitour.error.Utils; import solitour_backend.solitour.information.dto.request.InformationModifyRequest; import solitour_backend.solitour.information.dto.request.InformationRegisterRequest; -import solitour_backend.solitour.information.dto.response.*; +import solitour_backend.solitour.information.dto.response.InformationBriefResponse; +import solitour_backend.solitour.information.dto.response.InformationDetailResponse; +import solitour_backend.solitour.information.dto.response.InformationMainResponse; +import solitour_backend.solitour.information.dto.response.InformationRankResponse; +import solitour_backend.solitour.information.dto.response.InformationResponse; import solitour_backend.solitour.information.service.InformationService; @RestController @@ -37,10 +47,11 @@ public class InformationController { @PostMapping @Authenticated - public ResponseEntity createInformation(@Valid @RequestPart("request") InformationRegisterRequest informationRegisterRequest, - @RequestPart("thumbNailImage") MultipartFile thumbnail, - @RequestPart("contentImages") List contentImages, - BindingResult bindingResult) { + public ResponseEntity createInformation( + @Valid @RequestPart("request") InformationRegisterRequest informationRegisterRequest, + @RequestPart("thumbNailImage") MultipartFile thumbnail, + @RequestPart("contentImages") List contentImages, + BindingResult bindingResult) { Utils.validationRequest(bindingResult); InformationResponse informationResponse = informationService.registerInformation( informationRegisterRequest, thumbnail, contentImages); @@ -54,7 +65,8 @@ public ResponseEntity createInformation(@Valid @RequestPart public ResponseEntity getDetailInformation(@PathVariable Long informationId, HttpServletRequest request) { Long userId = findUser(request); - InformationDetailResponse informationDetailResponse = informationService.getDetailInformation(userId, informationId); + InformationDetailResponse informationDetailResponse = informationService.getDetailInformation(userId, + informationId); return ResponseEntity .status(HttpStatus.OK) @@ -89,15 +101,17 @@ public ResponseEntity deleteInformation(@PathVariable Long informationId) } @GetMapping("/parent-category/{parentCategoryId}") - public ResponseEntity> pageInformationByParentCategoryFilterZoneCategory(@RequestParam(defaultValue = "0") int page, - @RequestParam(required = false, name = "zoneCategory") Long zoneCategoryId, - @PathVariable("parentCategoryId") Long categoryId, - HttpServletRequest request) { + public ResponseEntity> pageInformationByParentCategoryFilterZoneCategory( + @RequestParam(defaultValue = "0") int page, + @RequestParam(required = false, name = "zoneCategory") Long zoneCategoryId, + @PathVariable("parentCategoryId") Long categoryId, + HttpServletRequest request) { Long userId = findUser(request); Pageable pageable = PageRequest.of(page, PAGE_SIZE); - Page briefInformationPage = informationService.getBriefInformationPageByParentCategoryFilterZoneCategory(pageable, categoryId, userId, zoneCategoryId); + Page briefInformationPage = informationService.getBriefInformationPageByParentCategoryFilterZoneCategory( + pageable, categoryId, userId, zoneCategoryId); return ResponseEntity .status(HttpStatus.OK) @@ -105,14 +119,16 @@ public ResponseEntity> pageInformationByParentCat } @GetMapping("/child-category/{childCategoryId}") - public ResponseEntity> pageInformationByChildCategoryFilterZoneCategory(@RequestParam(defaultValue = "0") int page, - @PathVariable("childCategoryId") Long categoryId, - @RequestParam(required = false, name = "zoneCategory") Long zoneCategoryId, - HttpServletRequest request) { + public ResponseEntity> pageInformationByChildCategoryFilterZoneCategory( + @RequestParam(defaultValue = "0") int page, + @PathVariable("childCategoryId") Long categoryId, + @RequestParam(required = false, name = "zoneCategory") Long zoneCategoryId, + HttpServletRequest request) { Long userId = findUser(request); Pageable pageable = PageRequest.of(page, PAGE_SIZE); - Page briefInformationPage = informationService.getBriefInformationPageByChildCategoryFilterZoneCategory(pageable, categoryId, userId, zoneCategoryId); + Page briefInformationPage = informationService.getBriefInformationPageByChildCategoryFilterZoneCategory( + pageable, categoryId, userId, zoneCategoryId); return ResponseEntity .status(HttpStatus.OK) @@ -121,26 +137,30 @@ public ResponseEntity> pageInformationByChildCate //지역 카테고리 별 좋아요순 @GetMapping("/parent-category/{parentCategory}/like-count") - public ResponseEntity> pageInformationByParentCategoryFilterZoneCategoryLikeCount(@RequestParam(defaultValue = "0") int page, - @RequestParam(required = false, name = "zoneCategory") Long zoneCategoryId, - @PathVariable("parentCategory") Long categoryId, - HttpServletRequest request) { + public ResponseEntity> pageInformationByParentCategoryFilterZoneCategoryLikeCount( + @RequestParam(defaultValue = "0") int page, + @RequestParam(required = false, name = "zoneCategory") Long zoneCategoryId, + @PathVariable("parentCategory") Long categoryId, + HttpServletRequest request) { Long userId = findUser(request); Pageable pageable = PageRequest.of(page, PAGE_SIZE); - Page briefInformationPage = informationService.getBriefInformationPageByParentCategoryFilterZoneCategoryLikeCount(pageable, categoryId, userId, zoneCategoryId); + Page briefInformationPage = informationService.getBriefInformationPageByParentCategoryFilterZoneCategoryLikeCount( + pageable, categoryId, userId, zoneCategoryId); return ResponseEntity .status(HttpStatus.OK) .body(briefInformationPage); } @GetMapping("/child-category/{childCategory}/like-count") - public ResponseEntity> pageInformationChildCategoryFilterZoneCategoryLikeCount(@RequestParam(defaultValue = "0") int page, - @RequestParam(required = false, name = "zoneCategory") Long zoneCategoryId, - @PathVariable("childCategory") Long categoryId, - HttpServletRequest request) { + public ResponseEntity> pageInformationChildCategoryFilterZoneCategoryLikeCount( + @RequestParam(defaultValue = "0") int page, + @RequestParam(required = false, name = "zoneCategory") Long zoneCategoryId, + @PathVariable("childCategory") Long categoryId, + HttpServletRequest request) { Long userId = findUser(request); Pageable pageable = PageRequest.of(page, PAGE_SIZE); - Page briefInformationPage = informationService.getBriefInformationPageByChildCategoryFilterZoneCategoryLikeCount(pageable, categoryId, userId, zoneCategoryId); + Page briefInformationPage = informationService.getBriefInformationPageByChildCategoryFilterZoneCategoryLikeCount( + pageable, categoryId, userId, zoneCategoryId); return ResponseEntity .status(HttpStatus.OK) .body(briefInformationPage); @@ -149,27 +169,31 @@ public ResponseEntity> pageInformationChildCatego //지역 카테고리 별 조회순 @GetMapping("/parent-category/{parentCategoryId}/view-count") - public ResponseEntity> pageInformationByParentCategoryFilterZoneCategoryViewCount(@RequestParam(defaultValue = "0") int page, - @RequestParam(required = false, name = "zoneCategory") Long zoneCategoryId, - @PathVariable("parentCategoryId") Long categoryId, - HttpServletRequest request) { + public ResponseEntity> pageInformationByParentCategoryFilterZoneCategoryViewCount( + @RequestParam(defaultValue = "0") int page, + @RequestParam(required = false, name = "zoneCategory") Long zoneCategoryId, + @PathVariable("parentCategoryId") Long categoryId, + HttpServletRequest request) { Long userId = findUser(request); Pageable pageable = PageRequest.of(page, PAGE_SIZE); - Page briefInformationPage = informationService.getBriefInformationPageByParentCategoryFilterZoneCategoryViewCount(pageable, categoryId, userId, zoneCategoryId); + Page briefInformationPage = informationService.getBriefInformationPageByParentCategoryFilterZoneCategoryViewCount( + pageable, categoryId, userId, zoneCategoryId); return ResponseEntity .status(HttpStatus.OK) .body(briefInformationPage); } @GetMapping("/child-category/{childCategoryId}/view-count") - public ResponseEntity> pageInformationByChildCategoryViewCount(@RequestParam(defaultValue = "0") int page, - @PathVariable("childCategoryId") Long categoryId, - @RequestParam(required = false, name = "zoneCategory") Long zoneCategoryId, - HttpServletRequest request) { + public ResponseEntity> pageInformationByChildCategoryViewCount( + @RequestParam(defaultValue = "0") int page, + @PathVariable("childCategoryId") Long categoryId, + @RequestParam(required = false, name = "zoneCategory") Long zoneCategoryId, + HttpServletRequest request) { Long userId = findUser(request); Pageable pageable = PageRequest.of(page, PAGE_SIZE); - Page briefInformationPage = informationService.getBriefInformationPageByChildCategoryFilterZoneCategoryViewCount(pageable, categoryId, userId, zoneCategoryId); + Page briefInformationPage = informationService.getBriefInformationPageByChildCategoryFilterZoneCategoryViewCount( + pageable, categoryId, userId, zoneCategoryId); return ResponseEntity .status(HttpStatus.OK) .body(briefInformationPage); diff --git a/src/main/java/solitour_backend/solitour/information/dto/request/InformationModifyRequest.java b/src/main/java/solitour_backend/solitour/information/dto/request/InformationModifyRequest.java index 9140375c..a5bcc333 100644 --- a/src/main/java/solitour_backend/solitour/information/dto/request/InformationModifyRequest.java +++ b/src/main/java/solitour_backend/solitour/information/dto/request/InformationModifyRequest.java @@ -4,6 +4,7 @@ import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.Size; +import java.util.List; import lombok.Getter; import lombok.NoArgsConstructor; import solitour_backend.solitour.image.dto.request.ImageDeleteRequest; @@ -11,8 +12,6 @@ import solitour_backend.solitour.place.dto.request.PlaceModifyRequest; import solitour_backend.solitour.tag.dto.request.TagRegisterRequest; -import java.util.List; - @Getter @NoArgsConstructor public class InformationModifyRequest { diff --git a/src/main/java/solitour_backend/solitour/information/dto/request/InformationRegisterRequest.java b/src/main/java/solitour_backend/solitour/information/dto/request/InformationRegisterRequest.java index 25254a27..64c4d73e 100644 --- a/src/main/java/solitour_backend/solitour/information/dto/request/InformationRegisterRequest.java +++ b/src/main/java/solitour_backend/solitour/information/dto/request/InformationRegisterRequest.java @@ -4,9 +4,7 @@ import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.Size; - import java.util.List; - import lombok.Getter; import lombok.NoArgsConstructor; import solitour_backend.solitour.place.dto.request.PlaceRegisterRequest; diff --git a/src/main/java/solitour_backend/solitour/information/dto/response/InformationDetailResponse.java b/src/main/java/solitour_backend/solitour/information/dto/response/InformationDetailResponse.java index bdfc33bf..574c7e84 100644 --- a/src/main/java/solitour_backend/solitour/information/dto/response/InformationDetailResponse.java +++ b/src/main/java/solitour_backend/solitour/information/dto/response/InformationDetailResponse.java @@ -2,7 +2,6 @@ import java.time.LocalDateTime; import java.util.List; - import lombok.AllArgsConstructor; import lombok.Getter; import solitour_backend.solitour.image.dto.response.ImageResponse; diff --git a/src/main/java/solitour_backend/solitour/information/entity/Information.java b/src/main/java/solitour_backend/solitour/information/entity/Information.java index 9bc83035..bb60e6bc 100644 --- a/src/main/java/solitour_backend/solitour/information/entity/Information.java +++ b/src/main/java/solitour_backend/solitour/information/entity/Information.java @@ -1,9 +1,17 @@ package solitour_backend.solitour.information.entity; -import jakarta.persistence.*; - +import jakarta.persistence.CascadeType; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.FetchType; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.ManyToOne; +import jakarta.persistence.OneToOne; +import jakarta.persistence.Table; import java.time.LocalDateTime; - import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; diff --git a/src/main/java/solitour_backend/solitour/information/repository/InformationRepositoryCustom.java b/src/main/java/solitour_backend/solitour/information/repository/InformationRepositoryCustom.java index 07ff36c6..0ad412ad 100644 --- a/src/main/java/solitour_backend/solitour/information/repository/InformationRepositoryCustom.java +++ b/src/main/java/solitour_backend/solitour/information/repository/InformationRepositoryCustom.java @@ -1,5 +1,6 @@ package solitour_backend.solitour.information.repository; +import java.util.List; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.repository.NoRepositoryBean; @@ -7,23 +8,37 @@ import solitour_backend.solitour.information.dto.response.InformationMainResponse; import solitour_backend.solitour.information.dto.response.InformationRankResponse; -import java.util.List; - @NoRepositoryBean public interface InformationRepositoryCustom { - Page getInformationByParentCategoryFilterZoneCategory(Pageable pageable, Long parentCategoryId, Long userId, Long zoneCategoryId); - - Page getInformationByChildCategoryFilterZoneCategory(Pageable pageable, Long childCategoryId, Long userId, Long zoneCategoryId); - - Page getInformationByParentCategoryFilterZoneCategoryLikeCount(Pageable pageable, Long categoryId, Long userId, Long zoneCategoryId); - - Page getInformationByChildCategoryFilterZoneCategoryLikeCount(Pageable pageable, Long categoryId, Long userId, Long zoneCategoryId); - - Page getInformationByParentCategoryFilterZoneCategoryViewCount(Pageable pageable, Long categoryId, Long userId, Long zoneCategoryId); - - Page getInformationByChildCategoryFilterZoneCategoryViewCount(Pageable pageable, Long categoryId, Long userId, Long zoneCategoryId); + Page getInformationByParentCategoryFilterZoneCategory(Pageable pageable, + Long parentCategoryId, Long userId, + Long zoneCategoryId); + + Page getInformationByChildCategoryFilterZoneCategory(Pageable pageable, + Long childCategoryId, Long userId, + Long zoneCategoryId); + + Page getInformationByParentCategoryFilterZoneCategoryLikeCount(Pageable pageable, + Long categoryId, + Long userId, + Long zoneCategoryId); + + Page getInformationByChildCategoryFilterZoneCategoryLikeCount(Pageable pageable, + Long categoryId, + Long userId, + Long zoneCategoryId); + + Page getInformationByParentCategoryFilterZoneCategoryViewCount(Pageable pageable, + Long categoryId, + Long userId, + Long zoneCategoryId); + + Page getInformationByChildCategoryFilterZoneCategoryViewCount(Pageable pageable, + Long categoryId, + Long userId, + Long zoneCategoryId); List getInformationRank(); diff --git a/src/main/java/solitour_backend/solitour/information/repository/InformationRepositoryImpl.java b/src/main/java/solitour_backend/solitour/information/repository/InformationRepositoryImpl.java index 935f9ff5..27794bb3 100644 --- a/src/main/java/solitour_backend/solitour/information/repository/InformationRepositoryImpl.java +++ b/src/main/java/solitour_backend/solitour/information/repository/InformationRepositoryImpl.java @@ -2,6 +2,9 @@ import com.querydsl.core.types.Projections; import com.querydsl.jpa.JPQLQuery; +import java.time.LocalDateTime; +import java.util.List; +import java.util.Objects; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageImpl; import org.springframework.data.domain.Pageable; @@ -18,10 +21,6 @@ import solitour_backend.solitour.information.entity.QInformation; import solitour_backend.solitour.zone_category.entity.QZoneCategory; -import java.time.LocalDateTime; -import java.util.List; -import java.util.Objects; - public class InformationRepositoryImpl extends QuerydslRepositorySupport implements InformationRepositoryCustom { public InformationRepositoryImpl() { @@ -38,11 +37,15 @@ public InformationRepositoryImpl() { @Override - public Page getInformationByParentCategoryFilterZoneCategory(Pageable pageable, Long parentCategoryId, Long userId, Long zoneCategoryId) { + public Page getInformationByParentCategoryFilterZoneCategory(Pageable pageable, + Long parentCategoryId, + Long userId, + Long zoneCategoryId) { JPQLQuery query = from(information) .join(zoneCategoryChild).on(zoneCategoryChild.id.eq(information.zoneCategory.id)) .leftJoin(zoneCategoryParent).on(zoneCategoryParent.id.eq(zoneCategoryChild.parentZoneCategory.id)) - .leftJoin(bookMarkInformation).on(bookMarkInformation.information.id.eq(information.id).and(bookMarkInformation.user.id.eq(userId))) + .leftJoin(bookMarkInformation) + .on(bookMarkInformation.information.id.eq(information.id).and(bookMarkInformation.user.id.eq(userId))) .leftJoin(image).on(image.information.id.eq(information.id) .and(image.imageStatus.eq(ImageStatus.THUMBNAIL))) .leftJoin(greatInformation).on(greatInformation.information.id.eq(information.id)) @@ -76,11 +79,15 @@ public Page getInformationByParentCategoryFilterZoneCa } @Override - public Page getInformationByChildCategoryFilterZoneCategory(Pageable pageable, Long childCategoryId, Long userId, Long zoneCategoryId) { + public Page getInformationByChildCategoryFilterZoneCategory(Pageable pageable, + Long childCategoryId, + Long userId, + Long zoneCategoryId) { JPQLQuery query = from(information) .join(zoneCategoryChild).on(zoneCategoryChild.id.eq(information.zoneCategory.id)) .leftJoin(zoneCategoryParent).on(zoneCategoryParent.id.eq(zoneCategoryChild.parentZoneCategory.id)) - .leftJoin(bookMarkInformation).on(bookMarkInformation.information.id.eq(information.id).and(bookMarkInformation.user.id.eq(userId))) + .leftJoin(bookMarkInformation) + .on(bookMarkInformation.information.id.eq(information.id).and(bookMarkInformation.user.id.eq(userId))) .leftJoin(image).on(image.information.id.eq(information.id) .and(image.imageStatus.eq(ImageStatus.THUMBNAIL))) .leftJoin(greatInformation).on(greatInformation.information.id.eq(information.id)) @@ -115,11 +122,15 @@ public Page getInformationByChildCategoryFilterZoneCat @Override - public Page getInformationByParentCategoryFilterZoneCategoryLikeCount(Pageable pageable, Long categoryId, Long userId, Long zoneCategoryId) { + public Page getInformationByParentCategoryFilterZoneCategoryLikeCount(Pageable pageable, + Long categoryId, + Long userId, + Long zoneCategoryId) { JPQLQuery query = from(information) .join(zoneCategoryChild).on(zoneCategoryChild.id.eq(information.zoneCategory.id)) .leftJoin(zoneCategoryParent).on(zoneCategoryParent.id.eq(zoneCategoryChild.parentZoneCategory.id)) - .leftJoin(bookMarkInformation).on(bookMarkInformation.information.id.eq(information.id).and(bookMarkInformation.user.id.eq(userId))) + .leftJoin(bookMarkInformation) + .on(bookMarkInformation.information.id.eq(information.id).and(bookMarkInformation.user.id.eq(userId))) .leftJoin(image).on(image.information.id.eq(information.id) .and(image.imageStatus.eq(ImageStatus.THUMBNAIL))) .leftJoin(greatInformation).on(greatInformation.information.id.eq(information.id)) @@ -129,7 +140,8 @@ public Page getInformationByParentCategoryFilterZoneCa query = query.where(information.zoneCategory.parentZoneCategory.id.eq(zoneCategoryId)); } - List list = query.groupBy(information.id, zoneCategoryChild.id, zoneCategoryParent.id, image.id) + List list = query.groupBy(information.id, zoneCategoryChild.id, zoneCategoryParent.id, + image.id) .orderBy(greatInformation.information.count().desc()) .select(Projections.constructor( InformationBriefResponse.class, @@ -152,11 +164,15 @@ public Page getInformationByParentCategoryFilterZoneCa } @Override - public Page getInformationByChildCategoryFilterZoneCategoryLikeCount(Pageable pageable, Long categoryId, Long userId, Long zoneCategoryId) { + public Page getInformationByChildCategoryFilterZoneCategoryLikeCount(Pageable pageable, + Long categoryId, + Long userId, + Long zoneCategoryId) { JPQLQuery query = from(information) .join(zoneCategoryChild).on(zoneCategoryChild.id.eq(information.zoneCategory.id)) .leftJoin(zoneCategoryParent).on(zoneCategoryParent.id.eq(zoneCategoryChild.parentZoneCategory.id)) - .leftJoin(bookMarkInformation).on(bookMarkInformation.information.id.eq(information.id).and(bookMarkInformation.user.id.eq(userId))) + .leftJoin(bookMarkInformation) + .on(bookMarkInformation.information.id.eq(information.id).and(bookMarkInformation.user.id.eq(userId))) .leftJoin(image).on(image.information.id.eq(information.id) .and(image.imageStatus.eq(ImageStatus.THUMBNAIL))) .leftJoin(greatInformation).on(greatInformation.information.id.eq(information.id)) @@ -190,11 +206,15 @@ public Page getInformationByChildCategoryFilterZoneCat } @Override - public Page getInformationByParentCategoryFilterZoneCategoryViewCount(Pageable pageable, Long categoryId, Long userId, Long zoneCategoryId) { + public Page getInformationByParentCategoryFilterZoneCategoryViewCount(Pageable pageable, + Long categoryId, + Long userId, + Long zoneCategoryId) { JPQLQuery query = from(information) .join(zoneCategoryChild).on(zoneCategoryChild.id.eq(information.zoneCategory.id)) .leftJoin(zoneCategoryParent).on(zoneCategoryParent.id.eq(zoneCategoryChild.parentZoneCategory.id)) - .leftJoin(bookMarkInformation).on(bookMarkInformation.information.id.eq(information.id).and(bookMarkInformation.user.id.eq(userId))) + .leftJoin(bookMarkInformation) + .on(bookMarkInformation.information.id.eq(information.id).and(bookMarkInformation.user.id.eq(userId))) .leftJoin(image).on(image.information.id.eq(information.id) .and(image.imageStatus.eq(ImageStatus.THUMBNAIL))) .leftJoin(greatInformation).on(greatInformation.information.id.eq(information.id)) @@ -228,11 +248,15 @@ public Page getInformationByParentCategoryFilterZoneCa } @Override - public Page getInformationByChildCategoryFilterZoneCategoryViewCount(Pageable pageable, Long categoryId, Long userId, Long zoneCategoryId) { + public Page getInformationByChildCategoryFilterZoneCategoryViewCount(Pageable pageable, + Long categoryId, + Long userId, + Long zoneCategoryId) { JPQLQuery query = from(information) .join(zoneCategoryChild).on(zoneCategoryChild.id.eq(information.zoneCategory.id)) .leftJoin(zoneCategoryParent).on(zoneCategoryParent.id.eq(zoneCategoryChild.parentZoneCategory.id)) - .leftJoin(bookMarkInformation).on(bookMarkInformation.information.id.eq(information.id).and(bookMarkInformation.user.id.eq(userId))) + .leftJoin(bookMarkInformation) + .on(bookMarkInformation.information.id.eq(information.id).and(bookMarkInformation.user.id.eq(userId))) .leftJoin(image).on(image.information.id.eq(information.id) .and(image.imageStatus.eq(ImageStatus.THUMBNAIL))) .leftJoin(greatInformation).on(greatInformation.information.id.eq(information.id)) @@ -271,12 +295,15 @@ public List getInformationLikeCountFromCreatedIn3(Long return from(information) .leftJoin(zoneCategoryChild).on(zoneCategoryChild.id.eq(information.zoneCategory.id)) .leftJoin(zoneCategoryParent).on(zoneCategoryParent.id.eq(zoneCategoryChild.parentZoneCategory.id)) - .leftJoin(bookMarkInformation).on(bookMarkInformation.information.id.eq(information.id).and(bookMarkInformation.user.id.eq(userId))) - .leftJoin(image).on(image.information.id.eq(information.id).and(image.imageStatus.eq(ImageStatus.THUMBNAIL))) + .leftJoin(bookMarkInformation) + .on(bookMarkInformation.information.id.eq(information.id).and(bookMarkInformation.user.id.eq(userId))) + .leftJoin(image) + .on(image.information.id.eq(information.id).and(image.imageStatus.eq(ImageStatus.THUMBNAIL))) .leftJoin(greatInformation).on(greatInformation.information.id.eq(information.id)) .leftJoin(category).on(category.id.eq(information.category.id)) .where(information.createdDate.after(LocalDateTime.now().minusMonths(3))) - .groupBy(information.id, information.title, zoneCategoryParent.name, zoneCategoryChild.name, bookMarkInformation.id, image.address) + .groupBy(information.id, information.title, zoneCategoryParent.name, zoneCategoryChild.name, + bookMarkInformation.id, image.address) .orderBy(greatInformation.information.id.count().desc()) .select(Projections.constructor( InformationMainResponse.class, @@ -294,11 +321,13 @@ public List getInformationLikeCountFromCreatedIn3(Long } @Override - public List getInformationRecommend(Long informationId, Long childCategoryId, Long userId) { + public List getInformationRecommend(Long informationId, Long childCategoryId, + Long userId) { return from(information) .join(zoneCategoryChild).on(zoneCategoryChild.id.eq(information.zoneCategory.id)) .leftJoin(zoneCategoryParent).on(zoneCategoryParent.id.eq(zoneCategoryChild.parentZoneCategory.id)) - .leftJoin(bookMarkInformation).on(bookMarkInformation.information.id.eq(information.id).and(bookMarkInformation.user.id.eq(userId))) + .leftJoin(bookMarkInformation) + .on(bookMarkInformation.information.id.eq(information.id).and(bookMarkInformation.user.id.eq(userId))) .leftJoin(image).on(image.information.id.eq(information.id) .and(image.imageStatus.eq(ImageStatus.THUMBNAIL))) .leftJoin(greatInformation).on(greatInformation.information.id.eq(information.id)) diff --git a/src/main/java/solitour_backend/solitour/information/service/InformationService.java b/src/main/java/solitour_backend/solitour/information/service/InformationService.java index d25e24b9..d1a00257 100644 --- a/src/main/java/solitour_backend/solitour/information/service/InformationService.java +++ b/src/main/java/solitour_backend/solitour/information/service/InformationService.java @@ -1,5 +1,10 @@ package solitour_backend.solitour.information.service; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; import lombok.RequiredArgsConstructor; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; @@ -26,7 +31,11 @@ import solitour_backend.solitour.information.dto.mapper.InformationMapper; import solitour_backend.solitour.information.dto.request.InformationModifyRequest; import solitour_backend.solitour.information.dto.request.InformationRegisterRequest; -import solitour_backend.solitour.information.dto.response.*; +import solitour_backend.solitour.information.dto.response.InformationBriefResponse; +import solitour_backend.solitour.information.dto.response.InformationDetailResponse; +import solitour_backend.solitour.information.dto.response.InformationMainResponse; +import solitour_backend.solitour.information.dto.response.InformationRankResponse; +import solitour_backend.solitour.information.dto.response.InformationResponse; import solitour_backend.solitour.information.entity.Information; import solitour_backend.solitour.information.exception.InformationNotExistsException; import solitour_backend.solitour.information.repository.InformationRepository; @@ -50,12 +59,6 @@ import solitour_backend.solitour.zone_category.exception.ZoneCategoryNotExistsException; import solitour_backend.solitour.zone_category.repository.ZoneCategoryRepository; -import java.time.LocalDate; -import java.time.LocalDateTime; -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; - @Service @Transactional(readOnly = true) @RequiredArgsConstructor @@ -83,7 +86,8 @@ public class InformationService { @Transactional - public InformationResponse registerInformation(InformationRegisterRequest informationRegisterRequest, MultipartFile thumbnail, List contentImages) { + public InformationResponse registerInformation(InformationRegisterRequest informationRegisterRequest, + MultipartFile thumbnail, List contentImages) { Category category = categoryRepository.findById(informationRegisterRequest.getCategoryId()) .orElseThrow( () -> new CategoryNotExistsException("해당하는 id의 category 가 없습니다")); @@ -172,7 +176,8 @@ public InformationDetailResponse getDetailInformation(Long userId, Long informat int likeCount = greatInformationRepository.countByInformationId(information.getId()); - List informationRecommend = informationRepository.getInformationRecommend(information.getId(), information.getCategory().getId(), userId); + List informationRecommend = informationRepository.getInformationRecommend( + information.getId(), information.getCategory().getId(), userId); return new InformationDetailResponse( information.getTitle(), @@ -191,7 +196,8 @@ public InformationDetailResponse getDetailInformation(Long userId, Long informat } @Transactional - public InformationResponse modifyInformation(Long id, InformationModifyRequest informationModifyRequest, MultipartFile thumbNail, List contentImages) { + public InformationResponse modifyInformation(Long id, InformationModifyRequest informationModifyRequest, + MultipartFile thumbNail, List contentImages) { Information information = informationRepository.findById(id) .orElseThrow( () -> new InformationNotExistsException("해당하는 id의 information이 존재하지 않습니다.")); @@ -214,11 +220,13 @@ public InformationResponse modifyInformation(Long id, InformationModifyRequest i () -> new CategoryNotExistsException("해당하는 cateogry Id 가 존재하지 않습니다.")); information.setCategory(categoryInformation); - ZoneCategory parentZoneCategory = zoneCategoryRepository.findByParentZoneCategoryIdAndName(null, informationModifyRequest.getZoneCategoryNameParent()) + ZoneCategory parentZoneCategory = zoneCategoryRepository.findByParentZoneCategoryIdAndName(null, + informationModifyRequest.getZoneCategoryNameParent()) .orElseThrow( () -> new ZoneCategoryNotExistsException("해당하는 name에 대한 zoneCategory가 존재하지 않습니다")); - ZoneCategory childZoneCategory = zoneCategoryRepository.findByParentZoneCategoryIdAndName(parentZoneCategory.getId(), informationModifyRequest.getZoneCategoryNameChild()) + ZoneCategory childZoneCategory = zoneCategoryRepository.findByParentZoneCategoryIdAndName( + parentZoneCategory.getId(), informationModifyRequest.getZoneCategoryNameChild()) .orElseThrow( () -> new ZoneCategoryNotExistsException("해당하는 name에 대한 zoneCategory가 존재하지 않습니다")); @@ -323,7 +331,10 @@ public void deleteInformation(Long id) { } //default - public Page getBriefInformationPageByParentCategoryFilterZoneCategory(Pageable pageable, Long parentCategoryId, Long userId, Long zoneCategoryId) { + public Page getBriefInformationPageByParentCategoryFilterZoneCategory(Pageable pageable, + Long parentCategoryId, + Long userId, + Long zoneCategoryId) { if (!categoryRepository.existsById(parentCategoryId)) { throw new CategoryNotExistsException("해당하는 id의 category는 없습니다"); } @@ -331,21 +342,27 @@ public Page getBriefInformationPageByParentCategoryFil throw new ZoneCategoryNotExistsException("해당하는 id의 zoneCategory는 없습니다"); } - return informationRepository.getInformationByParentCategoryFilterZoneCategory(pageable, parentCategoryId, userId, zoneCategoryId); + return informationRepository.getInformationByParentCategoryFilterZoneCategory(pageable, parentCategoryId, + userId, zoneCategoryId); } - public Page getBriefInformationPageByChildCategoryFilterZoneCategory(Pageable pageable, Long childCategoryId, Long userId, Long zoneCategoryId) { + public Page getBriefInformationPageByChildCategoryFilterZoneCategory(Pageable pageable, + Long childCategoryId, + Long userId, + Long zoneCategoryId) { if (!categoryRepository.existsById(childCategoryId)) { throw new CategoryNotExistsException("해당하는 id의 category는 없습니다"); } if (Objects.nonNull(zoneCategoryId) && !zoneCategoryRepository.existsById(zoneCategoryId)) { throw new ZoneCategoryNotExistsException("해당하는 id의 zoneCategory는 없습니다"); } - return informationRepository.getInformationByChildCategoryFilterZoneCategory(pageable, childCategoryId, userId, zoneCategoryId); + return informationRepository.getInformationByChildCategoryFilterZoneCategory(pageable, childCategoryId, userId, + zoneCategoryId); } //지역카테고리별 좋아요순 - public Page getBriefInformationPageByParentCategoryFilterZoneCategoryLikeCount(Pageable pageable, Long parentCategoryId, Long userId, Long zoneCategoryId) { + public Page getBriefInformationPageByParentCategoryFilterZoneCategoryLikeCount( + Pageable pageable, Long parentCategoryId, Long userId, Long zoneCategoryId) { if (!categoryRepository.existsById(parentCategoryId)) { throw new CategoryNotExistsException("해당하는 id의 category는 없습니다"); } @@ -353,10 +370,12 @@ public Page getBriefInformationPageByParentCategoryFil throw new ZoneCategoryNotExistsException("해당하는 id의 zoneCategory는 없습니다"); } - return informationRepository.getInformationByParentCategoryFilterZoneCategoryLikeCount(pageable, parentCategoryId, userId, zoneCategoryId); + return informationRepository.getInformationByParentCategoryFilterZoneCategoryLikeCount(pageable, + parentCategoryId, userId, zoneCategoryId); } - public Page getBriefInformationPageByChildCategoryFilterZoneCategoryLikeCount(Pageable pageable, Long childCategoryId, Long userId, Long zoneCategoryId) { + public Page getBriefInformationPageByChildCategoryFilterZoneCategoryLikeCount( + Pageable pageable, Long childCategoryId, Long userId, Long zoneCategoryId) { if (!categoryRepository.existsById(childCategoryId)) { throw new CategoryNotExistsException("해당하는 id의 category는 없습니다"); } @@ -364,11 +383,13 @@ public Page getBriefInformationPageByChildCategoryFilt throw new ZoneCategoryNotExistsException("해당하는 id의 zoneCategory는 없습니다"); } - return informationRepository.getInformationByChildCategoryFilterZoneCategoryLikeCount(pageable, childCategoryId, userId, zoneCategoryId); + return informationRepository.getInformationByChildCategoryFilterZoneCategoryLikeCount(pageable, childCategoryId, + userId, zoneCategoryId); } //지역카테고리별 조회순 - public Page getBriefInformationPageByParentCategoryFilterZoneCategoryViewCount(Pageable pageable, Long parentCategoryId, Long userId, Long zoneCategoryId) { + public Page getBriefInformationPageByParentCategoryFilterZoneCategoryViewCount( + Pageable pageable, Long parentCategoryId, Long userId, Long zoneCategoryId) { if (!categoryRepository.existsById(parentCategoryId)) { throw new CategoryNotExistsException("해당하는 id의 category는 없습니다"); } @@ -376,10 +397,12 @@ public Page getBriefInformationPageByParentCategoryFil throw new ZoneCategoryNotExistsException("해당하는 id의 zoneCategory는 없습니다"); } - return informationRepository.getInformationByParentCategoryFilterZoneCategoryViewCount(pageable, parentCategoryId, userId, zoneCategoryId); + return informationRepository.getInformationByParentCategoryFilterZoneCategoryViewCount(pageable, + parentCategoryId, userId, zoneCategoryId); } - public Page getBriefInformationPageByChildCategoryFilterZoneCategoryViewCount(Pageable pageable, Long childCategoryId, Long userId, Long zoneCategoryId) { + public Page getBriefInformationPageByChildCategoryFilterZoneCategoryViewCount( + Pageable pageable, Long childCategoryId, Long userId, Long zoneCategoryId) { if (!categoryRepository.existsById(childCategoryId)) { throw new CategoryNotExistsException("해당하는 id의 category는 없습니다"); } @@ -387,7 +410,8 @@ public Page getBriefInformationPageByChildCategoryFilt throw new ZoneCategoryNotExistsException("해당하는 id의 zoneCategory는 없습니다"); } - return informationRepository.getInformationByChildCategoryFilterZoneCategoryViewCount(pageable, childCategoryId, userId, zoneCategoryId); + return informationRepository.getInformationByChildCategoryFilterZoneCategoryViewCount(pageable, childCategoryId, + userId, zoneCategoryId); } public List getRankInformation() { diff --git a/src/main/java/solitour_backend/solitour/place/dto/request/PlaceModifyRequest.java b/src/main/java/solitour_backend/solitour/place/dto/request/PlaceModifyRequest.java index 1e2deb67..36c02f37 100644 --- a/src/main/java/solitour_backend/solitour/place/dto/request/PlaceModifyRequest.java +++ b/src/main/java/solitour_backend/solitour/place/dto/request/PlaceModifyRequest.java @@ -7,9 +7,7 @@ import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.Size; - import java.math.BigDecimal; - import lombok.Getter; import lombok.NoArgsConstructor; diff --git a/src/main/java/solitour_backend/solitour/place/dto/request/PlaceRegisterRequest.java b/src/main/java/solitour_backend/solitour/place/dto/request/PlaceRegisterRequest.java index 7b155282..ca9d4256 100644 --- a/src/main/java/solitour_backend/solitour/place/dto/request/PlaceRegisterRequest.java +++ b/src/main/java/solitour_backend/solitour/place/dto/request/PlaceRegisterRequest.java @@ -7,9 +7,7 @@ import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.Size; - import java.math.BigDecimal; - import lombok.AllArgsConstructor; import lombok.Getter; import lombok.NoArgsConstructor; diff --git a/src/main/java/solitour_backend/solitour/place/dto/response/PlaceResponse.java b/src/main/java/solitour_backend/solitour/place/dto/response/PlaceResponse.java index 3779914a..61e397a0 100644 --- a/src/main/java/solitour_backend/solitour/place/dto/response/PlaceResponse.java +++ b/src/main/java/solitour_backend/solitour/place/dto/response/PlaceResponse.java @@ -1,7 +1,6 @@ package solitour_backend.solitour.place.dto.response; import java.math.BigDecimal; - import lombok.AllArgsConstructor; import lombok.Getter; diff --git a/src/main/java/solitour_backend/solitour/place/entity/Place.java b/src/main/java/solitour_backend/solitour/place/entity/Place.java index 036196c0..8e54daa0 100644 --- a/src/main/java/solitour_backend/solitour/place/entity/Place.java +++ b/src/main/java/solitour_backend/solitour/place/entity/Place.java @@ -6,9 +6,7 @@ import jakarta.persistence.GenerationType; import jakarta.persistence.Id; import jakarta.persistence.Table; - import java.math.BigDecimal; - import lombok.AllArgsConstructor; import lombok.Getter; import lombok.NoArgsConstructor; diff --git a/src/main/java/solitour_backend/solitour/tag/dto/mapper/TagMapper.java b/src/main/java/solitour_backend/solitour/tag/dto/mapper/TagMapper.java index 3ab218ed..337e7a17 100644 --- a/src/main/java/solitour_backend/solitour/tag/dto/mapper/TagMapper.java +++ b/src/main/java/solitour_backend/solitour/tag/dto/mapper/TagMapper.java @@ -1,7 +1,6 @@ package solitour_backend.solitour.tag.dto.mapper; import java.util.List; - import org.mapstruct.Mapper; import org.mapstruct.Mapping; import org.mapstruct.ReportingPolicy; diff --git a/src/main/java/solitour_backend/solitour/user/controller/UserController.java b/src/main/java/solitour_backend/solitour/user/controller/UserController.java index 64b50691..4ad5cea9 100644 --- a/src/main/java/solitour_backend/solitour/user/controller/UserController.java +++ b/src/main/java/solitour_backend/solitour/user/controller/UserController.java @@ -1,11 +1,25 @@ package solitour_backend.solitour.user.controller; import lombok.RequiredArgsConstructor; +import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; +import solitour_backend.solitour.auth.config.Authenticated; import solitour_backend.solitour.auth.config.AuthenticationPrincipal; +import solitour_backend.solitour.auth.service.OauthService; +import solitour_backend.solitour.auth.service.TokenService; +import solitour_backend.solitour.auth.support.google.GoogleConnector; +import solitour_backend.solitour.auth.support.kakao.KakaoConnector; +import solitour_backend.solitour.user.dto.UpdateAgeAndSex; +import solitour_backend.solitour.user.dto.UpdateNicknameRequest; +import solitour_backend.solitour.user.exception.NicknameAlreadyExistsException; +import solitour_backend.solitour.user.exception.UserNotExistsException; import solitour_backend.solitour.user.service.UserService; import solitour_backend.solitour.user.service.dto.response.UserInfoResponse; @@ -14,14 +28,79 @@ @RequestMapping("/api/users") public class UserController { - private final UserService service; - + private final UserService userService; + private final OauthService oauthservice; + private final KakaoConnector kakaoConnector; + private final GoogleConnector googleConnector; + private final TokenService tokenService; + @Authenticated @GetMapping("/info") public ResponseEntity retrieveUserInfo(@AuthenticationPrincipal Long userId) { - UserInfoResponse response = service.retrieveUserInfo(userId); + UserInfoResponse response = userService.retrieveUserInfo(userId); return ResponseEntity.ok(response); } + @Authenticated + @PutMapping("/nickname") + public ResponseEntity updateNickname(@AuthenticationPrincipal Long userId, + @RequestBody UpdateNicknameRequest request) { + try { + userService.updateNickname(userId, request.nickname()); + return ResponseEntity.ok("Nickname updated successfully"); + } catch (UserNotExistsException e) { + return ResponseEntity.status(HttpStatus.NOT_FOUND).body("User not found"); + } catch (NicknameAlreadyExistsException e) { + return ResponseEntity.status(HttpStatus.CONFLICT).body("Nickname already exists"); + } catch (Exception e) { + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("An internal error occurred"); + } + } + + @Authenticated + @PutMapping("/age-sex") + public ResponseEntity updateAgeAndSex(@AuthenticationPrincipal Long userId, + @RequestBody UpdateAgeAndSex request) { + try { + userService.updateAgeAndSex(userId, request.age(), request.sex()); + return ResponseEntity.ok("Age and Sex updated successfully"); + } catch (UserNotExistsException e) { + return ResponseEntity.status(HttpStatus.NOT_FOUND).body("User not found"); + } catch (Exception e) { + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("An internal error occurred"); + } + } + + @Authenticated + @DeleteMapping() + public ResponseEntity deleteUser(@AuthenticationPrincipal Long id, @RequestParam String type, + @RequestParam String code, @RequestParam String redirectUrl) { + String token = getOauthAccessToken(type, code, redirectUrl); + + try { + oauthservice.revokeToken(type, token); + + oauthservice.logout(id); + userService.deleteUser(id); + + return ResponseEntity.ok("User deleted successfully"); + } catch (Exception e) { + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("An error occurred"); + } + } + + private String getOauthAccessToken(String type, String code, String redirectUrl) { + String token = ""; + switch (type) { + case "kakao" -> { + token = kakaoConnector.requestAccessToken(code, redirectUrl); + } + case "google" -> { + token = googleConnector.requestAccessToken(code, redirectUrl); + } + default -> throw new RuntimeException("Unsupported oauth type"); + } + return token; + } } diff --git a/src/main/java/solitour_backend/solitour/user/dto/UpdateAgeAndSex.java b/src/main/java/solitour_backend/solitour/user/dto/UpdateAgeAndSex.java new file mode 100644 index 00000000..d6269927 --- /dev/null +++ b/src/main/java/solitour_backend/solitour/user/dto/UpdateAgeAndSex.java @@ -0,0 +1,4 @@ +package solitour_backend.solitour.user.dto; + +public record UpdateAgeAndSex(String age, String sex) { +} diff --git a/src/main/java/solitour_backend/solitour/user/dto/UpdateNicknameRequest.java b/src/main/java/solitour_backend/solitour/user/dto/UpdateNicknameRequest.java new file mode 100644 index 00000000..26845597 --- /dev/null +++ b/src/main/java/solitour_backend/solitour/user/dto/UpdateNicknameRequest.java @@ -0,0 +1,4 @@ +package solitour_backend.solitour.user.dto; + +public record UpdateNicknameRequest(String nickname) { +} diff --git a/src/main/java/solitour_backend/solitour/user/entity/User.java b/src/main/java/solitour_backend/solitour/user/entity/User.java index df933ae4..ac16c20d 100644 --- a/src/main/java/solitour_backend/solitour/user/entity/User.java +++ b/src/main/java/solitour_backend/solitour/user/entity/User.java @@ -10,9 +10,7 @@ import jakarta.persistence.JoinColumn; import jakarta.persistence.OneToOne; import jakarta.persistence.Table; - import java.time.LocalDateTime; - import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Getter; @@ -77,4 +75,18 @@ public class User { @Column(name = "user_deleted_at") private LocalDateTime deletedAt; + + public void updateNickname(String nickname) { + this.nickname = nickname; + } + + public void updateAgeAndSex(String age, String sex) { + this.age = Integer.parseInt(age); + this.sex = sex; + } + + public void deleteUser(Long userId) { + this.userStatus = UserStatus.DELETE; + this.deletedAt = LocalDateTime.now(); + } } diff --git a/src/main/java/solitour_backend/solitour/user/entity/UserRepository.java b/src/main/java/solitour_backend/solitour/user/entity/UserRepository.java index cb890187..d60646e6 100644 --- a/src/main/java/solitour_backend/solitour/user/entity/UserRepository.java +++ b/src/main/java/solitour_backend/solitour/user/entity/UserRepository.java @@ -1,16 +1,19 @@ package solitour_backend.solitour.user.entity; import java.util.Optional; - import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; public interface UserRepository extends JpaRepository { + @Query("SELECT u FROM User u JOIN FETCH u.userImage WHERE u.nickname = :nickname AND u.userStatus = '활성화'") Optional findByNickname(String nickname); + @Query("SELECT u FROM User u JOIN FETCH u.userImage WHERE u.email = :email AND u.userStatus = '활성화'") Optional findByEmail(String email); - @Query("SELECT u FROM User u JOIN FETCH u.userImage WHERE u.id = :userId") + @Query("SELECT u FROM User u JOIN FETCH u.userImage WHERE u.id = :userId AND u.userStatus = '활성화'") User findByUserId(Long userId); + + boolean existsByNickname(String nickname); } diff --git a/src/main/java/solitour_backend/solitour/user/exception/NicknameAlreadyExistsException.java b/src/main/java/solitour_backend/solitour/user/exception/NicknameAlreadyExistsException.java new file mode 100644 index 00000000..b8742134 --- /dev/null +++ b/src/main/java/solitour_backend/solitour/user/exception/NicknameAlreadyExistsException.java @@ -0,0 +1,7 @@ +package solitour_backend.solitour.user.exception; + +public class NicknameAlreadyExistsException extends RuntimeException { + public NicknameAlreadyExistsException(String message) { + super(message); + } +} diff --git a/src/main/java/solitour_backend/solitour/user/service/UserService.java b/src/main/java/solitour_backend/solitour/user/service/UserService.java index 1047004e..38b84f52 100644 --- a/src/main/java/solitour_backend/solitour/user/service/UserService.java +++ b/src/main/java/solitour_backend/solitour/user/service/UserService.java @@ -5,6 +5,7 @@ import org.springframework.transaction.annotation.Transactional; import solitour_backend.solitour.user.entity.User; import solitour_backend.solitour.user.entity.UserRepository; +import solitour_backend.solitour.user.exception.NicknameAlreadyExistsException; import solitour_backend.solitour.user.service.dto.response.UserInfoResponse; @Service @@ -20,4 +21,25 @@ public UserInfoResponse retrieveUserInfo(Long userId) { return new UserInfoResponse(user); } + @Transactional + public void updateNickname(Long userId, String nickname) { + if (userRepository.existsByNickname(nickname)) { + throw new NicknameAlreadyExistsException("Nickname already exists"); + } + User user = userRepository.findByUserId(userId); + user.updateNickname(nickname); + } + + @Transactional + public void updateAgeAndSex(Long userId, String age, String sex) { + User user = userRepository.findByUserId(userId); + user.updateAgeAndSex(age, sex); + } + + + @Transactional + public void deleteUser(Long userId) { + User user = userRepository.findByUserId(userId); + user.deleteUser(userId); + } } diff --git a/src/main/java/solitour_backend/solitour/user/user_status/UserStatus.java b/src/main/java/solitour_backend/solitour/user/user_status/UserStatus.java index 5b57113a..957a8cb3 100644 --- a/src/main/java/solitour_backend/solitour/user/user_status/UserStatus.java +++ b/src/main/java/solitour_backend/solitour/user/user_status/UserStatus.java @@ -1,7 +1,6 @@ package solitour_backend.solitour.user.user_status; import java.util.Arrays; - import lombok.Getter; @Getter diff --git a/src/main/java/solitour_backend/solitour/user_image/entity/UserImage.java b/src/main/java/solitour_backend/solitour/user_image/entity/UserImage.java index 6bd5b15f..62062a56 100644 --- a/src/main/java/solitour_backend/solitour/user_image/entity/UserImage.java +++ b/src/main/java/solitour_backend/solitour/user_image/entity/UserImage.java @@ -6,9 +6,7 @@ import jakarta.persistence.GenerationType; import jakarta.persistence.Id; import jakarta.persistence.Table; - import java.time.LocalDate; - import lombok.Getter; import lombok.NoArgsConstructor; diff --git a/src/main/java/solitour_backend/solitour/user_image/service/UserImageService.java b/src/main/java/solitour_backend/solitour/user_image/service/UserImageService.java index 8af2cbca..a8de5fc2 100644 --- a/src/main/java/solitour_backend/solitour/user_image/service/UserImageService.java +++ b/src/main/java/solitour_backend/solitour/user_image/service/UserImageService.java @@ -1,7 +1,6 @@ package solitour_backend.solitour.user_image.service; import java.time.LocalDate; - import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; diff --git a/src/main/java/solitour_backend/solitour/util/TimeUtil.java b/src/main/java/solitour_backend/solitour/util/TimeUtil.java index 9ecf8b03..f5a41d01 100644 --- a/src/main/java/solitour_backend/solitour/util/TimeUtil.java +++ b/src/main/java/solitour_backend/solitour/util/TimeUtil.java @@ -1,11 +1,10 @@ package solitour_backend.solitour.util; -import org.springframework.stereotype.Component; - import java.time.Duration; import java.time.LocalTime; import java.time.ZoneId; import java.time.ZonedDateTime; +import org.springframework.stereotype.Component; @Component public class TimeUtil { diff --git a/src/main/java/solitour_backend/solitour/zone_category/controller/ZoneCategoryController.java b/src/main/java/solitour_backend/solitour/zone_category/controller/ZoneCategoryController.java index d6af5d19..fd0f1112 100644 --- a/src/main/java/solitour_backend/solitour/zone_category/controller/ZoneCategoryController.java +++ b/src/main/java/solitour_backend/solitour/zone_category/controller/ZoneCategoryController.java @@ -37,8 +37,9 @@ public ResponseEntity getZoneCategory(@PathVariable Long i } @PostMapping - public ResponseEntity registerZoneCategory(@Valid @RequestBody ZoneCategoryRegisterRequest zoneCategoryRegisterRequest, - BindingResult bindingResult) { + public ResponseEntity registerZoneCategory( + @Valid @RequestBody ZoneCategoryRegisterRequest zoneCategoryRegisterRequest, + BindingResult bindingResult) { if (bindingResult.hasErrors()) { throw new RequestValidationFailedException(bindingResult); } diff --git a/src/main/java/solitour_backend/solitour/zone_category/repository/ZoneCategoryRepository.java b/src/main/java/solitour_backend/solitour/zone_category/repository/ZoneCategoryRepository.java index ef854ddf..24e599c7 100644 --- a/src/main/java/solitour_backend/solitour/zone_category/repository/ZoneCategoryRepository.java +++ b/src/main/java/solitour_backend/solitour/zone_category/repository/ZoneCategoryRepository.java @@ -1,7 +1,6 @@ package solitour_backend.solitour.zone_category.repository; import java.util.Optional; - import org.springframework.data.jpa.repository.JpaRepository; import solitour_backend.solitour.zone_category.entity.ZoneCategory; diff --git a/src/main/java/solitour_backend/solitour/zone_category/service/ZoneCategoryService.java b/src/main/java/solitour_backend/solitour/zone_category/service/ZoneCategoryService.java index 5da296c9..4f808ab1 100644 --- a/src/main/java/solitour_backend/solitour/zone_category/service/ZoneCategoryService.java +++ b/src/main/java/solitour_backend/solitour/zone_category/service/ZoneCategoryService.java @@ -1,7 +1,6 @@ package solitour_backend.solitour.zone_category.service; import java.util.Objects; - import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; From 28e23ce67f51ac368a9926768035022e9ff6daed Mon Sep 17 00:00:00 2001 From: "SK\\ssssk" Date: Sun, 11 Aug 2024 10:57:12 +0900 Subject: [PATCH 099/371] =?UTF-8?q?fix:=20cookies=EA=B0=80=20=EB=B9=88=20?= =?UTF-8?q?=EB=B0=B0=EC=97=B4=EC=9D=B4=20=EC=95=84=EB=8B=8C=20null=20?= =?UTF-8?q?=EC=9D=B8=20=EA=B2=BD=EC=9A=B0=20null=EB=A1=9C=20=EC=B2=98?= =?UTF-8?q?=EB=A6=AC=ED=95=98=EA=B8=B0=20=EC=9C=84=ED=95=B4=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 --- .../solitour/auth/support/CookieExtractor.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/solitour_backend/solitour/auth/support/CookieExtractor.java b/src/main/java/solitour_backend/solitour/auth/support/CookieExtractor.java index 4dfced91..3f1ad865 100644 --- a/src/main/java/solitour_backend/solitour/auth/support/CookieExtractor.java +++ b/src/main/java/solitour_backend/solitour/auth/support/CookieExtractor.java @@ -6,6 +6,9 @@ public class CookieExtractor { public static String findToken(String token, Cookie[] cookies) { String value = null; + if(cookies == null) { + return null; + } for (Cookie cookie : cookies) { if (token.equals(cookie.getName())) { value = cookie.getValue(); @@ -14,5 +17,4 @@ public static String findToken(String token, Cookie[] cookies) { } return value; } - } From 207453b23e43c6b474e2937d31f1099b875a721f Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Tue, 13 Aug 2024 00:57:48 +0900 Subject: [PATCH 100/371] =?UTF-8?q?feat:=20=EC=A2=8B=EC=95=84=EC=9A=94=20?= =?UTF-8?q?=EC=97=AC=EB=B6=80=20=ED=95=84=EB=93=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../solitour/gathering/dto/response/GatheringBriefResponse.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/solitour_backend/solitour/gathering/dto/response/GatheringBriefResponse.java b/src/main/java/solitour_backend/solitour/gathering/dto/response/GatheringBriefResponse.java index 00c5c788..1f9f942f 100644 --- a/src/main/java/solitour_backend/solitour/gathering/dto/response/GatheringBriefResponse.java +++ b/src/main/java/solitour_backend/solitour/gathering/dto/response/GatheringBriefResponse.java @@ -30,6 +30,7 @@ public class GatheringBriefResponse { private Integer endAge; private Integer personCount; private Integer nowPersonCount; + private Boolean isLike; } From fe4a473bd3de558c558a65eca3470cdc6bdb741b Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Tue, 13 Aug 2024 00:58:00 +0900 Subject: [PATCH 101/371] =?UTF-8?q?feat:=20=EC=A2=8B=EC=95=84=EC=9A=94=20?= =?UTF-8?q?=EC=97=AC=EB=B6=80=20=ED=95=84=EB=93=9C=20=EC=B6=94=EA=B0=80?= =?UTF-8?q?=EB=A1=9C=20=EC=9D=B8=ED=95=9C=20=EC=BF=BC=EB=A6=AC=EB=AC=B8=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../repository/GatheringRepositoryImpl.java | 22 +++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryImpl.java b/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryImpl.java index aa0d74a8..64206531 100644 --- a/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryImpl.java +++ b/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryImpl.java @@ -1,7 +1,11 @@ package solitour_backend.solitour.gathering.repository; import com.querydsl.core.types.Projections; + import java.util.List; + +import com.querydsl.core.types.dsl.CaseBuilder; +import com.querydsl.jpa.JPAExpressions; import org.springframework.data.jpa.repository.support.QuerydslRepositorySupport; import solitour_backend.solitour.book_mark_gathering.entity.QBookMarkGathering; import solitour_backend.solitour.gathering.dto.response.GatheringBriefResponse; @@ -29,6 +33,8 @@ public GatheringRepositoryImpl() { @Override public List getGatheringRecommend(Long gatheringId, Long gatheringCategoryId, Long userId) { + QGreatGathering greatGatheringSub = new QGreatGathering("greatGatheringSub"); + return from(gathering) .join(zoneCategoryChild).on(zoneCategoryChild.id.eq(gathering.zoneCategory.id)) .leftJoin(zoneCategoryParent).on(zoneCategoryParent.id.eq(zoneCategoryChild.parentZoneCategory.id)) @@ -43,7 +49,11 @@ public List getGatheringRecommend(Long gatheringId, Long .and(gatheringApplicants.gatheringStatus.eq(GatheringStatus.CONSENT) .or(gatheringApplicants.gatheringStatus.isNull())) ) - .groupBy(gathering.id, zoneCategoryChild.id, zoneCategoryParent.id, category.id) + .groupBy(gathering.id, zoneCategoryChild.id, zoneCategoryParent.id, category.id, + gathering.title, gathering.viewCount, gathering.user.name, + gathering.scheduleStartDate, gathering.scheduleEndDate, + gathering.deadline, gathering.allowedSex, + gathering.startAge, gathering.endAge, gathering.personCount) .orderBy(gathering.createdAt.desc()) .select(Projections.constructor( GatheringBriefResponse.class, @@ -63,7 +73,15 @@ public List getGatheringRecommend(Long gatheringId, Long gathering.startAge, gathering.endAge, gathering.personCount, - gatheringApplicants.count().coalesce(0L).intValue() + gatheringApplicants.count().coalesce(0L).intValue(), + new CaseBuilder() + .when(JPAExpressions.selectOne() + .from(greatGatheringSub) + .where(greatGatheringSub.gathering.id.eq(gathering.id) + .and(greatGatheringSub.user.id.eq(userId))) + .exists()) + .then(true) + .otherwise(false) )).limit(3L).fetch(); } From b48cd47ed4ff48017ae4d9d83cd07aa751187e5b Mon Sep 17 00:00:00 2001 From: Donghun Won Date: Thu, 15 Aug 2024 19:50:55 +0900 Subject: [PATCH 102/371] =?UTF-8?q?=20Feat(77):=20=EC=97=91=EC=84=B8?= =?UTF-8?q?=EC=8A=A4=20=ED=86=A0=ED=81=B0=20=EA=B8=B0=EA=B0=84=20=EC=97=B0?= =?UTF-8?q?=EC=9E=A5=20=EB=B0=8F=20=EB=A1=9C=EA=B7=B8=EC=95=84=EC=9B=83=20?= =?UTF-8?q?=EC=8B=9C=20=EC=BF=A0=ED=82=A4=20=EC=82=AD=EC=A0=9C=20=20(#78)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Feat : 엑세스 토큰 기간 연장, 로그아웃 시 쿠키 삭제 * Style : 코드 포맷팅 --- .../auth/controller/OauthController.java | 4 ++-- .../solitour/auth/service/OauthService.java | 16 +++++++++++++--- .../solitour/auth/support/CookieExtractor.java | 2 +- .../solitour/user/controller/UserController.java | 6 ++++-- 4 files changed, 20 insertions(+), 8 deletions(-) diff --git a/src/main/java/solitour_backend/solitour/auth/controller/OauthController.java b/src/main/java/solitour_backend/solitour/auth/controller/OauthController.java index fbc48ea3..a55d1119 100644 --- a/src/main/java/solitour_backend/solitour/auth/controller/OauthController.java +++ b/src/main/java/solitour_backend/solitour/auth/controller/OauthController.java @@ -46,8 +46,8 @@ public ResponseEntity login(HttpServletResponse response, @Reques } @PostMapping("/logout") - public ResponseEntity logout(@AuthenticationPrincipal Long memberId) { - oauthService.logout(memberId); + public ResponseEntity logout(HttpServletResponse response, @AuthenticationPrincipal Long memberId) { + oauthService.logout(response, memberId); return ResponseEntity.ok().build(); } diff --git a/src/main/java/solitour_backend/solitour/auth/service/OauthService.java b/src/main/java/solitour_backend/solitour/auth/service/OauthService.java index 9c2ad915..0bb75d06 100644 --- a/src/main/java/solitour_backend/solitour/auth/service/OauthService.java +++ b/src/main/java/solitour_backend/solitour/auth/service/OauthService.java @@ -2,6 +2,7 @@ import jakarta.servlet.http.Cookie; +import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; import java.time.LocalDateTime; import java.util.Objects; @@ -51,7 +52,7 @@ public OauthLinkResponse generateAuthUrl(String type, String redirectUrl) { @Transactional public LoginResponse requestAccessToken(String type, String code, String redirectUrl) { User user = checkAndSaveUser(type, code, redirectUrl); - final int ACCESS_COOKIE_AGE = (int) TimeUnit.MINUTES.toSeconds(15); + final int ACCESS_COOKIE_AGE = (int) TimeUnit.MINUTES.toSeconds(30); final int REFRESH_COOKIE_AGE = (int) TimeUnit.DAYS.toSeconds(30); String token = jwtTokenProvider.createAccessToken(user.getId()); @@ -165,7 +166,7 @@ private String getAuthLink(String type, String redirectUrl) { public AccessTokenResponse reissueAccessToken(Long userId) { boolean isExistMember = userRepository.existsById(userId); - int ACCESS_COOKIE_AGE = (int) TimeUnit.MINUTES.toSeconds(15); + int ACCESS_COOKIE_AGE = (int) TimeUnit.MINUTES.toSeconds(30); if (!isExistMember) { throw new RuntimeException("유효하지 않은 토큰입니다."); } @@ -176,8 +177,17 @@ public AccessTokenResponse reissueAccessToken(Long userId) { } @Transactional - public void logout(Long userId) { + public void logout(HttpServletResponse response, Long userId) { tokenService.deleteByMemberId(userId); + deleteCookie("access_token", "", response); + deleteCookie("refresh_token", "", response); + } + + private void deleteCookie(String name, String value, HttpServletResponse response) { + Cookie cookie = new Cookie(name, value); + cookie.setMaxAge(0); + cookie.setPath("/"); + response.addCookie(cookie); } public void revokeToken(String type, String token) throws IOException { diff --git a/src/main/java/solitour_backend/solitour/auth/support/CookieExtractor.java b/src/main/java/solitour_backend/solitour/auth/support/CookieExtractor.java index 3f1ad865..912a4df5 100644 --- a/src/main/java/solitour_backend/solitour/auth/support/CookieExtractor.java +++ b/src/main/java/solitour_backend/solitour/auth/support/CookieExtractor.java @@ -6,7 +6,7 @@ public class CookieExtractor { public static String findToken(String token, Cookie[] cookies) { String value = null; - if(cookies == null) { + if (cookies == null) { return null; } for (Cookie cookie : cookies) { diff --git a/src/main/java/solitour_backend/solitour/user/controller/UserController.java b/src/main/java/solitour_backend/solitour/user/controller/UserController.java index 4ad5cea9..496c5bd9 100644 --- a/src/main/java/solitour_backend/solitour/user/controller/UserController.java +++ b/src/main/java/solitour_backend/solitour/user/controller/UserController.java @@ -1,5 +1,6 @@ package solitour_backend.solitour.user.controller; +import jakarta.servlet.http.HttpServletResponse; import lombok.RequiredArgsConstructor; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -74,14 +75,15 @@ public ResponseEntity updateAgeAndSex(@AuthenticationPrincipal Long user @Authenticated @DeleteMapping() - public ResponseEntity deleteUser(@AuthenticationPrincipal Long id, @RequestParam String type, + public ResponseEntity deleteUser(HttpServletResponse response, @AuthenticationPrincipal Long id, + @RequestParam String type, @RequestParam String code, @RequestParam String redirectUrl) { String token = getOauthAccessToken(type, code, redirectUrl); try { oauthservice.revokeToken(type, token); - oauthservice.logout(id); + oauthservice.logout(response, id); userService.deleteUser(id); return ResponseEntity.ok("User deleted successfully"); From 77c88ccf9d16b701b4fad6d6bd2aad87771c2f34 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Sat, 17 Aug 2024 23:01:23 +0900 Subject: [PATCH 103/371] =?UTF-8?q?feat:=20gathering=20page=20=EC=9A=94?= =?UTF-8?q?=EC=B2=AD=20dto?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dto/request/GatheringPageRequest.java | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 src/main/java/solitour_backend/solitour/gathering/dto/request/GatheringPageRequest.java diff --git a/src/main/java/solitour_backend/solitour/gathering/dto/request/GatheringPageRequest.java b/src/main/java/solitour_backend/solitour/gathering/dto/request/GatheringPageRequest.java new file mode 100644 index 00000000..2f17be2e --- /dev/null +++ b/src/main/java/solitour_backend/solitour/gathering/dto/request/GatheringPageRequest.java @@ -0,0 +1,44 @@ +package solitour_backend.solitour.gathering.dto.request; + +import com.fasterxml.jackson.annotation.JsonFormat; +import jakarta.validation.constraints.Min; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import org.springframework.format.annotation.DateTimeFormat; +import solitour_backend.solitour.gathering.entity.AllowedSex; + +import java.time.LocalDate; + +@Getter +@Setter +@AllArgsConstructor +@NoArgsConstructor +public class GatheringPageRequest { + private Boolean isExclude; + + @Min(1) + private Long category; + + @Min(1) + private Long location; + + private AllowedSex allowedSex; + + @Min(20) + private Integer startAge; + + @Min(20) + private Integer endAge; + + private String sort; + + @JsonFormat(pattern = "yyyy-MM-dd") + @DateTimeFormat(pattern = "yyyy-MM-dd") + private LocalDate startDate; + + @JsonFormat(pattern = "yyyy-MM-dd") + @DateTimeFormat(pattern = "yyyy-MM-dd") + private LocalDate endDate; +} From 8f883e646b6b5715677c82ff26b7e9e433316f6c Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Sat, 17 Aug 2024 23:21:52 +0900 Subject: [PATCH 104/371] feat: GatheringCategory Response dto --- .../dto/response/GatheringCategoryResponse.java | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 src/main/java/solitour_backend/solitour/gathering_category/dto/response/GatheringCategoryResponse.java diff --git a/src/main/java/solitour_backend/solitour/gathering_category/dto/response/GatheringCategoryResponse.java b/src/main/java/solitour_backend/solitour/gathering_category/dto/response/GatheringCategoryResponse.java new file mode 100644 index 00000000..9f882cb2 --- /dev/null +++ b/src/main/java/solitour_backend/solitour/gathering_category/dto/response/GatheringCategoryResponse.java @@ -0,0 +1,11 @@ +package solitour_backend.solitour.gathering_category.dto.response; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor +public class GatheringCategoryResponse { + private Long id; + private String name; +} From 60d065c9986fa48b75090d84d2396dfe60e3e976 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Sat, 17 Aug 2024 23:22:46 +0900 Subject: [PATCH 105/371] =?UTF-8?q?feat:=20=EB=AA=A8=EC=9E=84=20=ED=8E=98?= =?UTF-8?q?=EC=9D=B4=EC=A7=80=EB=84=A4=EC=9D=B4=EC=85=98=20=EB=A9=94?= =?UTF-8?q?=EC=84=9C=EB=93=9C=20=EC=84=A0=EC=96=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../repository/GatheringRepositoryCustom.java | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryCustom.java b/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryCustom.java index 2f66d69c..55c32407 100644 --- a/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryCustom.java +++ b/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryCustom.java @@ -1,10 +1,20 @@ package solitour_backend.solitour.gathering.repository; import java.util.List; + +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; import org.springframework.data.repository.NoRepositoryBean; +import solitour_backend.solitour.gathering.dto.request.GatheringPageRequest; import solitour_backend.solitour.gathering.dto.response.GatheringBriefResponse; @NoRepositoryBean public interface GatheringRepositoryCustom { + String LIKE_COUNT_SORT = "likes"; + String VIEW_COUNT_SORT = "views"; + List getGatheringRecommend(Long informationId, Long gatheringCategoryId, Long userId); + + Page getGatheringPageFilterAndOrder(Pageable pageable, GatheringPageRequest gatheringPageRequest, Long userId); + } From b6b61794fc4c0afb3c7d4f3aab2913f9f0490ad3 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Sat, 17 Aug 2024 23:23:00 +0900 Subject: [PATCH 106/371] =?UTF-8?q?feat:=20=EB=AA=A8=EC=9E=84=20=ED=8E=98?= =?UTF-8?q?=EC=9D=B4=EC=A7=80=EB=84=A4=EC=9D=B4=EC=85=98=20=ED=95=84?= =?UTF-8?q?=ED=84=B0=EB=A7=81=20=EB=B0=8F=20=EC=A0=95=EB=A0=AC=20=EA=B5=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../repository/GatheringRepositoryImpl.java | 139 +++++++++++++++++- 1 file changed, 137 insertions(+), 2 deletions(-) diff --git a/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryImpl.java b/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryImpl.java index 64206531..f5e14d98 100644 --- a/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryImpl.java +++ b/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryImpl.java @@ -1,13 +1,24 @@ package solitour_backend.solitour.gathering.repository; +import com.querydsl.core.BooleanBuilder; +import com.querydsl.core.types.OrderSpecifier; import com.querydsl.core.types.Projections; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.LocalTime; import java.util.List; +import java.util.Objects; -import com.querydsl.core.types.dsl.CaseBuilder; +import com.querydsl.core.types.dsl.*; import com.querydsl.jpa.JPAExpressions; +import com.querydsl.jpa.JPQLQuery; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageImpl; +import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.support.QuerydslRepositorySupport; import solitour_backend.solitour.book_mark_gathering.entity.QBookMarkGathering; +import solitour_backend.solitour.gathering.dto.request.GatheringPageRequest; import solitour_backend.solitour.gathering.dto.response.GatheringBriefResponse; import solitour_backend.solitour.gathering.entity.Gathering; import solitour_backend.solitour.gathering.entity.QGathering; @@ -22,6 +33,8 @@ public GatheringRepositoryImpl() { super(Gathering.class); } + + QGathering gathering = QGathering.gathering; QZoneCategory zoneCategoryChild = QZoneCategory.zoneCategory; QZoneCategory zoneCategoryParent = new QZoneCategory("zoneCategoryParent"); @@ -63,7 +76,7 @@ public List getGatheringRecommend(Long gatheringId, Long zoneCategoryChild.name, gathering.viewCount, bookMarkGathering.user.id.isNotNull(), - greatGathering.gathering.count().coalesce(0L).intValue(), + countGreatGatheringByGatheringById(), category.name, gathering.user.name, gathering.scheduleStartDate, @@ -86,4 +99,126 @@ public List getGatheringRecommend(Long gatheringId, Long } + @Override + public Page getGatheringPageFilterAndOrder(Pageable pageable, GatheringPageRequest gatheringPageRequest, Long userId) { + BooleanBuilder booleanBuilder = makeWhereSQL(gatheringPageRequest); + + OrderSpecifier orderSpecifier = getOrderSpecifier(gatheringPageRequest.getSort()); + + NumberExpression countGreatGathering = countGreatGatheringByGatheringById(); + + List content = from(gathering) + .join(zoneCategoryChild).on(zoneCategoryChild.id.eq(gathering.zoneCategory.id)) + .leftJoin(zoneCategoryParent).on(zoneCategoryParent.id.eq(zoneCategoryChild.parentZoneCategory.id)) + .leftJoin(bookMarkGathering).on(bookMarkGathering.gathering.id.eq(gathering.id).and(bookMarkGathering.user.id.eq(userId))) + .leftJoin(greatGathering).on(greatGathering.gathering.id.eq(gathering.id).and(greatGathering.isDeleted.isFalse())) + .leftJoin(gatheringApplicants).on(gatheringApplicants.gathering.id.eq(gathering.id)) + .where(booleanBuilder) + .groupBy(gathering.id, zoneCategoryChild.id, zoneCategoryParent.id, category.id, + gathering.title, gathering.viewCount, gathering.user.name, + gathering.scheduleStartDate, gathering.scheduleEndDate, + gathering.deadline, gathering.allowedSex, + gathering.startAge, gathering.endAge, gathering.personCount) + .orderBy(orderSpecifier) + .select(Projections.constructor( + GatheringBriefResponse.class, + gathering.id, + gathering.title, + zoneCategoryParent.name, + zoneCategoryChild.name, + gathering.viewCount, + bookMarkGathering.user.id.isNotNull(), + countGreatGathering, + gathering.gatheringCategory.name, + gathering.user.name, + gathering.scheduleStartDate, + gathering.scheduleEndDate, + gathering.deadline, + gathering.allowedSex, + gathering.startAge, + gathering.endAge, + gathering.personCount, + gatheringApplicants.count().coalesce(0L).intValue(), + new CaseBuilder() + .when(JPAExpressions.selectOne() + .from(greatGathering) + .where(greatGathering.gathering.id.eq(gathering.id) + .and(greatGathering.user.id.eq(userId))) + .exists()) + .then(true) + .otherwise(false) + )).offset(pageable.getOffset()) + .limit(pageable.getPageSize()) + .fetch(); + + long total = content.size(); + + return new PageImpl<>(content, pageable, total); + } + + //where 절 + private BooleanBuilder makeWhereSQL(GatheringPageRequest gatheringPageRequest) { + BooleanBuilder whereClause = new BooleanBuilder(); + + if (Objects.nonNull(gatheringPageRequest.getCategory())) { + whereClause.and(gathering.gatheringCategory.id.eq(gatheringPageRequest.getCategory())); + } + + if (Objects.nonNull(gatheringPageRequest.getLocation())) { + whereClause.and(gathering.zoneCategory.parentZoneCategory.id.eq(gatheringPageRequest.getLocation())); + } + + if (Objects.nonNull(gatheringPageRequest.getAllowedSex())) { + whereClause.and(gathering.allowedSex.eq(gatheringPageRequest.getAllowedSex())); + } + int currentYear = LocalDate.now().getYear(); + + if (Objects.nonNull(gatheringPageRequest.getStartAge()) && Objects.nonNull(gatheringPageRequest.getEndAge())) { + int userMinBirthYear = currentYear - gatheringPageRequest.getEndAge() + 1; + int userMaxBirthYear = currentYear - gatheringPageRequest.getStartAge() + 1; + + whereClause.and(gathering.startAge.goe(userMaxBirthYear)).and(gathering.endAge.loe(userMinBirthYear)); + } + + if (Objects.nonNull(gatheringPageRequest.getStartDate()) && Objects.nonNull(gatheringPageRequest.getEndDate())) { + whereClause.and(gathering.scheduleStartDate.goe(gatheringPageRequest.getStartDate().atStartOfDay())) + .and(gathering.scheduleEndDate.loe(gatheringPageRequest.getEndDate().atTime(LocalTime.MAX))); + } + + if (Objects.nonNull(gatheringPageRequest.getIsExclude())) { + whereClause.and(gathering.isFinish.eq(gatheringPageRequest.getIsExclude())); + } + + return whereClause; + } + + // 정렬 방식 + private OrderSpecifier getOrderSpecifier(String sort) { + PathBuilder entityPath = new PathBuilder<>(Gathering.class, "gathering"); + + if (Objects.nonNull(sort)) { + if (LIKE_COUNT_SORT.equalsIgnoreCase(sort)) { + return countGreatGatheringByGatheringById().desc(); + } else if (VIEW_COUNT_SORT.equalsIgnoreCase(sort)) { + return entityPath.getNumber("viewCount", Integer.class).desc(); + } + } + + return entityPath.getDateTime("createdAt", LocalDateTime.class).desc(); + } + + // 좋아요 수 가져오는 식 + private NumberExpression countGreatGatheringByGatheringById() { + QGreatGathering greatGatheringSub = QGreatGathering.greatGathering; + JPQLQuery likeCountSubQuery = JPAExpressions + .select(greatGatheringSub.count()) + .from(greatGatheringSub) + .where(greatGatheringSub.gathering.id.eq(gathering.id) + .and(greatGatheringSub.isDeleted.isFalse())); + return Expressions.numberTemplate(Long.class, "{0}", likeCountSubQuery) + .coalesce(0L) + .intValue(); + } + + } From 7de3c3154228f3aebc5504f12d24423ea9a990e2 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Sat, 17 Aug 2024 23:23:23 +0900 Subject: [PATCH 107/371] =?UTF-8?q?feat:=20=EB=AA=A8=EC=9E=84=20=ED=8E=98?= =?UTF-8?q?=EC=9D=B4=EC=A7=80=EB=84=A4=EC=9D=B4=EC=85=98=20=ED=95=84?= =?UTF-8?q?=ED=84=B0=EB=A7=81=20=EB=B0=8F=20=EC=A0=95=EB=A0=AC=20service?= =?UTF-8?q?=20=EB=B0=8F=20request=20dto=20validation?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../gathering/service/GatheringService.java | 61 ++++++++++++++++--- 1 file changed, 51 insertions(+), 10 deletions(-) diff --git a/src/main/java/solitour_backend/solitour/gathering/service/GatheringService.java b/src/main/java/solitour_backend/solitour/gathering/service/GatheringService.java index 1ca3ede8..887f54a3 100644 --- a/src/main/java/solitour_backend/solitour/gathering/service/GatheringService.java +++ b/src/main/java/solitour_backend/solitour/gathering/service/GatheringService.java @@ -3,11 +3,16 @@ import java.util.ArrayList; import java.util.List; import java.util.Objects; + import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import solitour_backend.solitour.error.exception.RequestValidationFailedException; import solitour_backend.solitour.gathering.dto.mapper.GatheringMapper; import solitour_backend.solitour.gathering.dto.request.GatheringModifyRequest; +import solitour_backend.solitour.gathering.dto.request.GatheringPageRequest; import solitour_backend.solitour.gathering.dto.request.GatheringRegisterRequest; import solitour_backend.solitour.gathering.dto.response.GatheringBriefResponse; import solitour_backend.solitour.gathering.dto.response.GatheringDetailResponse; @@ -47,6 +52,10 @@ import solitour_backend.solitour.zone_category.exception.ZoneCategoryNotExistsException; import solitour_backend.solitour.zone_category.repository.ZoneCategoryRepository; +import static solitour_backend.solitour.gathering.repository.GatheringRepositoryCustom.LIKE_COUNT_SORT; +import static solitour_backend.solitour.gathering.repository.GatheringRepositoryCustom.VIEW_COUNT_SORT; + + @Service @Transactional(readOnly = true) @RequiredArgsConstructor @@ -67,6 +76,7 @@ public class GatheringService { private final GatheringApplicantsRepository gatheringApplicantsRepository; private final GatheringApplicantsMapper gatheringApplicantsMapper; + public GatheringDetailResponse getGatheringDetail(Long userId, Long gatheringId) { Gathering gathering = gatheringRepository.findById(gatheringId) .orElseThrow( @@ -245,21 +255,52 @@ public GatheringResponse modifyGathering(Long userId, Long gatheringId, return gatheringMapper.mapToGatheringResponse(gathering); } + public Page getPageGathering(Pageable pageable, GatheringPageRequest gatheringPageRequest, Long userId) { + validateGatheringPageRequest(gatheringPageRequest); -} - - - - - - - - - + return gatheringRepository.getGatheringPageFilterAndOrder(pageable, gatheringPageRequest, userId); + } + private void validateGatheringPageRequest(GatheringPageRequest gatheringPageRequest) { + // Category 검증 + if (Objects.nonNull(gatheringPageRequest.getCategory())) { + if (!gatheringCategoryRepository.existsById(gatheringPageRequest.getCategory())) { + throw new GatheringCategoryNotExistsException("해당하는 모임 카테고리가 없습니다."); + } + } + // Location 검증 + if (Objects.nonNull(gatheringPageRequest.getLocation())) { + if (!zoneCategoryRepository.existsById(gatheringPageRequest.getLocation())) { + throw new ZoneCategoryNotExistsException("해당하는 지역 카테고리가 없습니다."); + } + } + // 나이 범위 검증 + if (Objects.nonNull(gatheringPageRequest.getStartAge()) && Objects.nonNull(gatheringPageRequest.getEndAge())) { + if (gatheringPageRequest.getStartAge() > gatheringPageRequest.getEndAge()) { + throw new RequestValidationFailedException("시작 나이가 끝 나이보다 클 수 없습니다."); + } + } else if (Objects.nonNull(gatheringPageRequest.getStartAge()) || Objects.nonNull(gatheringPageRequest.getEndAge())) { + throw new RequestValidationFailedException("시작 나이와 끝 나이는 둘 다 입력되거나 둘 다 비어 있어야 합니다."); + } + // 정렬 방식 검증 + if (Objects.nonNull(gatheringPageRequest.getSort())) { + if (!LIKE_COUNT_SORT.equals(gatheringPageRequest.getSort()) && !VIEW_COUNT_SORT.equals(gatheringPageRequest.getSort())) { + throw new RequestValidationFailedException("잘못된 정렬 코드입니다."); + } + } + // 날짜 검증 + if (Objects.nonNull(gatheringPageRequest.getStartDate()) && Objects.nonNull(gatheringPageRequest.getEndDate())) { + if (gatheringPageRequest.getStartDate().isAfter(gatheringPageRequest.getEndDate())) { + throw new RequestValidationFailedException("시작 날짜가 종료 날짜보다 나중일 수 없습니다."); + } + } else if (Objects.nonNull(gatheringPageRequest.getStartDate()) || Objects.nonNull(gatheringPageRequest.getEndDate())) { + throw new RequestValidationFailedException("시작 날짜와 종료 날짜는 둘 다 입력되거나 둘 다 비어 있어야 합니다."); + } + } +} \ No newline at end of file From 259f45fcabf6a4a093645137ca0f47141fc4a89c Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Sat, 17 Aug 2024 23:23:36 +0900 Subject: [PATCH 108/371] =?UTF-8?q?feat:=20=EB=AA=A8=EC=9E=84=20=ED=8E=98?= =?UTF-8?q?=EC=9D=B4=EC=A7=80=EB=84=A4=EC=9D=B4=EC=85=98=20=ED=95=84?= =?UTF-8?q?=ED=84=B0=EB=A7=81=20=EB=B0=8F=20=EC=A0=95=EB=A0=AC=20controlle?= =?UTF-8?q?r?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/GatheringController.java | 35 +++++++++++++++---- 1 file changed, 28 insertions(+), 7 deletions(-) diff --git a/src/main/java/solitour_backend/solitour/gathering/controller/GatheringController.java b/src/main/java/solitour_backend/solitour/gathering/controller/GatheringController.java index 5f75bd2d..4ff38052 100644 --- a/src/main/java/solitour_backend/solitour/gathering/controller/GatheringController.java +++ b/src/main/java/solitour_backend/solitour/gathering/controller/GatheringController.java @@ -2,30 +2,33 @@ import jakarta.servlet.http.HttpServletRequest; import jakarta.validation.Valid; + import java.time.LocalDateTime; import java.util.Objects; + import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.validation.BindingResult; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.PutMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; import solitour_backend.solitour.auth.config.AuthenticationPrincipal; import solitour_backend.solitour.auth.support.CookieExtractor; import solitour_backend.solitour.auth.support.JwtTokenProvider; import solitour_backend.solitour.error.Utils; import solitour_backend.solitour.error.exception.RequestValidationFailedException; import solitour_backend.solitour.gathering.dto.request.GatheringModifyRequest; +import solitour_backend.solitour.gathering.dto.request.GatheringPageRequest; import solitour_backend.solitour.gathering.dto.request.GatheringRegisterRequest; +import solitour_backend.solitour.gathering.dto.response.GatheringBriefResponse; import solitour_backend.solitour.gathering.dto.response.GatheringDetailResponse; import solitour_backend.solitour.gathering.dto.response.GatheringResponse; import solitour_backend.solitour.gathering.service.GatheringService; +import static solitour_backend.solitour.information.controller.InformationController.PAGE_SIZE; + @RestController @RequiredArgsConstructor @RequestMapping("/api/gatherings") @@ -76,6 +79,7 @@ public ResponseEntity updateGathering(@AuthenticationPrincipa if (gatheringModifyRequest.getEndAge() > gatheringModifyRequest.getStartAge()) { throw new RequestValidationFailedException("시작 나이 연도가 끝 나이 연도 보다 앞에 있네요"); } + if (gatheringModifyRequest.getScheduleStartDate().isAfter(gatheringModifyRequest.getScheduleEndDate())) { throw new RequestValidationFailedException("시작 날짜는 종료 날짜보다 앞에 있어야 합니다."); } @@ -92,6 +96,23 @@ public ResponseEntity updateGathering(@AuthenticationPrincipa } + @GetMapping + public ResponseEntity> pageGathering(@RequestParam(defaultValue = "0") int page, + @Valid @ModelAttribute GatheringPageRequest gatheringPageRequest, + BindingResult bindingResult, + HttpServletRequest request) { + Utils.validationRequest(bindingResult); + Long userId = findUser(request); + + Pageable pageable = PageRequest.of(page, PAGE_SIZE); + Page pageGathering = gatheringService.getPageGathering(pageable, gatheringPageRequest, userId); + + return ResponseEntity + .status(HttpStatus.OK) + .body(pageGathering); + } + + private Long findUser(HttpServletRequest request) { String token = CookieExtractor.findToken("access_token", request.getCookies()); From 71b651c3f5fbc3bc0cbfdf861ed992e3a8191e00 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Sat, 17 Aug 2024 23:34:18 +0900 Subject: [PATCH 109/371] =?UTF-8?q?feat:=20gathering=20=EC=B9=B4=ED=85=8C?= =?UTF-8?q?=EA=B3=A0=EB=A6=AC=20=EA=B8=B0=EB=B3=B8=EC=A0=81=EC=9D=B8=20cru?= =?UTF-8?q?d=20=EB=B3=80=EA=B2=BD=20=EB=B0=8F=20=ED=8C=A8=ED=82=A4?= =?UTF-8?q?=EC=A7=80=20=EC=9D=B4=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dto/mapper/GatheringCategoryMapper.java | 7 +- .../service/GatheringCategoryService.java | 93 ------------------- .../GatheringCategoryController.java | 43 +++++---- .../GatheringCategoryModifyRequest.java | 14 +++ .../entity/GatheringCategory.java | 9 +- .../GatheringCategoryRepository.java | 2 - .../service/GatheringCategoryService.java | 61 ++++++++++++ 7 files changed, 101 insertions(+), 128 deletions(-) delete mode 100644 src/main/java/solitour_backend/solitour/admin/service/GatheringCategoryService.java rename src/main/java/solitour_backend/solitour/{admin => gathering_category}/controller/GatheringCategoryController.java (52%) create mode 100644 src/main/java/solitour_backend/solitour/gathering_category/dto/request/GatheringCategoryModifyRequest.java create mode 100644 src/main/java/solitour_backend/solitour/gathering_category/service/GatheringCategoryService.java diff --git a/src/main/java/solitour_backend/solitour/admin/dto/mapper/GatheringCategoryMapper.java b/src/main/java/solitour_backend/solitour/admin/dto/mapper/GatheringCategoryMapper.java index 07838841..40d47484 100644 --- a/src/main/java/solitour_backend/solitour/admin/dto/mapper/GatheringCategoryMapper.java +++ b/src/main/java/solitour_backend/solitour/admin/dto/mapper/GatheringCategoryMapper.java @@ -1,15 +1,16 @@ package solitour_backend.solitour.admin.dto.mapper; import java.util.List; + import org.mapstruct.Mapper; import org.mapstruct.ReportingPolicy; -import solitour_backend.solitour.category.dto.response.CategoryResponse; +import solitour_backend.solitour.gathering_category.dto.response.GatheringCategoryResponse; import solitour_backend.solitour.gathering_category.entity.GatheringCategory; @Mapper(componentModel = "spring", unmappedTargetPolicy = ReportingPolicy.ERROR) public interface GatheringCategoryMapper { - CategoryResponse mapToCategoryResponse(GatheringCategory category); + GatheringCategoryResponse mapToCategoryResponse(GatheringCategory category); - List mapToCategoryResponses(List categories); + List mapToCategoryResponses(List categories); } diff --git a/src/main/java/solitour_backend/solitour/admin/service/GatheringCategoryService.java b/src/main/java/solitour_backend/solitour/admin/service/GatheringCategoryService.java deleted file mode 100644 index 58b50f9c..00000000 --- a/src/main/java/solitour_backend/solitour/admin/service/GatheringCategoryService.java +++ /dev/null @@ -1,93 +0,0 @@ -package solitour_backend.solitour.admin.service; - -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; -import lombok.RequiredArgsConstructor; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; -import solitour_backend.solitour.admin.dto.mapper.GatheringCategoryMapper; -import solitour_backend.solitour.category.dto.request.CategoryModifyRequest; -import solitour_backend.solitour.category.dto.request.CategoryRegisterRequest; -import solitour_backend.solitour.category.dto.response.CategoryGetResponse; -import solitour_backend.solitour.category.dto.response.CategoryResponse; -import solitour_backend.solitour.category.exception.CategoryNotExistsException; -import solitour_backend.solitour.gathering_category.entity.GatheringCategory; -import solitour_backend.solitour.gathering_category.repository.GatheringCategoryRepository; - -@Service -@Transactional(readOnly = true) -@RequiredArgsConstructor -public class GatheringCategoryService { - - private final GatheringCategoryRepository gatheringCategoryRepository; - private final GatheringCategoryMapper gatheringCategoryMapper; - - @Transactional - public CategoryResponse registerCategory(CategoryRegisterRequest categoryRegisterRequest) { - GatheringCategory parentCategoryEntity; - if (Objects.isNull(categoryRegisterRequest.getParentCategory())) { - parentCategoryEntity = null; - } else { - parentCategoryEntity = gatheringCategoryRepository.findById( - categoryRegisterRequest.getParentCategory()) - .orElseThrow( - () -> new CategoryNotExistsException("Parent category not found")); - } - - GatheringCategory category = new GatheringCategory(parentCategoryEntity, categoryRegisterRequest.getName()); - GatheringCategory saveCategory = gatheringCategoryRepository.save(category); - - return gatheringCategoryMapper.mapToCategoryResponse(saveCategory); - } - - - public CategoryResponse getCategory(Long id) { - GatheringCategory category = gatheringCategoryRepository.findById(id) - .orElseThrow( - () -> new CategoryNotExistsException("category not found")); - - return gatheringCategoryMapper.mapToCategoryResponse(category); - } - - - public List getChildrenCategories(Long id) { - List childrenCategories = gatheringCategoryRepository.findAllByParentCategoryId(id); - - return gatheringCategoryMapper.mapToCategoryResponses(childrenCategories); - } - - public List getParentCategories() { - List parentCategories = gatheringCategoryRepository.findAllByParentCategoryId(null); - List categoryGetResponses = new ArrayList<>(); - - for (GatheringCategory category : parentCategories) { - List childrenCategories = getChildrenCategories(category.getId()); - categoryGetResponses.add( - new CategoryGetResponse(category.getId(), category.getName(), childrenCategories)); - } - - return categoryGetResponses; - } - - @Transactional - public CategoryResponse modifyCategory(Long id, CategoryModifyRequest categoryModifyRequest) { - GatheringCategory parentCategoryEntity; - if (Objects.isNull(categoryModifyRequest.getParentCategory())) { - parentCategoryEntity = null; - } else { - parentCategoryEntity = gatheringCategoryRepository.findById( - categoryModifyRequest.getParentCategory()) - .orElseThrow( - () -> new CategoryNotExistsException("Parent category not found")); - } - - GatheringCategory category = gatheringCategoryRepository.findById(id).orElseThrow(); - - category.setName(categoryModifyRequest.getName()); - category.setParentCategory(parentCategoryEntity); - - return gatheringCategoryMapper.mapToCategoryResponse(category); - } - -} diff --git a/src/main/java/solitour_backend/solitour/admin/controller/GatheringCategoryController.java b/src/main/java/solitour_backend/solitour/gathering_category/controller/GatheringCategoryController.java similarity index 52% rename from src/main/java/solitour_backend/solitour/admin/controller/GatheringCategoryController.java rename to src/main/java/solitour_backend/solitour/gathering_category/controller/GatheringCategoryController.java index 9a2e822c..7ade5fba 100644 --- a/src/main/java/solitour_backend/solitour/admin/controller/GatheringCategoryController.java +++ b/src/main/java/solitour_backend/solitour/gathering_category/controller/GatheringCategoryController.java @@ -1,7 +1,9 @@ -package solitour_backend.solitour.admin.controller; +package solitour_backend.solitour.gathering_category.controller; import jakarta.validation.Valid; + import java.util.List; + import lombok.RequiredArgsConstructor; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -13,12 +15,12 @@ import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; -import solitour_backend.solitour.admin.service.GatheringCategoryService; -import solitour_backend.solitour.category.dto.request.CategoryModifyRequest; import solitour_backend.solitour.category.dto.request.CategoryRegisterRequest; -import solitour_backend.solitour.category.dto.response.CategoryGetResponse; -import solitour_backend.solitour.category.dto.response.CategoryResponse; +import solitour_backend.solitour.error.Utils; import solitour_backend.solitour.error.exception.RequestValidationFailedException; +import solitour_backend.solitour.gathering_category.dto.request.GatheringCategoryModifyRequest; +import solitour_backend.solitour.gathering_category.dto.response.GatheringCategoryResponse; +import solitour_backend.solitour.gathering_category.service.GatheringCategoryService; @RestController @RequiredArgsConstructor @@ -28,8 +30,8 @@ public class GatheringCategoryController { private final GatheringCategoryService gatheringCategoryService; @GetMapping - public ResponseEntity> getAllCategories() { - List parentCategories = gatheringCategoryService.getParentCategories(); + public ResponseEntity> getAllCategories() { + List parentCategories = gatheringCategoryService.getCategories(); return ResponseEntity .status(HttpStatus.OK) @@ -37,8 +39,8 @@ public ResponseEntity> getAllCategories() { } @GetMapping("/{id}") - public ResponseEntity getCategory(@PathVariable Long id) { - CategoryResponse category = gatheringCategoryService.getCategory(id); + public ResponseEntity getCategory(@PathVariable Long id) { + GatheringCategoryResponse category = gatheringCategoryService.getCategory(id); return ResponseEntity .status(HttpStatus.OK) @@ -46,13 +48,11 @@ public ResponseEntity getCategory(@PathVariable Long id) { } @PostMapping - public ResponseEntity registerCategory( - @Valid @RequestBody CategoryRegisterRequest categoryRegisterRequest, - BindingResult bindingResult) { - if (bindingResult.hasErrors()) { - throw new RequestValidationFailedException(bindingResult); - } - CategoryResponse categoryResponse = gatheringCategoryService.registerCategory( + public ResponseEntity registerCategory(@Valid @RequestBody CategoryRegisterRequest categoryRegisterRequest, + BindingResult bindingResult) { + Utils.validationRequest(bindingResult); + + GatheringCategoryResponse categoryResponse = gatheringCategoryService.registerCategory( categoryRegisterRequest); return ResponseEntity .status(HttpStatus.CREATED) @@ -61,15 +61,14 @@ public ResponseEntity registerCategory( } @PutMapping("/{id}") - public ResponseEntity modifyCategory( - @Valid @RequestBody CategoryModifyRequest categoryModifyRequest, - BindingResult bindingResult, - @PathVariable Long id) { + public ResponseEntity modifyCategory(@Valid @RequestBody GatheringCategoryModifyRequest gatheringCategoryModifyRequest, + BindingResult bindingResult, + @PathVariable Long id) { if (bindingResult.hasErrors()) { throw new RequestValidationFailedException(bindingResult); } - CategoryResponse categoryResponse = gatheringCategoryService.modifyCategory(id, - categoryModifyRequest); + GatheringCategoryResponse categoryResponse = gatheringCategoryService.modifyCategory(id, + gatheringCategoryModifyRequest); return ResponseEntity .status(HttpStatus.CREATED) diff --git a/src/main/java/solitour_backend/solitour/gathering_category/dto/request/GatheringCategoryModifyRequest.java b/src/main/java/solitour_backend/solitour/gathering_category/dto/request/GatheringCategoryModifyRequest.java new file mode 100644 index 00000000..703826f5 --- /dev/null +++ b/src/main/java/solitour_backend/solitour/gathering_category/dto/request/GatheringCategoryModifyRequest.java @@ -0,0 +1,14 @@ +package solitour_backend.solitour.gathering_category.dto.request; + +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.Size; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor +public class GatheringCategoryModifyRequest { + @NotBlank + @Size(min = 2, max = 20) + private String name; +} diff --git a/src/main/java/solitour_backend/solitour/gathering_category/entity/GatheringCategory.java b/src/main/java/solitour_backend/solitour/gathering_category/entity/GatheringCategory.java index 8ad8b714..03307870 100644 --- a/src/main/java/solitour_backend/solitour/gathering_category/entity/GatheringCategory.java +++ b/src/main/java/solitour_backend/solitour/gathering_category/entity/GatheringCategory.java @@ -2,12 +2,9 @@ import jakarta.persistence.Column; import jakarta.persistence.Entity; -import jakarta.persistence.FetchType; import jakarta.persistence.GeneratedValue; import jakarta.persistence.GenerationType; import jakarta.persistence.Id; -import jakarta.persistence.JoinColumn; -import jakarta.persistence.ManyToOne; import jakarta.persistence.Table; import lombok.Getter; import lombok.NoArgsConstructor; @@ -25,15 +22,11 @@ public class GatheringCategory { @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; - @ManyToOne(fetch = FetchType.EAGER) - @JoinColumn(name = "parent_category_id") - private GatheringCategory parentCategory; @Column(name = "gathering_category_name") private String name; - public GatheringCategory(GatheringCategory parentCategory, String name) { - this.parentCategory = parentCategory; + public GatheringCategory(String name) { this.name = name; } } diff --git a/src/main/java/solitour_backend/solitour/gathering_category/repository/GatheringCategoryRepository.java b/src/main/java/solitour_backend/solitour/gathering_category/repository/GatheringCategoryRepository.java index c68fdde3..c014b277 100644 --- a/src/main/java/solitour_backend/solitour/gathering_category/repository/GatheringCategoryRepository.java +++ b/src/main/java/solitour_backend/solitour/gathering_category/repository/GatheringCategoryRepository.java @@ -1,10 +1,8 @@ package solitour_backend.solitour.gathering_category.repository; -import java.util.List; import org.springframework.data.jpa.repository.JpaRepository; import solitour_backend.solitour.gathering_category.entity.GatheringCategory; public interface GatheringCategoryRepository extends JpaRepository { - List findAllByParentCategoryId(Long parentCategoryId); } diff --git a/src/main/java/solitour_backend/solitour/gathering_category/service/GatheringCategoryService.java b/src/main/java/solitour_backend/solitour/gathering_category/service/GatheringCategoryService.java new file mode 100644 index 00000000..b33badd2 --- /dev/null +++ b/src/main/java/solitour_backend/solitour/gathering_category/service/GatheringCategoryService.java @@ -0,0 +1,61 @@ +package solitour_backend.solitour.gathering_category.service; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import solitour_backend.solitour.admin.dto.mapper.GatheringCategoryMapper; +import solitour_backend.solitour.category.dto.request.CategoryRegisterRequest; +import solitour_backend.solitour.category.exception.CategoryNotExistsException; +import solitour_backend.solitour.gathering_category.dto.request.GatheringCategoryModifyRequest; +import solitour_backend.solitour.gathering_category.dto.response.GatheringCategoryResponse; +import solitour_backend.solitour.gathering_category.entity.GatheringCategory; +import solitour_backend.solitour.gathering_category.repository.GatheringCategoryRepository; + +@Service +@Transactional(readOnly = true) +@RequiredArgsConstructor +public class GatheringCategoryService { + + private final GatheringCategoryRepository gatheringCategoryRepository; + private final GatheringCategoryMapper gatheringCategoryMapper; + + @Transactional + public GatheringCategoryResponse registerCategory(CategoryRegisterRequest categoryRegisterRequest) { + + + GatheringCategory category = new GatheringCategory(categoryRegisterRequest.getName()); + GatheringCategory saveCategory = gatheringCategoryRepository.save(category); + + return gatheringCategoryMapper.mapToCategoryResponse(saveCategory); + } + + + public GatheringCategoryResponse getCategory(Long id) { + GatheringCategory category = gatheringCategoryRepository.findById(id) + .orElseThrow( + () -> new CategoryNotExistsException("category not found")); + + return gatheringCategoryMapper.mapToCategoryResponse(category); + } + + + public List getCategories() { + List allGatheringCategory = gatheringCategoryRepository.findAll(); + + return gatheringCategoryMapper.mapToCategoryResponses(allGatheringCategory); + } + + @Transactional + public GatheringCategoryResponse modifyCategory(Long id, GatheringCategoryModifyRequest gatheringCategoryModifyRequest) { + GatheringCategory category = gatheringCategoryRepository.findById(id).orElseThrow(); + + category.setName(gatheringCategoryModifyRequest.getName()); + + return gatheringCategoryMapper.mapToCategoryResponse(category); + } + +} From ae38ba632c4c3f9f44089fae9df9f97431ec1e3b Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Sun, 18 Aug 2024 02:45:47 +0900 Subject: [PATCH 110/371] feat: gathering rank response dto --- .../gathering/dto/response/GatheringRankResponse.java | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 src/main/java/solitour_backend/solitour/gathering/dto/response/GatheringRankResponse.java diff --git a/src/main/java/solitour_backend/solitour/gathering/dto/response/GatheringRankResponse.java b/src/main/java/solitour_backend/solitour/gathering/dto/response/GatheringRankResponse.java new file mode 100644 index 00000000..00a54ba1 --- /dev/null +++ b/src/main/java/solitour_backend/solitour/gathering/dto/response/GatheringRankResponse.java @@ -0,0 +1,11 @@ +package solitour_backend.solitour.gathering.dto.response; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor +public class GatheringRankResponse { + private Long id; + private String title; +} From f71b6c85b98e43171a8b8ceebdd602efeb86ca9d Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Sun, 18 Aug 2024 02:46:10 +0900 Subject: [PATCH 111/371] =?UTF-8?q?refactor:=20=EB=AC=B8=EC=9E=A5=20?= =?UTF-8?q?=EC=A0=95=EB=A0=AC=ED=95=B4=EC=84=9C=20=EB=B3=B4=EC=97=AC?= =?UTF-8?q?=EC=A3=BC=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../RequestValidationFailedException.java | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/main/java/solitour_backend/solitour/error/exception/RequestValidationFailedException.java b/src/main/java/solitour_backend/solitour/error/exception/RequestValidationFailedException.java index 81bfc786..f179eed6 100644 --- a/src/main/java/solitour_backend/solitour/error/exception/RequestValidationFailedException.java +++ b/src/main/java/solitour_backend/solitour/error/exception/RequestValidationFailedException.java @@ -1,7 +1,9 @@ package solitour_backend.solitour.error.exception; import jakarta.validation.ValidationException; + import java.util.stream.Collectors; + import org.springframework.validation.BindingResult; public class RequestValidationFailedException extends ValidationException { @@ -10,13 +12,15 @@ public RequestValidationFailedException(BindingResult bindingResult) { super(bindingResult.getAllErrors() .stream() .map(objectError -> new StringBuilder() - .append("object: ") + .append("Object: ") .append(objectError.getObjectName()) - .append(", message: ") + .append("\nMessage: ") .append(objectError.getDefaultMessage()) - .append(", error code: ") - .append(objectError.getCode())) - .collect(Collectors.joining("|"))); + .append("\nError Code: ") + .append(objectError.getCode()) + .append("\n") + .toString()) + .collect(Collectors.joining("\n-----------------------------\n"))); } From 34b4bdb1892a0231f27449b4f77df6124d863190 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Sun, 18 Aug 2024 02:46:45 +0900 Subject: [PATCH 112/371] feat: gathering Rank List repository --- .../gathering/repository/GatheringRepositoryCustom.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryCustom.java b/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryCustom.java index 55c32407..58c1f97d 100644 --- a/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryCustom.java +++ b/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryCustom.java @@ -7,6 +7,7 @@ import org.springframework.data.repository.NoRepositoryBean; import solitour_backend.solitour.gathering.dto.request.GatheringPageRequest; import solitour_backend.solitour.gathering.dto.response.GatheringBriefResponse; +import solitour_backend.solitour.gathering.dto.response.GatheringRankResponse; @NoRepositoryBean public interface GatheringRepositoryCustom { @@ -17,4 +18,5 @@ public interface GatheringRepositoryCustom { Page getGatheringPageFilterAndOrder(Pageable pageable, GatheringPageRequest gatheringPageRequest, Long userId); + List getGatheringRankList(); } From 0bc878691c95a28cd0d6a8bbb5038a4000e7ec0a Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Sun, 18 Aug 2024 02:47:13 +0900 Subject: [PATCH 113/371] =?UTF-8?q?feat:=20gathering=20Rank=20List=20repos?= =?UTF-8?q?itory=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../repository/GatheringRepositoryImpl.java | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryImpl.java b/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryImpl.java index f5e14d98..2599fe73 100644 --- a/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryImpl.java +++ b/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryImpl.java @@ -20,6 +20,7 @@ import solitour_backend.solitour.book_mark_gathering.entity.QBookMarkGathering; import solitour_backend.solitour.gathering.dto.request.GatheringPageRequest; import solitour_backend.solitour.gathering.dto.response.GatheringBriefResponse; +import solitour_backend.solitour.gathering.dto.response.GatheringRankResponse; import solitour_backend.solitour.gathering.entity.Gathering; import solitour_backend.solitour.gathering.entity.QGathering; import solitour_backend.solitour.gathering_applicants.entity.GatheringStatus; @@ -34,7 +35,6 @@ public GatheringRepositoryImpl() { } - QGathering gathering = QGathering.gathering; QZoneCategory zoneCategoryChild = QZoneCategory.zoneCategory; QZoneCategory zoneCategoryParent = new QZoneCategory("zoneCategoryParent"); @@ -53,7 +53,6 @@ public List getGatheringRecommend(Long gatheringId, Long .leftJoin(zoneCategoryParent).on(zoneCategoryParent.id.eq(zoneCategoryChild.parentZoneCategory.id)) .leftJoin(bookMarkGathering) .on(bookMarkGathering.gathering.id.eq(gathering.id).and(bookMarkGathering.user.id.eq(userId))) - .leftJoin(greatGathering).on(greatGathering.gathering.id.eq(gathering.id)) .leftJoin(category).on(category.id.eq(gathering.gatheringCategory.id)) .leftJoin(gatheringApplicants).on(gatheringApplicants.gathering.id.eq(gathering.id)) .where(gathering.isFinish.eq(Boolean.FALSE) @@ -111,7 +110,6 @@ public Page getGatheringPageFilterAndOrder(Pageable page .join(zoneCategoryChild).on(zoneCategoryChild.id.eq(gathering.zoneCategory.id)) .leftJoin(zoneCategoryParent).on(zoneCategoryParent.id.eq(zoneCategoryChild.parentZoneCategory.id)) .leftJoin(bookMarkGathering).on(bookMarkGathering.gathering.id.eq(gathering.id).and(bookMarkGathering.user.id.eq(userId))) - .leftJoin(greatGathering).on(greatGathering.gathering.id.eq(gathering.id).and(greatGathering.isDeleted.isFalse())) .leftJoin(gatheringApplicants).on(gatheringApplicants.gathering.id.eq(gathering.id)) .where(booleanBuilder) .groupBy(gathering.id, zoneCategoryChild.id, zoneCategoryParent.id, category.id, @@ -156,6 +154,21 @@ public Page getGatheringPageFilterAndOrder(Pageable page return new PageImpl<>(content, pageable, total); } + @Override + public List getGatheringRankList() { + return from(gathering) + .orderBy(countGreatGatheringByGatheringById().desc()) + .groupBy(gathering.id, gathering.title) + .where(gathering.isFinish.eq(Boolean.FALSE)) + .limit(5) + .select(Projections.constructor( + GatheringRankResponse.class, + gathering.id, + gathering.title + )).fetch(); + } + + //where 절 private BooleanBuilder makeWhereSQL(GatheringPageRequest gatheringPageRequest) { BooleanBuilder whereClause = new BooleanBuilder(); From 3d901420c73393ffe0a25838d1ecf74af46b269e Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Sun, 18 Aug 2024 02:47:24 +0900 Subject: [PATCH 114/371] feat: gathering Rank List service --- .../solitour/gathering/service/GatheringService.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/main/java/solitour_backend/solitour/gathering/service/GatheringService.java b/src/main/java/solitour_backend/solitour/gathering/service/GatheringService.java index 887f54a3..ff411d62 100644 --- a/src/main/java/solitour_backend/solitour/gathering/service/GatheringService.java +++ b/src/main/java/solitour_backend/solitour/gathering/service/GatheringService.java @@ -16,6 +16,7 @@ import solitour_backend.solitour.gathering.dto.request.GatheringRegisterRequest; import solitour_backend.solitour.gathering.dto.response.GatheringBriefResponse; import solitour_backend.solitour.gathering.dto.response.GatheringDetailResponse; +import solitour_backend.solitour.gathering.dto.response.GatheringRankResponse; import solitour_backend.solitour.gathering.dto.response.GatheringResponse; import solitour_backend.solitour.gathering.entity.Gathering; import solitour_backend.solitour.gathering.exception.GatheringCategoryNotExistsException; @@ -261,6 +262,11 @@ public Page getPageGathering(Pageable pageable, Gatherin return gatheringRepository.getGatheringPageFilterAndOrder(pageable, gatheringPageRequest, userId); } + public List getGatheringRankOrderByLikes() { + return gatheringRepository.getGatheringRankList(); + } + + private void validateGatheringPageRequest(GatheringPageRequest gatheringPageRequest) { // Category 검증 if (Objects.nonNull(gatheringPageRequest.getCategory())) { From d39e44922ba8d7e5e297c313b4faa3c567693efe Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Sun, 18 Aug 2024 02:47:43 +0900 Subject: [PATCH 115/371] feat: gathering Rank List controller --- .../controller/GatheringController.java | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/src/main/java/solitour_backend/solitour/gathering/controller/GatheringController.java b/src/main/java/solitour_backend/solitour/gathering/controller/GatheringController.java index 4ff38052..96def71c 100644 --- a/src/main/java/solitour_backend/solitour/gathering/controller/GatheringController.java +++ b/src/main/java/solitour_backend/solitour/gathering/controller/GatheringController.java @@ -4,6 +4,7 @@ import jakarta.validation.Valid; import java.time.LocalDateTime; +import java.util.List; import java.util.Objects; import lombok.RequiredArgsConstructor; @@ -24,6 +25,7 @@ import solitour_backend.solitour.gathering.dto.request.GatheringRegisterRequest; import solitour_backend.solitour.gathering.dto.response.GatheringBriefResponse; import solitour_backend.solitour.gathering.dto.response.GatheringDetailResponse; +import solitour_backend.solitour.gathering.dto.response.GatheringRankResponse; import solitour_backend.solitour.gathering.dto.response.GatheringResponse; import solitour_backend.solitour.gathering.service.GatheringService; @@ -97,10 +99,10 @@ public ResponseEntity updateGathering(@AuthenticationPrincipa @GetMapping - public ResponseEntity> pageGathering(@RequestParam(defaultValue = "0") int page, - @Valid @ModelAttribute GatheringPageRequest gatheringPageRequest, - BindingResult bindingResult, - HttpServletRequest request) { + public ResponseEntity> pageGatheringSortAndFilter(@RequestParam(defaultValue = "0") int page, + @Valid @ModelAttribute GatheringPageRequest gatheringPageRequest, + BindingResult bindingResult, + HttpServletRequest request) { Utils.validationRequest(bindingResult); Long userId = findUser(request); @@ -112,6 +114,15 @@ public ResponseEntity> pageGathering(@RequestParam( .body(pageGathering); } + @GetMapping("/ranks") + public ResponseEntity> getGatheringRankOrderByLikes() { + List gatheringRankOrderByLikes = gatheringService.getGatheringRankOrderByLikes(); + + return ResponseEntity + .status(HttpStatus.OK) + .body(gatheringRankOrderByLikes); + } + private Long findUser(HttpServletRequest request) { String token = CookieExtractor.findToken("access_token", request.getCookies()); From 9907ce6a9260f786c31c59085764893b992ddd22 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Tue, 20 Aug 2024 23:47:49 +0900 Subject: [PATCH 116/371] =?UTF-8?q?refactor:=20gathering=5Fcategory.dto.ma?= =?UTF-8?q?pper=20=ED=8C=A8=ED=82=A4=EC=A7=80=EB=A1=9C=20=EC=9D=B4?= =?UTF-8?q?=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dto/mapper/GatheringCategoryMapper.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename src/main/java/solitour_backend/solitour/{admin => gathering_category}/dto/mapper/GatheringCategoryMapper.java (89%) diff --git a/src/main/java/solitour_backend/solitour/admin/dto/mapper/GatheringCategoryMapper.java b/src/main/java/solitour_backend/solitour/gathering_category/dto/mapper/GatheringCategoryMapper.java similarity index 89% rename from src/main/java/solitour_backend/solitour/admin/dto/mapper/GatheringCategoryMapper.java rename to src/main/java/solitour_backend/solitour/gathering_category/dto/mapper/GatheringCategoryMapper.java index 40d47484..63eae28b 100644 --- a/src/main/java/solitour_backend/solitour/admin/dto/mapper/GatheringCategoryMapper.java +++ b/src/main/java/solitour_backend/solitour/gathering_category/dto/mapper/GatheringCategoryMapper.java @@ -1,4 +1,4 @@ -package solitour_backend.solitour.admin.dto.mapper; +package solitour_backend.solitour.gathering_category.dto.mapper; import java.util.List; From 0acb4b0d329529f6e4f5850aa9774be44c972b22 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Tue, 20 Aug 2024 23:48:24 +0900 Subject: [PATCH 117/371] =?UTF-8?q?feat:=20gatheringCategory=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80=20=EB=B0=8F=20isLike=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../gathering/dto/response/GatheringDetailResponse.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/main/java/solitour_backend/solitour/gathering/dto/response/GatheringDetailResponse.java b/src/main/java/solitour_backend/solitour/gathering/dto/response/GatheringDetailResponse.java index 3e7601d5..00f9fa0d 100644 --- a/src/main/java/solitour_backend/solitour/gathering/dto/response/GatheringDetailResponse.java +++ b/src/main/java/solitour_backend/solitour/gathering/dto/response/GatheringDetailResponse.java @@ -2,10 +2,12 @@ import java.time.LocalDateTime; import java.util.List; + import lombok.AllArgsConstructor; import lombok.Getter; import solitour_backend.solitour.gathering.entity.AllowedSex; import solitour_backend.solitour.gathering_applicants.dto.response.GatheringApplicantsResponse; +import solitour_backend.solitour.gathering_category.dto.response.GatheringCategoryResponse; import solitour_backend.solitour.place.dto.response.PlaceResponse; import solitour_backend.solitour.tag.dto.response.TagResponse; import solitour_backend.solitour.user.dto.UserPostingResponse; @@ -34,10 +36,13 @@ public class GatheringDetailResponse { private UserPostingResponse userPostingResponse; private PlaceResponse placeResponse; private ZoneCategoryResponse zoneCategoryResponse; + private GatheringCategoryResponse gatheringCategoryResponse; private Integer likeCount; private Integer nowPersonCount; + private Boolean isLike; + private List gatheringApplicantsResponses; private List gatheringRecommend; From e9cb5c780c0138edb8b46d44589fac1437091b68 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Tue, 20 Aug 2024 23:48:52 +0900 Subject: [PATCH 118/371] =?UTF-8?q?refactor:=20gatheringCategoryMapper=20?= =?UTF-8?q?=ED=8C=A8=ED=82=A4=EC=A7=80=20=EC=9D=B4=EB=8F=99=EC=9C=BC?= =?UTF-8?q?=EB=A1=9C=20=EC=9D=B8=ED=95=9C=20=EB=A6=AC=ED=8C=A9=ED=86=A0?= =?UTF-8?q?=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../gathering_category/service/GatheringCategoryService.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/main/java/solitour_backend/solitour/gathering_category/service/GatheringCategoryService.java b/src/main/java/solitour_backend/solitour/gathering_category/service/GatheringCategoryService.java index b33badd2..a3cfdab6 100644 --- a/src/main/java/solitour_backend/solitour/gathering_category/service/GatheringCategoryService.java +++ b/src/main/java/solitour_backend/solitour/gathering_category/service/GatheringCategoryService.java @@ -1,13 +1,11 @@ package solitour_backend.solitour.gathering_category.service; -import java.util.ArrayList; import java.util.List; -import java.util.Objects; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import solitour_backend.solitour.admin.dto.mapper.GatheringCategoryMapper; +import solitour_backend.solitour.gathering_category.dto.mapper.GatheringCategoryMapper; import solitour_backend.solitour.category.dto.request.CategoryRegisterRequest; import solitour_backend.solitour.category.exception.CategoryNotExistsException; import solitour_backend.solitour.gathering_category.dto.request.GatheringCategoryModifyRequest; From 843f397713f51be3f26a40096e6a34ae69b56352 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Tue, 20 Aug 2024 23:49:39 +0900 Subject: [PATCH 119/371] =?UTF-8?q?feat:=20=EB=AA=A8=EC=9E=84=20id?= =?UTF-8?q?=EC=99=80=20user=20id=EB=A5=BC=20=EC=9D=B4=EC=9A=A9=ED=95=98?= =?UTF-8?q?=EC=97=AC=20=EC=82=AD=EC=A0=9C=20=EB=90=98=EC=A7=80=20=EC=95=8A?= =?UTF-8?q?=EC=9D=80=20greatGathering=20=EC=9D=B4=20=EC=9E=88=EB=8A=94?= =?UTF-8?q?=EC=A7=80=20=ED=99=95=EC=9D=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../great_gathering/repository/GreatGatheringRepository.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/solitour_backend/solitour/great_gathering/repository/GreatGatheringRepository.java b/src/main/java/solitour_backend/solitour/great_gathering/repository/GreatGatheringRepository.java index c9f8eb3c..15f75dd2 100644 --- a/src/main/java/solitour_backend/solitour/great_gathering/repository/GreatGatheringRepository.java +++ b/src/main/java/solitour_backend/solitour/great_gathering/repository/GreatGatheringRepository.java @@ -8,4 +8,6 @@ public interface GreatGatheringRepository extends JpaRepository Date: Tue, 20 Aug 2024 23:50:22 +0900 Subject: [PATCH 120/371] =?UTF-8?q?feat:=20=ED=9A=8C=EC=9B=90=EC=9D=B4=20?= =?UTF-8?q?=EC=9D=B4=20=EB=AA=A8=EC=9E=84=EC=97=90=20=EC=A2=8B=EC=95=84?= =?UTF-8?q?=EC=9A=94=20=ED=96=88=EB=8A=94=EC=A7=80=20=ED=95=84=EB=93=9C?= =?UTF-8?q?=EC=99=80=20gathering=20=20category=20response=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../solitour/gathering/service/GatheringService.java | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/main/java/solitour_backend/solitour/gathering/service/GatheringService.java b/src/main/java/solitour_backend/solitour/gathering/service/GatheringService.java index ff411d62..77ca7596 100644 --- a/src/main/java/solitour_backend/solitour/gathering/service/GatheringService.java +++ b/src/main/java/solitour_backend/solitour/gathering/service/GatheringService.java @@ -27,6 +27,8 @@ import solitour_backend.solitour.gathering_applicants.entity.GatheringStatus; import solitour_backend.solitour.gathering_applicants.exception.GatheringNotManagerException; import solitour_backend.solitour.gathering_applicants.repository.GatheringApplicantsRepository; +import solitour_backend.solitour.gathering_category.dto.mapper.GatheringCategoryMapper; +import solitour_backend.solitour.gathering_category.dto.response.GatheringCategoryResponse; import solitour_backend.solitour.gathering_category.entity.GatheringCategory; import solitour_backend.solitour.gathering_category.repository.GatheringCategoryRepository; import solitour_backend.solitour.gathering_tag.entity.GatheringTag; @@ -76,6 +78,7 @@ public class GatheringService { private final GreatGatheringRepository greatGatheringRepository; private final GatheringApplicantsRepository gatheringApplicantsRepository; private final GatheringApplicantsMapper gatheringApplicantsMapper; + private final GatheringCategoryMapper gatheringCategoryMapper; public GatheringDetailResponse getGatheringDetail(Long userId, Long gatheringId) { @@ -94,6 +97,9 @@ public GatheringDetailResponse getGatheringDetail(Long userId, Long gatheringId) tagMapper.mapToTagResponse(data.getTag())) .toList(); } + GatheringCategory gatheringCategory = gathering.getGatheringCategory(); + + GatheringCategoryResponse gatheringCategoryResponse = gatheringCategoryMapper.mapToCategoryResponse(gatheringCategory); PlaceResponse placeResponse = placeMapper.mapToPlaceResponse(gathering.getPlace()); @@ -108,6 +114,8 @@ public GatheringDetailResponse getGatheringDetail(Long userId, Long gatheringId) int nowPersonCount = gatheringApplicantsRepository.countAllByGathering_IdAndGatheringStatus(gathering.getId(), GatheringStatus.CONSENT); + boolean isLike = greatGatheringRepository.existsByGatheringIdAndUserIdAndIsDeletedFalse(gathering.getId(), userId); + List gatheringRecommend = gatheringRepository.getGatheringRecommend(gathering.getId(), gathering.getGatheringCategory().getId(), userId); @@ -128,8 +136,10 @@ public GatheringDetailResponse getGatheringDetail(Long userId, Long gatheringId) userPostingResponse, placeResponse, zoneCategoryResponse, + gatheringCategoryResponse, likeCount, nowPersonCount, + isLike, gatheringApplicantsResponses, gatheringRecommend ); From d2ce968c7b6a4a04ef3d3f90ec0c0cdbcc63f8bc Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Wed, 21 Aug 2024 01:38:45 +0900 Subject: [PATCH 121/371] =?UTF-8?q?feat:=20=EB=AA=A8=EC=9E=84=20=EC=B0=B8?= =?UTF-8?q?=EC=97=AC=20=EA=B8=B0=EB=8A=A5=20=EB=AA=A8=EC=9E=84=20=EB=8B=B4?= =?UTF-8?q?=EB=8B=B9=EC=9E=90=EA=B0=80=20=ED=95=B4=EB=8B=B9=20=EA=B8=B0?= =?UTF-8?q?=EB=8A=A5=EC=9D=84=20=EC=B0=B8=EC=97=AC=ED=95=98=EB=A0=A4?= =?UTF-8?q?=EA=B3=A0=20=ED=95=A0=EB=95=8C=20=EC=98=88=EC=99=B8=EC=B2=98?= =?UTF-8?q?=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../exception/GatheringApplicantsManagerException.java | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 src/main/java/solitour_backend/solitour/gathering_applicants/exception/GatheringApplicantsManagerException.java diff --git a/src/main/java/solitour_backend/solitour/gathering_applicants/exception/GatheringApplicantsManagerException.java b/src/main/java/solitour_backend/solitour/gathering_applicants/exception/GatheringApplicantsManagerException.java new file mode 100644 index 00000000..cc82b5b9 --- /dev/null +++ b/src/main/java/solitour_backend/solitour/gathering_applicants/exception/GatheringApplicantsManagerException.java @@ -0,0 +1,7 @@ +package solitour_backend.solitour.gathering_applicants.exception; + +public class GatheringApplicantsManagerException extends RuntimeException { + public GatheringApplicantsManagerException(String message) { + super(message); + } +} From a4a2efefd92006cfe28ac36e4ecee61ec650de20 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Wed, 21 Aug 2024 01:38:57 +0900 Subject: [PATCH 122/371] =?UTF-8?q?feat:=20=EB=AA=A8=EC=9E=84=20=EC=B0=B8?= =?UTF-8?q?=EC=97=AC=20=EA=B8=B0=EB=8A=A5=20=EB=AA=A8=EC=9E=84=20=EB=8B=B4?= =?UTF-8?q?=EB=8B=B9=EC=9E=90=EA=B0=80=20=ED=95=B4=EB=8B=B9=20=EA=B8=B0?= =?UTF-8?q?=EB=8A=A5=EC=9D=84=20=EC=B0=B8=EC=97=AC=ED=95=98=EB=A0=A4?= =?UTF-8?q?=EA=B3=A0=20=ED=95=A0=EB=95=8C=20=EC=98=88=EC=99=B8=EC=B2=98?= =?UTF-8?q?=EB=A6=AC=20=EB=93=B1=EB=A1=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../solitour/error/GlobalControllerAdvice.java | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/main/java/solitour_backend/solitour/error/GlobalControllerAdvice.java b/src/main/java/solitour_backend/solitour/error/GlobalControllerAdvice.java index eb4c8236..b6a15f25 100644 --- a/src/main/java/solitour_backend/solitour/error/GlobalControllerAdvice.java +++ b/src/main/java/solitour_backend/solitour/error/GlobalControllerAdvice.java @@ -8,10 +8,7 @@ import solitour_backend.solitour.error.exception.RequestValidationFailedException; import solitour_backend.solitour.gathering.exception.GatheringCategoryNotExistsException; import solitour_backend.solitour.gathering.exception.GatheringNotExistsException; -import solitour_backend.solitour.gathering_applicants.exception.GatheringApplicantsAlreadyExistsException; -import solitour_backend.solitour.gathering_applicants.exception.GatheringApplicantsAlreadyFullPeopleException; -import solitour_backend.solitour.gathering_applicants.exception.GatheringApplicantsNotExistsException; -import solitour_backend.solitour.gathering_applicants.exception.GatheringNotManagerException; +import solitour_backend.solitour.gathering_applicants.exception.*; import solitour_backend.solitour.image.exception.ImageAlreadyExistsException; import solitour_backend.solitour.image.exception.ImageNotExistsException; import solitour_backend.solitour.image.exception.ImageRequestValidationFailedException; @@ -23,7 +20,7 @@ @RestControllerAdvice public class GlobalControllerAdvice { - @ExceptionHandler({RequestValidationFailedException.class, ImageRequestValidationFailedException.class}) + @ExceptionHandler({RequestValidationFailedException.class, ImageRequestValidationFailedException.class, GatheringApplicantsManagerException.class}) public ResponseEntity validationException(Exception exception) { return ResponseEntity .status(HttpStatus.BAD_REQUEST) From 6668a1812b14cbef549db29b6f4b93b8ebb2c5e5 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Wed, 21 Aug 2024 01:39:55 +0900 Subject: [PATCH 123/371] =?UTF-8?q?feat:=20=EB=AA=A8=EB=93=A0=20=EB=AA=A8?= =?UTF-8?q?=EC=9E=84=20=EC=B0=B8=EC=97=AC=20=EB=8D=B0=EC=9D=B4=ED=84=B0=20?= =?UTF-8?q?=EB=AA=A8=EC=9E=84=20=EC=95=84=EC=9D=B4=EB=94=94=EC=99=80=20?= =?UTF-8?q?=ED=95=B4=EB=8B=B9=20userId=20=EA=B0=80=20=EC=95=84=EB=8B=8C=20?= =?UTF-8?q?=EA=B1=B0=20=EC=A1=B0=ED=9A=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../repository/GatheringApplicantsRepository.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/solitour_backend/solitour/gathering_applicants/repository/GatheringApplicantsRepository.java b/src/main/java/solitour_backend/solitour/gathering_applicants/repository/GatheringApplicantsRepository.java index d3399046..7eda6876 100644 --- a/src/main/java/solitour_backend/solitour/gathering_applicants/repository/GatheringApplicantsRepository.java +++ b/src/main/java/solitour_backend/solitour/gathering_applicants/repository/GatheringApplicantsRepository.java @@ -7,7 +7,7 @@ import solitour_backend.solitour.gathering_applicants.entity.GatheringStatus; public interface GatheringApplicantsRepository extends JpaRepository { - List findAllByGathering_Id(Long id); + List findAllByGathering_IdAndUserIdNot(Long id, Long userId); int countAllByGathering_IdAndGatheringStatus(Long id, GatheringStatus gatheringStatus); From 3d4814ef286924176cc464e0f1000dd6605689f3 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Wed, 21 Aug 2024 01:41:23 +0900 Subject: [PATCH 124/371] =?UTF-8?q?feat:=20=EB=AA=A8=EC=9E=84=20=EB=93=B1?= =?UTF-8?q?=EB=A1=9D=ED=95=A0=EB=95=8C=20=EB=93=B1=EB=A1=9D=ED=95=9C=20use?= =?UTF-8?q?r=20=EB=AA=A8=EC=9E=84=20=EC=B0=B8=EC=97=AC=20=EB=93=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../gathering/service/GatheringService.java | 21 ++++++++----------- 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/src/main/java/solitour_backend/solitour/gathering/service/GatheringService.java b/src/main/java/solitour_backend/solitour/gathering/service/GatheringService.java index 77ca7596..86a5a62f 100644 --- a/src/main/java/solitour_backend/solitour/gathering/service/GatheringService.java +++ b/src/main/java/solitour_backend/solitour/gathering/service/GatheringService.java @@ -24,6 +24,7 @@ import solitour_backend.solitour.gathering.repository.GatheringRepository; import solitour_backend.solitour.gathering_applicants.dto.mapper.GatheringApplicantsMapper; import solitour_backend.solitour.gathering_applicants.dto.response.GatheringApplicantsResponse; +import solitour_backend.solitour.gathering_applicants.entity.GatheringApplicants; import solitour_backend.solitour.gathering_applicants.entity.GatheringStatus; import solitour_backend.solitour.gathering_applicants.exception.GatheringNotManagerException; import solitour_backend.solitour.gathering_applicants.repository.GatheringApplicantsRepository; @@ -103,16 +104,13 @@ public GatheringDetailResponse getGatheringDetail(Long userId, Long gatheringId) PlaceResponse placeResponse = placeMapper.mapToPlaceResponse(gathering.getPlace()); - ZoneCategoryResponse zoneCategoryResponse = zoneCategoryMapper.mapToZoneCategoryResponse( - gathering.getZoneCategory()); + ZoneCategoryResponse zoneCategoryResponse = zoneCategoryMapper.mapToZoneCategoryResponse(gathering.getZoneCategory()); int likeCount = greatGatheringRepository.countByGatheringId(gathering.getId()); - List gatheringApplicantsResponses = gatheringApplicantsMapper.mapToGatheringApplicantsResponses( - gatheringApplicantsRepository.findAllByGathering_Id(gathering.getId())); + List gatheringApplicantsResponses = gatheringApplicantsMapper.mapToGatheringApplicantsResponses(gatheringApplicantsRepository.findAllByGathering_IdAndUserIdNot(gathering.getId(), gathering.getUser().getId())); - int nowPersonCount = gatheringApplicantsRepository.countAllByGathering_IdAndGatheringStatus(gathering.getId(), - GatheringStatus.CONSENT); + int nowPersonCount = gatheringApplicantsRepository.countAllByGathering_IdAndGatheringStatus(gathering.getId(), GatheringStatus.CONSENT); boolean isLike = greatGatheringRepository.existsByGatheringIdAndUserIdAndIsDeletedFalse(gathering.getId(), userId); @@ -160,19 +158,16 @@ public GatheringResponse registerGathering(Long userId, GatheringRegisterRequest User user = userRepository.findById(userId) .orElseThrow( () -> new UserNotExistsException("해당하는 id의 User 가 없습니다")); - GatheringCategory gatheringCategory = gatheringCategoryRepository.findById( - gatheringRegisterRequest.getGatheringCategoryId()) + GatheringCategory gatheringCategory = gatheringCategoryRepository.findById(gatheringRegisterRequest.getGatheringCategoryId()) .orElseThrow( () -> new GatheringCategoryNotExistsException("해당하는 id의 category 가 없습니다")); - ZoneCategory parentZoneCategory = zoneCategoryRepository.findByParentZoneCategoryIdAndName( - null, gatheringRegisterRequest.getZoneCategoryNameParent()) + ZoneCategory parentZoneCategory = zoneCategoryRepository.findByParentZoneCategoryIdAndName(null, gatheringRegisterRequest.getZoneCategoryNameParent()) .orElseThrow( () -> new ZoneCategoryNotExistsException("해당하는 name의 ZoneCategory 없습니다")); - ZoneCategory childZoneCategory = zoneCategoryRepository.findByParentZoneCategoryIdAndName( - parentZoneCategory.getId(), gatheringRegisterRequest.getZoneCategoryNameChild()) + ZoneCategory childZoneCategory = zoneCategoryRepository.findByParentZoneCategoryIdAndName(parentZoneCategory.getId(), gatheringRegisterRequest.getZoneCategoryNameChild()) .orElseThrow( () -> new ZoneCategoryNotExistsException("해당하는 name의 ZoneCategory 없습니다")); @@ -199,6 +194,8 @@ public GatheringResponse registerGathering(Long userId, GatheringRegisterRequest List tags = tagMapper.mapToTags(gatheringRegisterRequest.getTagRegisterRequests()); List saveTags = tagRepository.saveAll(tags); + new GatheringApplicants(gathering, user, GatheringStatus.CONSENT); + for (Tag tag : saveTags) { gatheringTagRepository.save(new GatheringTag(tag, saveGathering)); } From d3c2f37666d26c6ad2d8570a7a3510b26fd2618d Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Wed, 21 Aug 2024 01:42:34 +0900 Subject: [PATCH 125/371] =?UTF-8?q?feat:=20=ED=95=B4=EB=8B=B9=20=EB=AA=A8?= =?UTF-8?q?=EC=9E=84=20=EB=8B=B4=EB=8B=B9=EC=9E=90=EA=B0=80=20=ED=95=B4?= =?UTF-8?q?=EB=8B=B9=20=EB=AA=A8=EC=9E=84=20=EC=B0=B8=EC=97=AC=20create,?= =?UTF-8?q?=20update,=20delete=20=ED=95=98=EB=A0=A4=EA=B3=A0=20=ED=95=A0?= =?UTF-8?q?=EB=95=8C=20=EC=98=88=EC=99=B8=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/GatheringApplicantsService.java | 24 +++++++++++++------ 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/src/main/java/solitour_backend/solitour/gathering_applicants/service/GatheringApplicantsService.java b/src/main/java/solitour_backend/solitour/gathering_applicants/service/GatheringApplicantsService.java index 18de534a..44cabd8a 100644 --- a/src/main/java/solitour_backend/solitour/gathering_applicants/service/GatheringApplicantsService.java +++ b/src/main/java/solitour_backend/solitour/gathering_applicants/service/GatheringApplicantsService.java @@ -1,6 +1,7 @@ package solitour_backend.solitour.gathering_applicants.service; import java.util.Objects; + import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -10,10 +11,7 @@ import solitour_backend.solitour.gathering_applicants.dto.request.GatheringApplicantsModifyRequest; import solitour_backend.solitour.gathering_applicants.entity.GatheringApplicants; import solitour_backend.solitour.gathering_applicants.entity.GatheringStatus; -import solitour_backend.solitour.gathering_applicants.exception.GatheringApplicantsAlreadyExistsException; -import solitour_backend.solitour.gathering_applicants.exception.GatheringApplicantsAlreadyFullPeopleException; -import solitour_backend.solitour.gathering_applicants.exception.GatheringApplicantsNotExistsException; -import solitour_backend.solitour.gathering_applicants.exception.GatheringNotManagerException; +import solitour_backend.solitour.gathering_applicants.exception.*; import solitour_backend.solitour.gathering_applicants.repository.GatheringApplicantsRepository; import solitour_backend.solitour.user.entity.User; import solitour_backend.solitour.user.entity.UserRepository; @@ -38,6 +36,10 @@ public void participateGatheringFromAnotherUser(Long userId, Long gatheringId) { () -> new UserNotExistsException("해당하는 id의 user가 없습니다")); + if (Objects.equals(gathering.getUser(), user)) { + throw new GatheringApplicantsManagerException("모임을 만든 사람은 해당 모임에 무조건 참여 하여 이미 있습니다"); + } + if (gatheringApplicantsRepository.existsByGatheringIdAndUserId(gathering.getId(), user.getId())) { throw new GatheringApplicantsAlreadyExistsException("해당 유저는 이미 참여 해 있습니다."); } @@ -64,14 +66,18 @@ public void deleteGatheringApplicantsFromAnotherUser(Long userId, Long gathering User user = userRepository.findById(userId) .orElseThrow( () -> - new UserNotExistsException("해당하는 id의 user가 없습니다")); + new UserNotExistsException("해당하는 id의 user 가 없습니다")); + + if (Objects.equals(gathering.getUser(), user)) { + throw new GatheringApplicantsManagerException("모임을 만든 사람은 해당 모임에 빠질 수 없습니다."); + } GatheringApplicants gatheringApplicants = gatheringApplicantsRepository.findByGatheringIdAndUserId( gathering.getId(), user.getId()) .orElseThrow( () -> new GatheringApplicantsNotExistsException( - "해당하는 모임과 user의 gathering applicants가 없습니다.")); + "해당하는 모임과 user 의 gathering applicants 가 없습니다.")); gatheringApplicantsRepository.delete(gatheringApplicants); } @@ -86,7 +92,7 @@ public boolean updateGatheringApplicantsManagement(Long userId, Long gatheringId User user = userRepository.findById(userId) .orElseThrow( () -> - new UserNotExistsException("해당하는 id의 user가 없습니다")); + new UserNotExistsException("해당하는 id의 user 가 없습니다")); if (!Objects.equals(gathering.getUser(), user)) { throw new GatheringNotManagerException("해당하는 user 가 해당 gathering 의 manage 가 아닙니다"); @@ -99,6 +105,10 @@ public boolean updateGatheringApplicantsManagement(Long userId, Long gatheringId new GatheringApplicantsNotExistsException("해당하는 모임, user 의 applicants 가 없습니다") ); + if (Objects.equals(gathering.getUser(), gatheringApplicants.getUser())) { + throw new GatheringApplicantsManagerException("모임을 만든 사람은 해당 모임 참여에 대한 수정이 불가 합니다."); + } + if (Objects.equals(gatheringApplicants.getGatheringStatus(), gatheringApplicantsModifyRequest.getGatheringStatus())) { return false; From 985426ef4f93b0d3ec0e644720b8f7783ca6378d Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Wed, 21 Aug 2024 01:43:12 +0900 Subject: [PATCH 126/371] fix: dto validation exception bindingResult --- .../controller/GatheringApplicantsController.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/main/java/solitour_backend/solitour/gathering_applicants/controller/GatheringApplicantsController.java b/src/main/java/solitour_backend/solitour/gathering_applicants/controller/GatheringApplicantsController.java index 2b73d214..d41ef2d3 100644 --- a/src/main/java/solitour_backend/solitour/gathering_applicants/controller/GatheringApplicantsController.java +++ b/src/main/java/solitour_backend/solitour/gathering_applicants/controller/GatheringApplicantsController.java @@ -4,6 +4,7 @@ import lombok.RequiredArgsConstructor; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; +import org.springframework.validation.BindingResult; import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; @@ -12,6 +13,7 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import solitour_backend.solitour.auth.config.AuthenticationPrincipal; +import solitour_backend.solitour.error.Utils; import solitour_backend.solitour.gathering_applicants.dto.request.GatheringApplicantsModifyRequest; import solitour_backend.solitour.gathering_applicants.service.GatheringApplicantsService; @@ -44,7 +46,9 @@ public ResponseEntity deleteParticipateGathering(@AuthenticationPrincipal @PutMapping("/{gatheringId}") public ResponseEntity updateParticipateGatheringStatus(@AuthenticationPrincipal Long userId, @PathVariable Long gatheringId, - @Valid @RequestBody GatheringApplicantsModifyRequest gatheringApplicantsModifyRequest) { + @Valid @RequestBody GatheringApplicantsModifyRequest gatheringApplicantsModifyRequest, + BindingResult bindingResult) { + Utils.validationRequest(bindingResult); boolean result = gatheringApplicantsService.updateGatheringApplicantsManagement(userId, gatheringId, gatheringApplicantsModifyRequest); From efee547f28ab79c6109b26501e7191a46ac7f446 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Thu, 22 Aug 2024 00:29:50 +0900 Subject: [PATCH 127/371] =?UTF-8?q?fix:=20gathering=20=ED=8E=98=EC=9D=B4?= =?UTF-8?q?=EC=A7=80=EB=84=A4=EC=9D=B4=EC=85=98=20=EC=98=A4=EB=A5=98=20?= =?UTF-8?q?=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../repository/GatheringRepositoryImpl.java | 50 +++++++++++++++---- 1 file changed, 39 insertions(+), 11 deletions(-) diff --git a/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryImpl.java b/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryImpl.java index 2599fe73..31f66d9a 100644 --- a/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryImpl.java +++ b/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryImpl.java @@ -9,10 +9,16 @@ import java.time.LocalTime; import java.util.List; import java.util.Objects; +import java.util.Optional; import com.querydsl.core.types.dsl.*; import com.querydsl.jpa.JPAExpressions; import com.querydsl.jpa.JPQLQuery; +import com.querydsl.jpa.impl.JPAQuery; +import com.querydsl.jpa.impl.JPAQueryFactory; +import jakarta.annotation.PostConstruct; +import jakarta.persistence.EntityManager; +import jakarta.persistence.PersistenceContext; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageImpl; import org.springframework.data.domain.Pageable; @@ -30,10 +36,21 @@ import solitour_backend.solitour.zone_category.entity.QZoneCategory; public class GatheringRepositoryImpl extends QuerydslRepositorySupport implements GatheringRepositoryCustom { + + @PersistenceContext + private EntityManager entityManager; + + private JPAQueryFactory queryFactory; + public GatheringRepositoryImpl() { super(Gathering.class); } + @PostConstruct + private void init() { + this.queryFactory = new JPAQueryFactory(entityManager); + } + QGathering gathering = QGathering.gathering; QZoneCategory zoneCategoryChild = QZoneCategory.zoneCategory; @@ -106,18 +123,18 @@ public Page getGatheringPageFilterAndOrder(Pageable page NumberExpression countGreatGathering = countGreatGatheringByGatheringById(); - List content = from(gathering) + JPAQuery countQuery = queryFactory + .select(gathering.id.count()) + .from(gathering) .join(zoneCategoryChild).on(zoneCategoryChild.id.eq(gathering.zoneCategory.id)) .leftJoin(zoneCategoryParent).on(zoneCategoryParent.id.eq(zoneCategoryChild.parentZoneCategory.id)) .leftJoin(bookMarkGathering).on(bookMarkGathering.gathering.id.eq(gathering.id).and(bookMarkGathering.user.id.eq(userId))) .leftJoin(gatheringApplicants).on(gatheringApplicants.gathering.id.eq(gathering.id)) - .where(booleanBuilder) - .groupBy(gathering.id, zoneCategoryChild.id, zoneCategoryParent.id, category.id, - gathering.title, gathering.viewCount, gathering.user.name, - gathering.scheduleStartDate, gathering.scheduleEndDate, - gathering.deadline, gathering.allowedSex, - gathering.startAge, gathering.endAge, gathering.personCount) - .orderBy(orderSpecifier) + .where(booleanBuilder); + + long total = Optional.ofNullable(countQuery.fetchOne()).orElse(0L); + + List content = queryFactory .select(Projections.constructor( GatheringBriefResponse.class, gathering.id, @@ -145,12 +162,23 @@ public Page getGatheringPageFilterAndOrder(Pageable page .exists()) .then(true) .otherwise(false) - )).offset(pageable.getOffset()) + )) + .from(gathering) + .join(zoneCategoryChild).on(zoneCategoryChild.id.eq(gathering.zoneCategory.id)) + .leftJoin(zoneCategoryParent).on(zoneCategoryParent.id.eq(zoneCategoryChild.parentZoneCategory.id)) + .leftJoin(bookMarkGathering).on(bookMarkGathering.gathering.id.eq(gathering.id).and(bookMarkGathering.user.id.eq(userId))) + .leftJoin(gatheringApplicants).on(gatheringApplicants.gathering.id.eq(gathering.id)) + .where(booleanBuilder) + .groupBy(gathering.id, zoneCategoryChild.id, zoneCategoryParent.id, category.id, + gathering.title, gathering.viewCount, gathering.user.name, + gathering.scheduleStartDate, gathering.scheduleEndDate, + gathering.deadline, gathering.allowedSex, + gathering.startAge, gathering.endAge, gathering.personCount) + .orderBy(orderSpecifier) + .offset(pageable.getOffset()) .limit(pageable.getPageSize()) .fetch(); - long total = content.size(); - return new PageImpl<>(content, pageable, total); } From dd21d404617ae7ab77c22a4baa54f478822743a8 Mon Sep 17 00:00:00 2001 From: Donghun Won Date: Thu, 22 Aug 2024 19:20:19 +0900 Subject: [PATCH 128/371] =?UTF-8?q?Feat=20:=20=EC=9C=A0=EC=A0=80=20?= =?UTF-8?q?=EC=9D=B4=EB=AF=B8=EC=A7=80=20=EC=97=85=EB=8D=B0=EC=9D=B4?= =?UTF-8?q?=ED=8A=B8=20,=20=EC=9C=A0=EC=A0=80=20=EC=A0=95=EB=B3=B4=20?= =?UTF-8?q?=EB=B0=98=ED=99=98=20Response=EC=97=90=20=EC=9C=A0=EC=A0=80=20?= =?UTF-8?q?=EC=83=9D=EC=84=B1=EC=9D=BC,=20oauth=20provider=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80=20(#90)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Feat : 유저이미지 업데이트 * Feat : 유저 정보 반환 response에 로그인 생성일, oauth provider 필드 추가 --- .../solitour/user/controller/UserController.java | 14 ++++++++++++++ .../solitour/user/service/UserService.java | 8 ++++++++ .../service/dto/response/UserInfoResponse.java | 5 +++++ .../solitour/user_image/entity/UserImage.java | 4 ++++ 4 files changed, 31 insertions(+) diff --git a/src/main/java/solitour_backend/solitour/user/controller/UserController.java b/src/main/java/solitour_backend/solitour/user/controller/UserController.java index 496c5bd9..9a7b8d8e 100644 --- a/src/main/java/solitour_backend/solitour/user/controller/UserController.java +++ b/src/main/java/solitour_backend/solitour/user/controller/UserController.java @@ -73,6 +73,20 @@ public ResponseEntity updateAgeAndSex(@AuthenticationPrincipal Long user } } + @Authenticated + @PutMapping("/image") + public ResponseEntity updateUserImage(@AuthenticationPrincipal Long userId, + @RequestParam String userImage) { + try { + userService.updateUserImage(userId, userImage); + return ResponseEntity.ok("UserImage updated successfully"); + } catch (UserNotExistsException e) { + return ResponseEntity.status(HttpStatus.NOT_FOUND).body("User not found"); + } catch (Exception e) { + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("An internal error occurred"); + } + } + @Authenticated @DeleteMapping() public ResponseEntity deleteUser(HttpServletResponse response, @AuthenticationPrincipal Long id, diff --git a/src/main/java/solitour_backend/solitour/user/service/UserService.java b/src/main/java/solitour_backend/solitour/user/service/UserService.java index 38b84f52..c6d88367 100644 --- a/src/main/java/solitour_backend/solitour/user/service/UserService.java +++ b/src/main/java/solitour_backend/solitour/user/service/UserService.java @@ -7,6 +7,7 @@ import solitour_backend.solitour.user.entity.UserRepository; import solitour_backend.solitour.user.exception.NicknameAlreadyExistsException; import solitour_backend.solitour.user.service.dto.response.UserInfoResponse; +import solitour_backend.solitour.user_image.entity.UserImage; @Service @RequiredArgsConstructor @@ -42,4 +43,11 @@ public void deleteUser(Long userId) { User user = userRepository.findByUserId(userId); user.deleteUser(userId); } + + @Transactional + public void updateUserImage(Long userId, String updateImage) { + User user = userRepository.findByUserId(userId); + UserImage userImage = user.getUserImage(); + userImage.updateUserImage(updateImage); + } } diff --git a/src/main/java/solitour_backend/solitour/user/service/dto/response/UserInfoResponse.java b/src/main/java/solitour_backend/solitour/user/service/dto/response/UserInfoResponse.java index 9e0e6e8d..ff2b475b 100644 --- a/src/main/java/solitour_backend/solitour/user/service/dto/response/UserInfoResponse.java +++ b/src/main/java/solitour_backend/solitour/user/service/dto/response/UserInfoResponse.java @@ -1,5 +1,6 @@ package solitour_backend.solitour.user.service.dto.response; +import java.time.LocalDateTime; import lombok.Getter; import solitour_backend.solitour.user.entity.User; import solitour_backend.solitour.user_image.entity.UserImage; @@ -14,7 +15,9 @@ public class UserInfoResponse { private final Integer age; private final String sex; private final String email; + private final String provider; private final String phoneNumber; + private final LocalDateTime createdAt; private final Boolean isAdmin; public UserInfoResponse(User user) { @@ -25,7 +28,9 @@ public UserInfoResponse(User user) { this.age = user.getAge(); this.sex = user.getSex(); this.email = user.getEmail(); + this.provider = user.getProvider(); this.phoneNumber = user.getPhoneNumber(); + this.createdAt = user.getCreatedAt(); this.isAdmin = user.getIsAdmin(); } } diff --git a/src/main/java/solitour_backend/solitour/user_image/entity/UserImage.java b/src/main/java/solitour_backend/solitour/user_image/entity/UserImage.java index 62062a56..c9c0ac49 100644 --- a/src/main/java/solitour_backend/solitour/user_image/entity/UserImage.java +++ b/src/main/java/solitour_backend/solitour/user_image/entity/UserImage.java @@ -31,4 +31,8 @@ public UserImage(String address, LocalDate createdDate) { this.address = address; this.createdDate = createdDate; } + + public void updateUserImage(String userImage) { + this.address = userImage; + } } From 5c5b7163050556047fcd25fd6e3e9eb2423ed0f8 Mon Sep 17 00:00:00 2001 From: Donghun Won Date: Thu, 22 Aug 2024 19:23:55 +0900 Subject: [PATCH 129/371] =?UTF-8?q?Feat(#91):=20=EC=97=AC=ED=96=89?= =?UTF-8?q?=EC=9D=BC=EA=B8=B0=20=20(#92)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Feat : 여행 일기 crud * Feat : 타이틀 이미지 필드 추가 --- .../diary/controller/DiaryController.java | 60 +++++++++++++ .../diary_day_content/DiaryDayContent.java | 60 +++++++++++++ .../solitour/diary/dto/DiaryRequest.java | 24 +++++ .../solitour/diary/dto/DiaryResponse.java | 63 +++++++++++++ .../solitour/diary/entity/Diary.java | 87 ++++++++++++++++++ .../diary/feeling_status/FeelingStatus.java | 26 ++++++ .../FeelingStatusConverter.java | 18 ++++ .../repository/DiaryDayContentRepository.java | 11 +++ .../diary/repository/DiaryRepository.java | 14 +++ .../solitour/diary/service/DiaryService.java | 89 +++++++++++++++++++ 10 files changed, 452 insertions(+) create mode 100644 src/main/java/solitour_backend/solitour/diary/controller/DiaryController.java create mode 100644 src/main/java/solitour_backend/solitour/diary/diary_day_content/DiaryDayContent.java create mode 100644 src/main/java/solitour_backend/solitour/diary/dto/DiaryRequest.java create mode 100644 src/main/java/solitour_backend/solitour/diary/dto/DiaryResponse.java create mode 100644 src/main/java/solitour_backend/solitour/diary/entity/Diary.java create mode 100644 src/main/java/solitour_backend/solitour/diary/feeling_status/FeelingStatus.java create mode 100644 src/main/java/solitour_backend/solitour/diary/feeling_status/FeelingStatusConverter.java create mode 100644 src/main/java/solitour_backend/solitour/diary/repository/DiaryDayContentRepository.java create mode 100644 src/main/java/solitour_backend/solitour/diary/repository/DiaryRepository.java create mode 100644 src/main/java/solitour_backend/solitour/diary/service/DiaryService.java diff --git a/src/main/java/solitour_backend/solitour/diary/controller/DiaryController.java b/src/main/java/solitour_backend/solitour/diary/controller/DiaryController.java new file mode 100644 index 00000000..42da3a11 --- /dev/null +++ b/src/main/java/solitour_backend/solitour/diary/controller/DiaryController.java @@ -0,0 +1,60 @@ +package solitour_backend.solitour.diary.controller; + +import lombok.RequiredArgsConstructor; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; +import solitour_backend.solitour.auth.config.Authenticated; +import solitour_backend.solitour.auth.config.AuthenticationPrincipal; +import solitour_backend.solitour.diary.dto.DiaryRequest; +import solitour_backend.solitour.diary.dto.DiaryResponse; +import solitour_backend.solitour.diary.service.DiaryService; + +@RestController +@RequiredArgsConstructor +@RequestMapping("/api/diary") +public class DiaryController { + + private final DiaryService diaryService; + + @Authenticated + @GetMapping() + public ResponseEntity getDiary(@AuthenticationPrincipal Long userId) { + DiaryResponse response = diaryService.getDiary(userId); + + return ResponseEntity.ok(response); + } + + @Authenticated + @PostMapping() + public ResponseEntity createDiary(@AuthenticationPrincipal Long userId, + @RequestBody DiaryRequest request) { + diaryService.createDiary(userId,request); + + return ResponseEntity.status(HttpStatus.CREATED).build(); + } + + @Authenticated + @PutMapping() + public ResponseEntity updateDiary(@AuthenticationPrincipal Long userId,@RequestParam Long diaryId, + @RequestBody DiaryRequest request) { + diaryService.updateDiary(userId,diaryId,request); + + return ResponseEntity.status(HttpStatus.OK).build(); + } + + @Authenticated + @DeleteMapping() + public ResponseEntity deleteDiary(@AuthenticationPrincipal Long userId,@RequestParam Long diaryId) { + diaryService.deleteDiary(userId,diaryId); + + return ResponseEntity.status(HttpStatus.OK).build(); + } +} diff --git a/src/main/java/solitour_backend/solitour/diary/diary_day_content/DiaryDayContent.java b/src/main/java/solitour_backend/solitour/diary/diary_day_content/DiaryDayContent.java new file mode 100644 index 00000000..f3317710 --- /dev/null +++ b/src/main/java/solitour_backend/solitour/diary/diary_day_content/DiaryDayContent.java @@ -0,0 +1,60 @@ +package solitour_backend.solitour.diary.diary_day_content; + +import jakarta.persistence.Column; +import jakarta.persistence.Convert; +import jakarta.persistence.Entity; +import jakarta.persistence.EntityListeners; +import jakarta.persistence.FetchType; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.ManyToOne; +import jakarta.persistence.Table; +import java.time.LocalDateTime; +import java.util.List; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import org.springframework.data.annotation.CreatedDate; +import org.springframework.data.annotation.LastModifiedDate; +import org.springframework.data.jpa.domain.support.AuditingEntityListener; +import solitour_backend.solitour.diary.dto.DiaryRequest.DiaryDayRequest; +import solitour_backend.solitour.diary.entity.Diary; +import solitour_backend.solitour.diary.feeling_status.FeelingStatus; +import solitour_backend.solitour.diary.feeling_status.FeelingStatusConverter; +import solitour_backend.solitour.gathering.entity.AllowedSex; +import solitour_backend.solitour.gathering.entity.AllowedSexConverter; +import solitour_backend.solitour.user.entity.User; + +@Entity +@Getter +@Table(name = "diary_day_content") +@Builder +@NoArgsConstructor +@AllArgsConstructor +@EntityListeners(AuditingEntityListener.class) +public class DiaryDayContent { + + @Id + @Column(name = "diary_day_content_id") + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "diary_id") + private Diary diary; + + @Column(name = "diary_day_content_place") + private String place; + + @Column(columnDefinition = "LONGTEXT", name = "diary_day_content_content") + private String content; + + @Column(name = "diary_day_content_feeling_status") + @Convert(converter = FeelingStatusConverter.class) + private FeelingStatus feelingStatus; + +} diff --git a/src/main/java/solitour_backend/solitour/diary/dto/DiaryRequest.java b/src/main/java/solitour_backend/solitour/diary/dto/DiaryRequest.java new file mode 100644 index 00000000..4501c7c0 --- /dev/null +++ b/src/main/java/solitour_backend/solitour/diary/dto/DiaryRequest.java @@ -0,0 +1,24 @@ +package solitour_backend.solitour.diary.dto; + +import java.time.LocalDateTime; +import java.util.List; +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor +public class DiaryRequest { + private String title; + private String titleImage; + private LocalDateTime startDatetime; + private LocalDateTime endDatetime; + private List diaryDayRequests; + + @Getter + @AllArgsConstructor + public static class DiaryDayRequest { + private String content; + private String feelingStatus; + private String place; + } +} diff --git a/src/main/java/solitour_backend/solitour/diary/dto/DiaryResponse.java b/src/main/java/solitour_backend/solitour/diary/dto/DiaryResponse.java new file mode 100644 index 00000000..d3ddfebb --- /dev/null +++ b/src/main/java/solitour_backend/solitour/diary/dto/DiaryResponse.java @@ -0,0 +1,63 @@ +package solitour_backend.solitour.diary.dto; + +import java.time.LocalDateTime; +import java.util.List; +import java.util.stream.Collectors; +import lombok.Builder; +import lombok.Getter; +import solitour_backend.solitour.diary.diary_day_content.DiaryDayContent; +import solitour_backend.solitour.diary.entity.Diary; + +@Getter +public class DiaryResponse { + private final List diaryContentResponse; + + public DiaryResponse(List diaries) { + + diaryContentResponse= diaries.stream().map( + diary -> DiaryContent.builder() + .diaryId(diary.getId()) + .title(diary.getTitle()) + .startDatetime(diary.getStartDatetime()) + .endDatetime(diary.getEndDatetime()) + .diaryDayContentResponses(new DiaryDayContentResponse(diary.getDiaryDayContent())).build() + ).collect(Collectors.toList()); + + } + + @Getter + @Builder + private static class DiaryContent { + private Long diaryId; + private String title; + private LocalDateTime startDatetime; + private LocalDateTime endDatetime; + private DiaryDayContentResponse diaryDayContentResponses; + } + + @Getter + private static class DiaryDayContentResponse { + + private final List diaryDayContentDetail; + + private DiaryDayContentResponse(List diaryDayContent) { + this.diaryDayContentDetail = diaryDayContent.stream() + .map(diaryDayContentDetail -> + DiaryDayContentDetail.builder() + .content(diaryDayContentDetail.getContent()) + .feelingStatus(diaryDayContentDetail.getFeelingStatus().name()) + .place(diaryDayContentDetail.getPlace()) + .build() + ).collect(Collectors.toList()); + } + + } + @Getter + @Builder + private static class DiaryDayContentDetail { + private String content; + private String feelingStatus; + private String place; + } + +} diff --git a/src/main/java/solitour_backend/solitour/diary/entity/Diary.java b/src/main/java/solitour_backend/solitour/diary/entity/Diary.java new file mode 100644 index 00000000..59df6a8f --- /dev/null +++ b/src/main/java/solitour_backend/solitour/diary/entity/Diary.java @@ -0,0 +1,87 @@ +package solitour_backend.solitour.diary.entity; + +import jakarta.persistence.CascadeType; +import jakarta.persistence.Column; +import jakarta.persistence.Convert; +import jakarta.persistence.Entity; +import jakarta.persistence.EntityListeners; +import jakarta.persistence.FetchType; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.ManyToOne; +import jakarta.persistence.OneToMany; +import jakarta.persistence.Table; +import java.time.LocalDateTime; +import java.util.List; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import org.springframework.data.annotation.CreatedDate; +import org.springframework.data.annotation.LastModifiedDate; +import org.springframework.data.jpa.domain.support.AuditingEntityListener; +import solitour_backend.solitour.diary.diary_day_content.DiaryDayContent; +import solitour_backend.solitour.diary.dto.DiaryRequest; +import solitour_backend.solitour.diary.dto.DiaryRequest.DiaryDayRequest; +import solitour_backend.solitour.diary.feeling_status.FeelingStatus; +import solitour_backend.solitour.diary.feeling_status.FeelingStatusConverter; +import solitour_backend.solitour.gathering.entity.AllowedSex; +import solitour_backend.solitour.gathering.entity.AllowedSexConverter; +import solitour_backend.solitour.gathering_category.entity.GatheringCategory; +import solitour_backend.solitour.place.entity.Place; +import solitour_backend.solitour.user.entity.User; +import solitour_backend.solitour.user.user_status.UserStatusConverter; +import solitour_backend.solitour.zone_category.entity.ZoneCategory; + + +@Entity +@Getter +@Table(name = "diary") +@NoArgsConstructor +@Builder +@AllArgsConstructor +@EntityListeners(AuditingEntityListener.class) +public class Diary { + + @Id + @Column(name = "diary_id") + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "user_id") + private User user; + + @Column(name = "diary_title") + private String title; + + @Column(name = "diary_title_image") + private String titleImage; + + @Column(name = "diary_start_date") + private LocalDateTime startDatetime; + + @Column(name = "diary_end_date") + private LocalDateTime endDatetime; + + @OneToMany(fetch = FetchType.LAZY,cascade = CascadeType.ALL, orphanRemoval = true, mappedBy = "diary") + private List diaryDayContent; + + @CreatedDate + @Column(name = "diary_created_date") + private LocalDateTime createdAt; + + @LastModifiedDate + @Column(name = "diary_edited_date") + private LocalDateTime editedAt; + + public void updateDiary(DiaryRequest request) { + this.title = request.getTitle(); + this.titleImage = request.getTitleImage(); + this.startDatetime = request.getStartDatetime(); + this.endDatetime = request.getEndDatetime(); + } +} diff --git a/src/main/java/solitour_backend/solitour/diary/feeling_status/FeelingStatus.java b/src/main/java/solitour_backend/solitour/diary/feeling_status/FeelingStatus.java new file mode 100644 index 00000000..a8307382 --- /dev/null +++ b/src/main/java/solitour_backend/solitour/diary/feeling_status/FeelingStatus.java @@ -0,0 +1,26 @@ +package solitour_backend.solitour.diary.feeling_status; + +import java.util.Arrays; +import lombok.Getter; + +@Getter +public enum FeelingStatus { + EXCITED("최고"), + NICE("좋아"), + SOSO("무난"), + SAD("슬퍼"), + ANGRY("화나"); + + private final String status; + + FeelingStatus(String status) { + this.status = status; + } + + public static FeelingStatus fromName(String status) { + return Arrays.stream(FeelingStatus.values()) + .filter(e -> e.getStatus().equals(status)) + .findAny() + .orElse(null); + } +} diff --git a/src/main/java/solitour_backend/solitour/diary/feeling_status/FeelingStatusConverter.java b/src/main/java/solitour_backend/solitour/diary/feeling_status/FeelingStatusConverter.java new file mode 100644 index 00000000..195d5cc1 --- /dev/null +++ b/src/main/java/solitour_backend/solitour/diary/feeling_status/FeelingStatusConverter.java @@ -0,0 +1,18 @@ +package solitour_backend.solitour.diary.feeling_status; + +import jakarta.persistence.AttributeConverter; +import jakarta.persistence.Converter; + +@Converter(autoApply = true) +public class FeelingStatusConverter implements AttributeConverter { + + @Override + public String convertToDatabaseColumn(FeelingStatus userStatus) { + return userStatus.getStatus(); + } + + @Override + public FeelingStatus convertToEntityAttribute(String dbData) { + return FeelingStatus.fromName(dbData); + } +} diff --git a/src/main/java/solitour_backend/solitour/diary/repository/DiaryDayContentRepository.java b/src/main/java/solitour_backend/solitour/diary/repository/DiaryDayContentRepository.java new file mode 100644 index 00000000..836f4370 --- /dev/null +++ b/src/main/java/solitour_backend/solitour/diary/repository/DiaryDayContentRepository.java @@ -0,0 +1,11 @@ +package solitour_backend.solitour.diary.repository; + +import java.util.Optional; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import solitour_backend.solitour.diary.diary_day_content.DiaryDayContent; +import solitour_backend.solitour.diary.entity.Diary; +import solitour_backend.solitour.user.entity.User; + +public interface DiaryDayContentRepository extends JpaRepository { +} diff --git a/src/main/java/solitour_backend/solitour/diary/repository/DiaryRepository.java b/src/main/java/solitour_backend/solitour/diary/repository/DiaryRepository.java new file mode 100644 index 00000000..efd2dd58 --- /dev/null +++ b/src/main/java/solitour_backend/solitour/diary/repository/DiaryRepository.java @@ -0,0 +1,14 @@ +package solitour_backend.solitour.diary.repository; + +import java.util.List; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import solitour_backend.solitour.diary.entity.Diary; + +public interface DiaryRepository extends JpaRepository { + @Query("SELECT d FROM Diary d WHERE d.user.id = :userId") + List findByUserId(Long userId); + + @Query("DELETE FROM Diary d WHERE d.user.id = :userId") + void deleteByUserId(Long userId); +} diff --git a/src/main/java/solitour_backend/solitour/diary/service/DiaryService.java b/src/main/java/solitour_backend/solitour/diary/service/DiaryService.java new file mode 100644 index 00000000..bbcf8753 --- /dev/null +++ b/src/main/java/solitour_backend/solitour/diary/service/DiaryService.java @@ -0,0 +1,89 @@ +package solitour_backend.solitour.diary.service; + +import java.time.LocalDateTime; +import java.util.List; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import solitour_backend.solitour.diary.diary_day_content.DiaryDayContent; +import solitour_backend.solitour.diary.dto.DiaryRequest; +import solitour_backend.solitour.diary.dto.DiaryRequest.DiaryDayRequest; +import solitour_backend.solitour.diary.dto.DiaryResponse; +import solitour_backend.solitour.diary.entity.Diary; +import solitour_backend.solitour.diary.feeling_status.FeelingStatus; +import solitour_backend.solitour.diary.repository.DiaryDayContentRepository; +import solitour_backend.solitour.diary.repository.DiaryRepository; +import solitour_backend.solitour.user.entity.User; +import solitour_backend.solitour.user.entity.UserRepository; + + +@Service +@Transactional(readOnly = true) +@RequiredArgsConstructor +public class DiaryService { + private final DiaryRepository diaryRepository; + private final DiaryDayContentRepository diaryDayContentRepository; + private final UserRepository userRepository; + + @Transactional + public void createDiary(Long userId, DiaryRequest request) { + User user = userRepository.findByUserId(userId); + Diary diary = Diary.builder() + .user(user) + .title(request.getTitle()) + .titleImage(request.getTitleImage()) + .startDatetime(request.getStartDatetime()) + .endDatetime(request.getEndDatetime()) + .createdAt(LocalDateTime.now()) + .build(); + + Diary savedDiary = diaryRepository.save(diary); + + saveDiaryDayContent(savedDiary, request); + } + + + private void saveDiaryDayContent(Diary savedDiary, DiaryRequest request) { + for (DiaryDayRequest dayRequest : request.getDiaryDayRequests()) { + DiaryDayContent diaryDayContent = DiaryDayContent.builder() + .diary(savedDiary) + .content(dayRequest.getContent()) + .feelingStatus(FeelingStatus.valueOf(dayRequest.getFeelingStatus())) + .place(dayRequest.getPlace()) + .build(); + diaryDayContentRepository.save(diaryDayContent); + } + } + + public DiaryResponse getDiary(Long userId) { + List diaries = diaryRepository.findByUserId(userId); + return new DiaryResponse(diaries); + } + + @Transactional + public void deleteDiary(Long userId, Long diaryId) { + Diary diary = diaryRepository.findById(diaryId) + .orElseThrow(() -> new IllegalArgumentException("해당 일기가 존재하지 않습니다.")); + if(!diary.getUser().getId().equals(userId)) { + throw new IllegalArgumentException("해당 일기에 대한 권한이 없습니다."); + } + diaryRepository.deleteById(diaryId); + } + + @Transactional + public void updateDiary(Long userId, Long diaryId, DiaryRequest request) { + Diary diary = diaryRepository.findById(diaryId) + .orElseThrow(() -> new IllegalArgumentException("해당 일기가 존재하지 않습니다.")); + if (!diary.getUser().getId().equals(userId)) { + throw new IllegalArgumentException("해당 일기에 대한 권한이 없습니다."); + } + updateDiary(diaryId,request); + } + + private void updateDiary(Long diaryId,DiaryRequest request) { + Diary diary = diaryRepository.findById(diaryId).orElseThrow(() -> new RuntimeException("Diary not found")); + diary.getDiaryDayContent().clear(); + diary.updateDiary(request); + saveDiaryDayContent(diary, request); + } +} \ No newline at end of file From f8be1cad7f9ba6ff8037ee17e7620caefa3a70ad Mon Sep 17 00:00:00 2001 From: Donghun Won Date: Thu, 22 Aug 2024 19:25:51 +0900 Subject: [PATCH 130/371] =?UTF-8?q?Feat=20:=20Image=20=EC=97=85=EB=A1=9C?= =?UTF-8?q?=EB=93=9C=20=EA=B8=B0=EB=8A=A5=20(#94)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../image/controller/ImageController.java | 44 +++++++++++++++++ .../solitour/image/entity/Image.java | 6 +++ .../image/image_status/ImageStatus.java | 3 +- .../solitour/image/service/ImageService.java | 49 +++++++++++++++++++ 4 files changed, 101 insertions(+), 1 deletion(-) create mode 100644 src/main/java/solitour_backend/solitour/image/controller/ImageController.java create mode 100644 src/main/java/solitour_backend/solitour/image/service/ImageService.java diff --git a/src/main/java/solitour_backend/solitour/image/controller/ImageController.java b/src/main/java/solitour_backend/solitour/image/controller/ImageController.java new file mode 100644 index 00000000..94c6d5a8 --- /dev/null +++ b/src/main/java/solitour_backend/solitour/image/controller/ImageController.java @@ -0,0 +1,44 @@ +package solitour_backend.solitour.image.controller; + +import lombok.RequiredArgsConstructor; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.validation.BindingResult; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RequestPart; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.multipart.MultipartFile; +import solitour_backend.solitour.auth.config.Authenticated; +import solitour_backend.solitour.auth.config.AuthenticationPrincipal; +import solitour_backend.solitour.error.Utils; +import solitour_backend.solitour.image.dto.response.ImageResponse; +import solitour_backend.solitour.image.service.ImageService; +import solitour_backend.solitour.user_image.dto.UserImageRequest; +import solitour_backend.solitour.user_image.dto.UserImageResponse; +import solitour_backend.solitour.user_image.service.UserImageService; + +@RestController +@RequiredArgsConstructor +@RequestMapping("/api/image") +public class ImageController { + + private final ImageService imageService; + + + @Authenticated + @PostMapping + public ResponseEntity uploadImage(@AuthenticationPrincipal Long userId, + @RequestPart("image") MultipartFile userImage, + @RequestParam String imagePath, + @RequestParam String imageStatus) { + ImageResponse informationResponse = imageService.uploadImage(userId, userImage, imagePath, + imageStatus); + + return ResponseEntity + .status(HttpStatus.CREATED) + .body(informationResponse); + } + +} diff --git a/src/main/java/solitour_backend/solitour/image/entity/Image.java b/src/main/java/solitour_backend/solitour/image/entity/Image.java index 5c77f5a9..ec85d381 100644 --- a/src/main/java/solitour_backend/solitour/image/entity/Image.java +++ b/src/main/java/solitour_backend/solitour/image/entity/Image.java @@ -48,4 +48,10 @@ public Image(ImageStatus imageStatus, Information information, String address, L this.address = address; this.createdDate = createdDate; } + + public Image(ImageStatus imageStatus, String imageUrl, LocalDate now) { + this.imageStatus = imageStatus; + this.address = imageUrl; + this.createdDate = now; + } } diff --git a/src/main/java/solitour_backend/solitour/image/image_status/ImageStatus.java b/src/main/java/solitour_backend/solitour/image/image_status/ImageStatus.java index 3c8541b7..2387343f 100644 --- a/src/main/java/solitour_backend/solitour/image/image_status/ImageStatus.java +++ b/src/main/java/solitour_backend/solitour/image/image_status/ImageStatus.java @@ -7,7 +7,8 @@ public enum ImageStatus { THUMBNAIL("썸네일"), CONTENT("본문"), - USER("회원"); + USER("회원"), + NONE("없음"); private final String name; diff --git a/src/main/java/solitour_backend/solitour/image/service/ImageService.java b/src/main/java/solitour_backend/solitour/image/service/ImageService.java new file mode 100644 index 00000000..ed8cda39 --- /dev/null +++ b/src/main/java/solitour_backend/solitour/image/service/ImageService.java @@ -0,0 +1,49 @@ +package solitour_backend.solitour.image.service; + +import java.time.LocalDate; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.multipart.MultipartFile; +import solitour_backend.solitour.image.dto.response.ImageResponse; +import solitour_backend.solitour.image.entity.Image; +import solitour_backend.solitour.image.image_status.ImageStatus; +import solitour_backend.solitour.image.repository.ImageRepository; +import solitour_backend.solitour.image.s3.S3Uploader; +import solitour_backend.solitour.user_image.dto.UserImageResponse; +import solitour_backend.solitour.user_image.entity.UserImage; +import solitour_backend.solitour.user_image.entity.UserImageRepository; + +@RequiredArgsConstructor +@Transactional(readOnly = true) +@Service +public class ImageService { + + private final UserImageRepository userImageRepository; + private final ImageRepository imageRepository; + private final S3Uploader s3Uploader; + + @Transactional + public ImageResponse uploadImage(Long userId, MultipartFile image, String imagePath, String imageStatus) { + String imageUrl = s3Uploader.upload(image, imagePath, userId); + ImageStatus status = checkImageStatus(imageStatus); + Image contentImage = new Image(status, imageUrl, LocalDate.now()); + imageRepository.save(contentImage); + return new ImageResponse(contentImage.getImageStatus().getName(), contentImage.getAddress()); + } + + private ImageStatus checkImageStatus(String imageStatus) { + switch (imageStatus) { + case "CONTENT" -> { + return ImageStatus.CONTENT; + } + case "USER" -> { + return ImageStatus.USER; + } + case "THUMNAIl" -> { + return ImageStatus.THUMBNAIL; + } + } + return ImageStatus.NONE; + } +} From 76b0c461d339f32e2910a19cd9126cae99b0a4ef Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Fri, 23 Aug 2024 02:27:20 +0900 Subject: [PATCH 131/371] =?UTF-8?q?fix:=20gathering=20=EB=AA=A8=EC=A7=91?= =?UTF-8?q?=20=EC=99=84=EB=A3=8C=20=EC=A0=9C=EC=99=B8=20=EC=98=A4=EB=A5=98?= =?UTF-8?q?=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../gathering/repository/GatheringRepositoryImpl.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryImpl.java b/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryImpl.java index 31f66d9a..cf58e843 100644 --- a/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryImpl.java +++ b/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryImpl.java @@ -226,8 +226,8 @@ private BooleanBuilder makeWhereSQL(GatheringPageRequest gatheringPageRequest) { .and(gathering.scheduleEndDate.loe(gatheringPageRequest.getEndDate().atTime(LocalTime.MAX))); } - if (Objects.nonNull(gatheringPageRequest.getIsExclude())) { - whereClause.and(gathering.isFinish.eq(gatheringPageRequest.getIsExclude())); + if (Objects.isNull(gatheringPageRequest.getIsExclude())) { + whereClause.and(gathering.isFinish.eq(false)); } return whereClause; From b20f6834fa76832c741c47eea2e3c756271b8cc0 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Fri, 23 Aug 2024 09:32:31 +0900 Subject: [PATCH 132/371] =?UTF-8?q?feat:=20home=20=EC=97=90=20=EB=B3=B4?= =?UTF-8?q?=EC=97=AC=EC=A7=88=203=EA=B0=9C=EC=9B=94=20=EC=9D=B4=EB=82=B4?= =?UTF-8?q?=EC=97=90=20=EC=83=9D=EC=84=B1=EB=90=98=EA=B3=A0=20=EC=A2=8B?= =?UTF-8?q?=EC=95=84=EC=9A=94=EC=88=9C=EC=9C=BC=EB=A1=9C=20=EC=A0=95?= =?UTF-8?q?=EB=A0=AC=EB=90=9C=20=EB=AA=A8=EC=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../gathering/repository/GatheringRepositoryCustom.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryCustom.java b/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryCustom.java index 58c1f97d..7463330c 100644 --- a/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryCustom.java +++ b/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryCustom.java @@ -19,4 +19,6 @@ public interface GatheringRepositoryCustom { Page getGatheringPageFilterAndOrder(Pageable pageable, GatheringPageRequest gatheringPageRequest, Long userId); List getGatheringRankList(); + + List getGatheringLikeCountFromCreatedIn3(Long userId); } From 4ebf4b07cb34d23ce7765ea5bd3f87f2f106bfc6 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Fri, 23 Aug 2024 09:32:43 +0900 Subject: [PATCH 133/371] =?UTF-8?q?feat:=20home=20=EC=97=90=20=EB=B3=B4?= =?UTF-8?q?=EC=97=AC=EC=A7=88=203=EA=B0=9C=EC=9B=94=20=EC=9D=B4=EB=82=B4?= =?UTF-8?q?=EC=97=90=20=EC=83=9D=EC=84=B1=EB=90=98=EA=B3=A0=20=EC=A2=8B?= =?UTF-8?q?=EC=95=84=EC=9A=94=EC=88=9C=EC=9C=BC=EB=A1=9C=20=EC=A0=95?= =?UTF-8?q?=EB=A0=AC=EB=90=9C=20=EB=AA=A8=EC=9E=84=20repository=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../repository/GatheringRepositoryImpl.java | 47 +++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryImpl.java b/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryImpl.java index cf58e843..aafec60a 100644 --- a/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryImpl.java +++ b/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryImpl.java @@ -196,6 +196,53 @@ public List getGatheringRankList() { )).fetch(); } + @Override + public List getGatheringLikeCountFromCreatedIn3(Long userId) { + NumberExpression likeCount = countGreatGatheringByGatheringById(); + return from(gathering) + .join(zoneCategoryChild).on(zoneCategoryChild.id.eq(gathering.zoneCategory.id)) + .leftJoin(zoneCategoryParent).on(zoneCategoryParent.id.eq(zoneCategoryChild.parentZoneCategory.id)) + .leftJoin(bookMarkGathering) + .on(bookMarkGathering.gathering.id.eq(gathering.id).and(bookMarkGathering.user.id.eq(userId))) + .leftJoin(category).on(category.id.eq(gathering.gatheringCategory.id)) + .leftJoin(gatheringApplicants).on(gatheringApplicants.gathering.id.eq(gathering.id)) + .where(gathering.isFinish.eq(Boolean.FALSE).and(gathering.createdAt.after(LocalDateTime.now().minusMonths(3)))) + .groupBy(gathering.id, zoneCategoryChild.id, zoneCategoryParent.id, category.id, + gathering.title, gathering.viewCount, gathering.user.name, + gathering.scheduleStartDate, gathering.scheduleEndDate, + gathering.deadline, gathering.allowedSex, + gathering.startAge, gathering.endAge, gathering.personCount) + .orderBy(likeCount.desc()) + .select(Projections.constructor( + GatheringBriefResponse.class, + gathering.id, + gathering.title, + zoneCategoryParent.name, + zoneCategoryChild.name, + gathering.viewCount, + bookMarkGathering.user.id.isNotNull(), + likeCount, + category.name, + gathering.user.name, + gathering.scheduleStartDate, + gathering.scheduleEndDate, + gathering.deadline, + gathering.allowedSex, + gathering.startAge, + gathering.endAge, + gathering.personCount, + gatheringApplicants.count().coalesce(0L).intValue(), + new CaseBuilder() + .when(JPAExpressions.selectOne() + .from(greatGathering) + .where(greatGathering.gathering.id.eq(gathering.id) + .and(greatGathering.user.id.eq(userId))) + .exists()) + .then(true) + .otherwise(false) + )).limit(6).fetch(); + } + //where 절 private BooleanBuilder makeWhereSQL(GatheringPageRequest gatheringPageRequest) { From 6ffa7db013b808d55b75b35e26bb885b3bb9a430 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Fri, 23 Aug 2024 09:32:53 +0900 Subject: [PATCH 134/371] =?UTF-8?q?feat:=20home=20=EC=97=90=20=EB=B3=B4?= =?UTF-8?q?=EC=97=AC=EC=A7=88=203=EA=B0=9C=EC=9B=94=20=EC=9D=B4=EB=82=B4?= =?UTF-8?q?=EC=97=90=20=EC=83=9D=EC=84=B1=EB=90=98=EA=B3=A0=20=EC=A2=8B?= =?UTF-8?q?=EC=95=84=EC=9A=94=EC=88=9C=EC=9C=BC=EB=A1=9C=20=EC=A0=95?= =?UTF-8?q?=EB=A0=AC=EB=90=9C=20=EB=AA=A8=EC=9E=84=20service?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../solitour/gathering/service/GatheringService.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main/java/solitour_backend/solitour/gathering/service/GatheringService.java b/src/main/java/solitour_backend/solitour/gathering/service/GatheringService.java index 86a5a62f..f5a81485 100644 --- a/src/main/java/solitour_backend/solitour/gathering/service/GatheringService.java +++ b/src/main/java/solitour_backend/solitour/gathering/service/GatheringService.java @@ -273,6 +273,10 @@ public List getGatheringRankOrderByLikes() { return gatheringRepository.getGatheringRankList(); } + public List getGatheringOrderByLikesFilterByCreate3After(Long userId) { + return gatheringRepository.getGatheringLikeCountFromCreatedIn3(userId); + } + private void validateGatheringPageRequest(GatheringPageRequest gatheringPageRequest) { // Category 검증 From 05809d2461aab15e99e0568d4b19dabf946d3405 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Fri, 23 Aug 2024 09:33:00 +0900 Subject: [PATCH 135/371] =?UTF-8?q?feat:=20home=20=EC=97=90=20=EB=B3=B4?= =?UTF-8?q?=EC=97=AC=EC=A7=88=203=EA=B0=9C=EC=9B=94=20=EC=9D=B4=EB=82=B4?= =?UTF-8?q?=EC=97=90=20=EC=83=9D=EC=84=B1=EB=90=98=EA=B3=A0=20=EC=A2=8B?= =?UTF-8?q?=EC=95=84=EC=9A=94=EC=88=9C=EC=9C=BC=EB=A1=9C=20=EC=A0=95?= =?UTF-8?q?=EB=A0=AC=EB=90=9C=20=EB=AA=A8=EC=9E=84=20controller?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../gathering/controller/GatheringController.java | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/main/java/solitour_backend/solitour/gathering/controller/GatheringController.java b/src/main/java/solitour_backend/solitour/gathering/controller/GatheringController.java index 96def71c..693ea53f 100644 --- a/src/main/java/solitour_backend/solitour/gathering/controller/GatheringController.java +++ b/src/main/java/solitour_backend/solitour/gathering/controller/GatheringController.java @@ -123,6 +123,17 @@ public ResponseEntity> getGatheringRankOrderByLikes( .body(gatheringRankOrderByLikes); } + @GetMapping("/home") + public ResponseEntity> getHomeGathering(HttpServletRequest request) { + Long userId = findUser(request); + + List gatheringOrderByLikesFilterByCreate3After = gatheringService.getGatheringOrderByLikesFilterByCreate3After(userId); + + return ResponseEntity + .status(HttpStatus.OK) + .body(gatheringOrderByLikesFilterByCreate3After); + } + private Long findUser(HttpServletRequest request) { String token = CookieExtractor.findToken("access_token", request.getCookies()); From 9b68eb150f31c7e2bd0587de4be11691ceeb9734 Mon Sep 17 00:00:00 2001 From: Donghun Won Date: Fri, 23 Aug 2024 13:31:56 +0900 Subject: [PATCH 136/371] =?UTF-8?q?Feat(#91)=20:=20=EA=B0=9C=EB=B3=84=20?= =?UTF-8?q?=EB=8B=A4=EC=9D=B4=EC=96=B4=EB=A6=AC=20=EC=A1=B0=ED=9A=8C,=20?= =?UTF-8?q?=ED=83=80=EC=9D=B4=ED=8B=80=20=EC=9D=B4=EB=AF=B8=EC=A7=80=20?= =?UTF-8?q?=EB=B0=98=ED=99=98=EA=B0=92=EC=97=90=20=EC=B6=94=EA=B0=80=20=20?= =?UTF-8?q?(#98)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Feat : 여행 일기 crud * Feat : 타이틀 이미지 필드 추가 * Feat : 개별 diary 조회, title 이미지 반환값에 추가 --- .../diary/controller/DiaryController.java | 35 ++++++---- .../solitour/diary/dto/DiaryListResponse.java | 65 +++++++++++++++++++ .../solitour/diary/dto/DiaryResponse.java | 26 ++++---- .../solitour/diary/service/DiaryService.java | 28 ++++++-- .../image/controller/ImageController.java | 8 +-- .../solitour/image/entity/Image.java | 4 +- .../solitour/image/service/ImageService.java | 4 +- 7 files changed, 131 insertions(+), 39 deletions(-) create mode 100644 src/main/java/solitour_backend/solitour/diary/dto/DiaryListResponse.java diff --git a/src/main/java/solitour_backend/solitour/diary/controller/DiaryController.java b/src/main/java/solitour_backend/solitour/diary/controller/DiaryController.java index 42da3a11..27a86f52 100644 --- a/src/main/java/solitour_backend/solitour/diary/controller/DiaryController.java +++ b/src/main/java/solitour_backend/solitour/diary/controller/DiaryController.java @@ -5,6 +5,7 @@ import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.RequestBody; @@ -13,8 +14,10 @@ import org.springframework.web.bind.annotation.RestController; import solitour_backend.solitour.auth.config.Authenticated; import solitour_backend.solitour.auth.config.AuthenticationPrincipal; +import solitour_backend.solitour.diary.dto.DiaryListResponse; import solitour_backend.solitour.diary.dto.DiaryRequest; import solitour_backend.solitour.diary.dto.DiaryResponse; +import solitour_backend.solitour.diary.entity.Diary; import solitour_backend.solitour.diary.service.DiaryService; @RestController @@ -22,38 +25,46 @@ @RequestMapping("/api/diary") public class DiaryController { - private final DiaryService diaryService; + private final DiaryService diaryService; @Authenticated @GetMapping() - public ResponseEntity getDiary(@AuthenticationPrincipal Long userId) { - DiaryResponse response = diaryService.getDiary(userId); + public ResponseEntity getAllDiary(@AuthenticationPrincipal Long userId) { + DiaryListResponse response = diaryService.getAllDiary(userId); + + return ResponseEntity.ok(response); + } + + @Authenticated + @GetMapping("/{diaryId}") + public ResponseEntity getDiary(@AuthenticationPrincipal Long userId, @PathVariable Long diaryId) { + DiaryResponse response = diaryService.getDiary(userId, diaryId); return ResponseEntity.ok(response); } @Authenticated @PostMapping() - public ResponseEntity createDiary(@AuthenticationPrincipal Long userId, - @RequestBody DiaryRequest request) { - diaryService.createDiary(userId,request); + public ResponseEntity createDiary(@AuthenticationPrincipal Long userId, + @RequestBody DiaryRequest request) { + Long diaryId = diaryService.createDiary(userId, request); - return ResponseEntity.status(HttpStatus.CREATED).build(); + return ResponseEntity.ok(diaryId); } @Authenticated @PutMapping() - public ResponseEntity updateDiary(@AuthenticationPrincipal Long userId,@RequestParam Long diaryId, + public ResponseEntity updateDiary(@AuthenticationPrincipal Long userId, @RequestParam Long diaryId, @RequestBody DiaryRequest request) { - diaryService.updateDiary(userId,diaryId,request); + diaryService.updateDiary(userId, diaryId, request); - return ResponseEntity.status(HttpStatus.OK).build(); + return ResponseEntity.ok(diaryId); } @Authenticated @DeleteMapping() - public ResponseEntity deleteDiary(@AuthenticationPrincipal Long userId,@RequestParam Long diaryId) { - diaryService.deleteDiary(userId,diaryId); + public ResponseEntity deleteDiary(@AuthenticationPrincipal Long userId, @RequestParam Long diaryId) { + diaryService.deleteDiary(userId, diaryId); return ResponseEntity.status(HttpStatus.OK).build(); } diff --git a/src/main/java/solitour_backend/solitour/diary/dto/DiaryListResponse.java b/src/main/java/solitour_backend/solitour/diary/dto/DiaryListResponse.java new file mode 100644 index 00000000..3a505191 --- /dev/null +++ b/src/main/java/solitour_backend/solitour/diary/dto/DiaryListResponse.java @@ -0,0 +1,65 @@ +package solitour_backend.solitour.diary.dto; + +import java.time.LocalDateTime; +import java.util.List; +import java.util.stream.Collectors; +import lombok.Builder; +import lombok.Getter; +import solitour_backend.solitour.diary.diary_day_content.DiaryDayContent; +import solitour_backend.solitour.diary.entity.Diary; + +@Getter +public class DiaryListResponse { + private final List diaryContentResponse; + + public DiaryListResponse(List diaries) { + + diaryContentResponse= diaries.stream().map( + diary -> DiaryContent.builder() + .diaryId(diary.getId()) + .title(diary.getTitle()) + .titleImage(diary.getTitleImage()) + .startDatetime(diary.getStartDatetime()) + .endDatetime(diary.getEndDatetime()) + .diaryDayContentResponses(new DiaryDayContentResponse(diary.getDiaryDayContent())).build() + ).collect(Collectors.toList()); + + } + + @Getter + @Builder + private static class DiaryContent { + private Long diaryId; + private String title; + private String titleImage; + private LocalDateTime startDatetime; + private LocalDateTime endDatetime; + private DiaryDayContentResponse diaryDayContentResponses; + } + + @Getter + private static class DiaryDayContentResponse { + + private final List diaryDayContentDetail; + + private DiaryDayContentResponse(List diaryDayContent) { + this.diaryDayContentDetail = diaryDayContent.stream() + .map(diaryDayContentDetail -> + DiaryDayContentDetail.builder() + .content(diaryDayContentDetail.getContent()) + .feelingStatus(diaryDayContentDetail.getFeelingStatus().name()) + .place(diaryDayContentDetail.getPlace()) + .build() + ).collect(Collectors.toList()); + } + + } + @Getter + @Builder + private static class DiaryDayContentDetail { + private String content; + private String feelingStatus; + private String place; + } + +} diff --git a/src/main/java/solitour_backend/solitour/diary/dto/DiaryResponse.java b/src/main/java/solitour_backend/solitour/diary/dto/DiaryResponse.java index d3ddfebb..5ac7ec9b 100644 --- a/src/main/java/solitour_backend/solitour/diary/dto/DiaryResponse.java +++ b/src/main/java/solitour_backend/solitour/diary/dto/DiaryResponse.java @@ -10,19 +10,18 @@ @Getter public class DiaryResponse { - private final List diaryContentResponse; - - public DiaryResponse(List diaries) { - - diaryContentResponse= diaries.stream().map( - diary -> DiaryContent.builder() - .diaryId(diary.getId()) - .title(diary.getTitle()) - .startDatetime(diary.getStartDatetime()) - .endDatetime(diary.getEndDatetime()) - .diaryDayContentResponses(new DiaryDayContentResponse(diary.getDiaryDayContent())).build() - ).collect(Collectors.toList()); - + private final DiaryContent diaryContentResponse; + + public DiaryResponse(Diary diary) { + + diaryContentResponse= DiaryContent.builder() + .diaryId(diary.getId()) + .title(diary.getTitle()) + .titleImage(diary.getTitleImage()) + .startDatetime(diary.getStartDatetime()) + .endDatetime(diary.getEndDatetime()) + .diaryDayContentResponses(new DiaryDayContentResponse(diary.getDiaryDayContent())) + .build(); } @Getter @@ -30,6 +29,7 @@ public DiaryResponse(List diaries) { private static class DiaryContent { private Long diaryId; private String title; + private String titleImage; private LocalDateTime startDatetime; private LocalDateTime endDatetime; private DiaryDayContentResponse diaryDayContentResponses; diff --git a/src/main/java/solitour_backend/solitour/diary/service/DiaryService.java b/src/main/java/solitour_backend/solitour/diary/service/DiaryService.java index bbcf8753..e3fbe3bc 100644 --- a/src/main/java/solitour_backend/solitour/diary/service/DiaryService.java +++ b/src/main/java/solitour_backend/solitour/diary/service/DiaryService.java @@ -6,6 +6,7 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import solitour_backend.solitour.diary.diary_day_content.DiaryDayContent; +import solitour_backend.solitour.diary.dto.DiaryListResponse; import solitour_backend.solitour.diary.dto.DiaryRequest; import solitour_backend.solitour.diary.dto.DiaryRequest.DiaryDayRequest; import solitour_backend.solitour.diary.dto.DiaryResponse; @@ -26,7 +27,7 @@ public class DiaryService { private final UserRepository userRepository; @Transactional - public void createDiary(Long userId, DiaryRequest request) { + public Long createDiary(Long userId, DiaryRequest request) { User user = userRepository.findByUserId(userId); Diary diary = Diary.builder() .user(user) @@ -40,6 +41,8 @@ public void createDiary(Long userId, DiaryRequest request) { Diary savedDiary = diaryRepository.save(diary); saveDiaryDayContent(savedDiary, request); + + return savedDiary.getId(); } @@ -55,16 +58,28 @@ private void saveDiaryDayContent(Diary savedDiary, DiaryRequest request) { } } - public DiaryResponse getDiary(Long userId) { + public DiaryListResponse getAllDiary(Long userId) { List diaries = diaryRepository.findByUserId(userId); - return new DiaryResponse(diaries); + return new DiaryListResponse(diaries); + } + + + public DiaryResponse getDiary(Long userId, Long diaryId) { + Diary diary = diaryRepository.findById(diaryId) + .orElseThrow(() -> new IllegalArgumentException("해당 일기가 존재하지 않습니다.")); + + if(!diary.getUser().getId().equals(userId)){ + throw new IllegalArgumentException("해당 일기에 대한 권한이 없습니다."); + } + + return new DiaryResponse(diary); } @Transactional public void deleteDiary(Long userId, Long diaryId) { Diary diary = diaryRepository.findById(diaryId) .orElseThrow(() -> new IllegalArgumentException("해당 일기가 존재하지 않습니다.")); - if(!diary.getUser().getId().equals(userId)) { + if (!diary.getUser().getId().equals(userId)) { throw new IllegalArgumentException("해당 일기에 대한 권한이 없습니다."); } diaryRepository.deleteById(diaryId); @@ -77,13 +92,14 @@ public void updateDiary(Long userId, Long diaryId, DiaryRequest request) { if (!diary.getUser().getId().equals(userId)) { throw new IllegalArgumentException("해당 일기에 대한 권한이 없습니다."); } - updateDiary(diaryId,request); + updateDiary(diaryId, request); } - private void updateDiary(Long diaryId,DiaryRequest request) { + private void updateDiary(Long diaryId, DiaryRequest request) { Diary diary = diaryRepository.findById(diaryId).orElseThrow(() -> new RuntimeException("Diary not found")); diary.getDiaryDayContent().clear(); diary.updateDiary(request); saveDiaryDayContent(diary, request); } + } \ No newline at end of file diff --git a/src/main/java/solitour_backend/solitour/image/controller/ImageController.java b/src/main/java/solitour_backend/solitour/image/controller/ImageController.java index 94c6d5a8..e3860cfd 100644 --- a/src/main/java/solitour_backend/solitour/image/controller/ImageController.java +++ b/src/main/java/solitour_backend/solitour/image/controller/ImageController.java @@ -29,16 +29,16 @@ public class ImageController { @Authenticated @PostMapping - public ResponseEntity uploadImage(@AuthenticationPrincipal Long userId, + public ResponseEntity uploadImage(@RequestParam Long id, @RequestPart("image") MultipartFile userImage, - @RequestParam String imagePath, + @RequestParam String type, @RequestParam String imageStatus) { - ImageResponse informationResponse = imageService.uploadImage(userId, userImage, imagePath, + ImageResponse imageResponse = imageService.uploadImage(id, userImage, type, imageStatus); return ResponseEntity .status(HttpStatus.CREATED) - .body(informationResponse); + .body(imageResponse); } } diff --git a/src/main/java/solitour_backend/solitour/image/entity/Image.java b/src/main/java/solitour_backend/solitour/image/entity/Image.java index ec85d381..e6773f57 100644 --- a/src/main/java/solitour_backend/solitour/image/entity/Image.java +++ b/src/main/java/solitour_backend/solitour/image/entity/Image.java @@ -49,8 +49,8 @@ public Image(ImageStatus imageStatus, Information information, String address, L this.createdDate = createdDate; } - public Image(ImageStatus imageStatus, String imageUrl, LocalDate now) { - this.imageStatus = imageStatus; + public Image(ImageStatus status, String imageUrl, LocalDate now) { + this.imageStatus = status; this.address = imageUrl; this.createdDate = now; } diff --git a/src/main/java/solitour_backend/solitour/image/service/ImageService.java b/src/main/java/solitour_backend/solitour/image/service/ImageService.java index ed8cda39..b0fa0b7d 100644 --- a/src/main/java/solitour_backend/solitour/image/service/ImageService.java +++ b/src/main/java/solitour_backend/solitour/image/service/ImageService.java @@ -24,8 +24,8 @@ public class ImageService { private final S3Uploader s3Uploader; @Transactional - public ImageResponse uploadImage(Long userId, MultipartFile image, String imagePath, String imageStatus) { - String imageUrl = s3Uploader.upload(image, imagePath, userId); + public ImageResponse uploadImage(Long id, MultipartFile image, String type, String imageStatus) { + String imageUrl = s3Uploader.upload(image, type, id); ImageStatus status = checkImageStatus(imageStatus); Image contentImage = new Image(status, imageUrl, LocalDate.now()); imageRepository.save(contentImage); From d1cfc740ab3a09b165529520e4cde338388f3756 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Sat, 24 Aug 2024 01:45:20 +0900 Subject: [PATCH 137/371] =?UTF-8?q?feat:=20page=20=EB=84=A4=EC=9D=B4?= =?UTF-8?q?=EC=85=98=EC=97=90=20=ED=95=84=ED=84=B0=20=EA=B2=80=EC=83=89=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../solitour/gathering/dto/request/GatheringPageRequest.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/solitour_backend/solitour/gathering/dto/request/GatheringPageRequest.java b/src/main/java/solitour_backend/solitour/gathering/dto/request/GatheringPageRequest.java index 2f17be2e..a75dd2f6 100644 --- a/src/main/java/solitour_backend/solitour/gathering/dto/request/GatheringPageRequest.java +++ b/src/main/java/solitour_backend/solitour/gathering/dto/request/GatheringPageRequest.java @@ -34,6 +34,8 @@ public class GatheringPageRequest { private String sort; + private String search; + @JsonFormat(pattern = "yyyy-MM-dd") @DateTimeFormat(pattern = "yyyy-MM-dd") private LocalDate startDate; From 28bf0d1a4112b49ae6559b00f429af3500425c05 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Sat, 24 Aug 2024 01:46:13 +0900 Subject: [PATCH 138/371] =?UTF-8?q?feat:=20=ED=8E=98=EC=9D=B4=EC=A7=80?= =?UTF-8?q?=EB=84=A4=EC=9D=B4=EC=85=98=20=ED=95=84=ED=84=B0=EC=97=90=20sea?= =?UTF-8?q?rch=20=EC=B6=94=EA=B0=80=20where=20=EC=A0=88=EC=97=90=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../gathering/repository/GatheringRepositoryImpl.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryImpl.java b/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryImpl.java index aafec60a..ce696423 100644 --- a/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryImpl.java +++ b/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryImpl.java @@ -277,6 +277,11 @@ private BooleanBuilder makeWhereSQL(GatheringPageRequest gatheringPageRequest) { whereClause.and(gathering.isFinish.eq(false)); } + if (Objects.nonNull(gatheringPageRequest.getSearch())) { + String searchKeyword = gatheringPageRequest.getSearch().trim(); + whereClause.and(gathering.title.trim().containsIgnoreCase(searchKeyword)); + } + return whereClause; } From 96379c922c46c7df285363f1ba15fd6102f97366 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Sat, 24 Aug 2024 03:13:16 +0900 Subject: [PATCH 139/371] =?UTF-8?q?feat:=20=EB=AA=A8=EC=9E=84=20=EC=82=AD?= =?UTF-8?q?=EC=A0=9C=20=EC=98=88=EC=99=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../gathering/exception/GatheringDeleteException.java | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 src/main/java/solitour_backend/solitour/gathering/exception/GatheringDeleteException.java diff --git a/src/main/java/solitour_backend/solitour/gathering/exception/GatheringDeleteException.java b/src/main/java/solitour_backend/solitour/gathering/exception/GatheringDeleteException.java new file mode 100644 index 00000000..4f8dc543 --- /dev/null +++ b/src/main/java/solitour_backend/solitour/gathering/exception/GatheringDeleteException.java @@ -0,0 +1,7 @@ +package solitour_backend.solitour.gathering.exception; + +public class GatheringDeleteException extends RuntimeException { + public GatheringDeleteException(String message) { + super(message); + } +} From ea6cd0f2c276d580088ebfb1a1443c7f7795b4f7 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Sat, 24 Aug 2024 03:14:52 +0900 Subject: [PATCH 140/371] =?UTF-8?q?feat:=20=EB=AA=A8=EC=9E=84=20=EC=82=AD?= =?UTF-8?q?=EC=A0=9C=20=EC=98=88=EC=99=B8=20404=20=ED=95=B8=EB=93=A4?= =?UTF-8?q?=EB=9F=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../solitour/error/GlobalControllerAdvice.java | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/main/java/solitour_backend/solitour/error/GlobalControllerAdvice.java b/src/main/java/solitour_backend/solitour/error/GlobalControllerAdvice.java index b6a15f25..a73f8fad 100644 --- a/src/main/java/solitour_backend/solitour/error/GlobalControllerAdvice.java +++ b/src/main/java/solitour_backend/solitour/error/GlobalControllerAdvice.java @@ -7,6 +7,7 @@ import solitour_backend.solitour.category.exception.CategoryNotExistsException; import solitour_backend.solitour.error.exception.RequestValidationFailedException; import solitour_backend.solitour.gathering.exception.GatheringCategoryNotExistsException; +import solitour_backend.solitour.gathering.exception.GatheringDeleteException; import solitour_backend.solitour.gathering.exception.GatheringNotExistsException; import solitour_backend.solitour.gathering_applicants.exception.*; import solitour_backend.solitour.image.exception.ImageAlreadyExistsException; @@ -20,7 +21,11 @@ @RestControllerAdvice public class GlobalControllerAdvice { - @ExceptionHandler({RequestValidationFailedException.class, ImageRequestValidationFailedException.class, GatheringApplicantsManagerException.class}) + @ExceptionHandler({ + RequestValidationFailedException.class, + ImageRequestValidationFailedException.class, + GatheringApplicantsManagerException.class + }) public ResponseEntity validationException(Exception exception) { return ResponseEntity .status(HttpStatus.BAD_REQUEST) @@ -47,7 +52,8 @@ public ResponseEntity conflictException(Exception exception) { UserNotExistsException.class, GatheringCategoryNotExistsException.class, GatheringNotExistsException.class, - GatheringApplicantsNotExistsException.class + GatheringApplicantsNotExistsException.class, + GatheringDeleteException.class, }) public ResponseEntity notFoundException(Exception exception) { return ResponseEntity From d362b15f402357be6f4441136a0a83e2a4458bb4 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Sat, 24 Aug 2024 03:16:20 +0900 Subject: [PATCH 141/371] =?UTF-8?q?feat:=20gathering=20=EC=82=AD=EC=A0=9C?= =?UTF-8?q?=EC=9D=B8=EC=A7=80=20=EC=BB=AC=EB=9F=BC=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../solitour_backend/solitour/gathering/entity/Gathering.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main/java/solitour_backend/solitour/gathering/entity/Gathering.java b/src/main/java/solitour_backend/solitour/gathering/entity/Gathering.java index 384302c7..bdd802ff 100644 --- a/src/main/java/solitour_backend/solitour/gathering/entity/Gathering.java +++ b/src/main/java/solitour_backend/solitour/gathering/entity/Gathering.java @@ -94,6 +94,9 @@ public class Gathering { @Column(name = "gathering_end_age") private Integer endAge; + @Column(name = "gathering_is_deleted") + private Boolean isDeleted; + public Gathering(User user, ZoneCategory zoneCategory, GatheringCategory gatheringCategory, Place place, String title, String content, Integer personCount, Integer viewCount, LocalDateTime scheduleStartDate, LocalDateTime scheduleEndDate, Boolean isFinish, @@ -113,5 +116,6 @@ public Gathering(User user, ZoneCategory zoneCategory, GatheringCategory gatheri this.allowedSex = allowedSex; this.startAge = startAge; this.endAge = endAge; + this.isDeleted = false; } } From 3dcd0f491c962a1c19115841e570527281eae39c Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Sat, 24 Aug 2024 03:24:10 +0900 Subject: [PATCH 142/371] =?UTF-8?q?feat:=20gathering=20=EC=82=AD=EC=A0=9C?= =?UTF-8?q?=20=EC=BB=AC=EB=9F=BC=20=EC=B6=94=EA=B0=80=20=ED=9B=84=20where?= =?UTF-8?q?=20=EC=A0=88=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../gathering/repository/GatheringRepositoryImpl.java | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryImpl.java b/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryImpl.java index ce696423..0d7fbe1e 100644 --- a/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryImpl.java +++ b/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryImpl.java @@ -75,6 +75,7 @@ public List getGatheringRecommend(Long gatheringId, Long .where(gathering.isFinish.eq(Boolean.FALSE) .and(gathering.gatheringCategory.id.eq(gatheringCategoryId)) .and(gathering.id.ne(gatheringId)) + .and(gathering.isDeleted.eq(Boolean.FALSE)) .and(gatheringApplicants.gatheringStatus.eq(GatheringStatus.CONSENT) .or(gatheringApplicants.gatheringStatus.isNull())) ) @@ -187,7 +188,8 @@ public List getGatheringRankList() { return from(gathering) .orderBy(countGreatGatheringByGatheringById().desc()) .groupBy(gathering.id, gathering.title) - .where(gathering.isFinish.eq(Boolean.FALSE)) + .where(gathering.isFinish.eq(Boolean.FALSE) + .and(gathering.isDeleted.eq(Boolean.FALSE))) .limit(5) .select(Projections.constructor( GatheringRankResponse.class, @@ -206,7 +208,9 @@ public List getGatheringLikeCountFromCreatedIn3(Long use .on(bookMarkGathering.gathering.id.eq(gathering.id).and(bookMarkGathering.user.id.eq(userId))) .leftJoin(category).on(category.id.eq(gathering.gatheringCategory.id)) .leftJoin(gatheringApplicants).on(gatheringApplicants.gathering.id.eq(gathering.id)) - .where(gathering.isFinish.eq(Boolean.FALSE).and(gathering.createdAt.after(LocalDateTime.now().minusMonths(3)))) + .where(gathering.isFinish.eq(Boolean.FALSE) + .and(gathering.isDeleted.eq(Boolean.FALSE)) + .and(gathering.createdAt.after(LocalDateTime.now().minusMonths(3)))) .groupBy(gathering.id, zoneCategoryChild.id, zoneCategoryParent.id, category.id, gathering.title, gathering.viewCount, gathering.user.name, gathering.scheduleStartDate, gathering.scheduleEndDate, @@ -248,6 +252,8 @@ public List getGatheringLikeCountFromCreatedIn3(Long use private BooleanBuilder makeWhereSQL(GatheringPageRequest gatheringPageRequest) { BooleanBuilder whereClause = new BooleanBuilder(); + whereClause.and(gathering.isDeleted.eq(Boolean.FALSE)); + if (Objects.nonNull(gatheringPageRequest.getCategory())) { whereClause.and(gathering.gatheringCategory.id.eq(gatheringPageRequest.getCategory())); } From 8c275cb7b6e4420dd9a2632c95f62b9dfb0407d0 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Sat, 24 Aug 2024 03:24:34 +0900 Subject: [PATCH 143/371] =?UTF-8?q?feat:=20gathering=20=EC=82=AD=EC=A0=9C?= =?UTF-8?q?=20service?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../gathering/service/GatheringService.java | 50 ++++++++++++++++--- 1 file changed, 44 insertions(+), 6 deletions(-) diff --git a/src/main/java/solitour_backend/solitour/gathering/service/GatheringService.java b/src/main/java/solitour_backend/solitour/gathering/service/GatheringService.java index f5a81485..9191b494 100644 --- a/src/main/java/solitour_backend/solitour/gathering/service/GatheringService.java +++ b/src/main/java/solitour_backend/solitour/gathering/service/GatheringService.java @@ -20,6 +20,7 @@ import solitour_backend.solitour.gathering.dto.response.GatheringResponse; import solitour_backend.solitour.gathering.entity.Gathering; import solitour_backend.solitour.gathering.exception.GatheringCategoryNotExistsException; +import solitour_backend.solitour.gathering.exception.GatheringDeleteException; import solitour_backend.solitour.gathering.exception.GatheringNotExistsException; import solitour_backend.solitour.gathering.repository.GatheringRepository; import solitour_backend.solitour.gathering_applicants.dto.mapper.GatheringApplicantsMapper; @@ -86,6 +87,11 @@ public GatheringDetailResponse getGatheringDetail(Long userId, Long gatheringId) Gathering gathering = gatheringRepository.findById(gatheringId) .orElseThrow( () -> new GatheringNotExistsException("해당하는 id의 gathering 이 존재 하지 않습니다")); + + if (gathering.getIsDeleted()) { + throw new GatheringDeleteException("해당하는 모임은 삭제가 되었습니다"); + } + UserPostingResponse userPostingResponse = userMapper.mapToUserPostingResponse(gathering.getUser()); List gatheringTags = gatheringTagRepository.findAllByGathering_Id(gathering.getId()); @@ -213,16 +219,26 @@ public GatheringResponse modifyGathering(Long userId, Long gatheringId, .orElseThrow( () -> new GatheringNotExistsException("해당하는 id의 gathering 이 존재 하지 않습니다")); + if (gathering.getIsDeleted()) { + throw new GatheringDeleteException("해당하는 모임은 삭제가 되었습니다"); + } + if (!Objects.equals(user, gathering.getUser())) { throw new GatheringNotManagerException("해당 유저는 권한이 없습니다"); } - GatheringCategory gatheringCategory = gatheringCategoryRepository.findById( - gatheringModifyRequest.getGatheringCategoryId()).orElseThrow(); - ZoneCategory parentZoneCategory = zoneCategoryRepository.findByParentZoneCategoryIdAndName(null, - gatheringModifyRequest.getZoneCategoryNameParent()).orElseThrow(); - ZoneCategory childZoneCategory = zoneCategoryRepository.findByParentZoneCategoryIdAndName( - parentZoneCategory.getId(), gatheringModifyRequest.getZoneCategoryNameChild()).orElseThrow(); + GatheringCategory gatheringCategory = gatheringCategoryRepository.findById(gatheringModifyRequest.getGatheringCategoryId()) + .orElseThrow( + () -> new GatheringCategoryNotExistsException("모임 카테고리가 존재 하지 않습니다") + ); + ZoneCategory parentZoneCategory = zoneCategoryRepository.findByParentZoneCategoryIdAndName(null, gatheringModifyRequest.getZoneCategoryNameParent()) + .orElseThrow( + () -> new ZoneCategoryNotExistsException("부모 지역 카테고리가 존재 하지 않습니다") + ); + ZoneCategory childZoneCategory = zoneCategoryRepository.findByParentZoneCategoryIdAndName(parentZoneCategory.getId(), gatheringModifyRequest.getZoneCategoryNameChild()) + .orElseThrow( + () -> new ZoneCategoryNotExistsException("자식 지역 카테고리가 존재 하지 않습니다") + ); Place place = gathering.getPlace(); PlaceModifyRequest placeModifyRequest = gatheringModifyRequest.getPlaceModifyRequest(); @@ -263,6 +279,28 @@ public GatheringResponse modifyGathering(Long userId, Long gatheringId, return gatheringMapper.mapToGatheringResponse(gathering); } + @Transactional + public void deleteGathering(Long gatheringId, Long userId) { + Gathering gathering = gatheringRepository.findById(gatheringId) + .orElseThrow( + () -> new GatheringNotExistsException("해당하는 id의 gathering 이 존재 하지 않습니다")); + + User user = userRepository.findById(userId) + .orElseThrow( + () -> new UserNotExistsException("해당하는 id의 User 가 없습니다")); + + if (!Objects.equals(user, gathering.getUser())) { + throw new GatheringNotManagerException("해당 유저는 권한이 없습니다"); + } + + if (gathering.getIsDeleted()) { + return; + } + + gathering.setIsDeleted(true); + + } + public Page getPageGathering(Pageable pageable, GatheringPageRequest gatheringPageRequest, Long userId) { validateGatheringPageRequest(gatheringPageRequest); From 0c1a1ccd1919a87d9f762fb8f83d004d123fe51a Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Sat, 24 Aug 2024 03:25:15 +0900 Subject: [PATCH 144/371] =?UTF-8?q?feat:=20gathering=20=EC=82=AD=EC=A0=9C?= =?UTF-8?q?=20controller?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../gathering/controller/GatheringController.java | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/main/java/solitour_backend/solitour/gathering/controller/GatheringController.java b/src/main/java/solitour_backend/solitour/gathering/controller/GatheringController.java index 693ea53f..2cd67adf 100644 --- a/src/main/java/solitour_backend/solitour/gathering/controller/GatheringController.java +++ b/src/main/java/solitour_backend/solitour/gathering/controller/GatheringController.java @@ -97,6 +97,17 @@ public ResponseEntity updateGathering(@AuthenticationPrincipa .body(gatheringResponse); } + @DeleteMapping("/{gatheringId}") + public ResponseEntity deleteGathering(@PathVariable Long gatheringId, HttpServletRequest request) { + Long userId = findUser(request); + + gatheringService.deleteGathering(gatheringId, userId); + + return ResponseEntity + .status(HttpStatus.NO_CONTENT) + .build(); + } + @GetMapping public ResponseEntity> pageGatheringSortAndFilter(@RequestParam(defaultValue = "0") int page, From 9474b07c5702f58c05679584c7310562a41e0270 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Sun, 25 Aug 2024 12:44:48 +0900 Subject: [PATCH 145/371] =?UTF-8?q?feat:=20information=20=ED=8E=98?= =?UTF-8?q?=EC=9D=B4=EC=A7=80=EB=84=A4=EC=9D=B4=EC=85=98=20=EC=A0=95?= =?UTF-8?q?=EB=A0=AC=20=ED=95=84=ED=84=B0=20=EC=B6=94=EA=B0=80=20=EA=B8=B0?= =?UTF-8?q?=EC=A1=B4=EC=9D=98=20=EC=BD=94=EB=93=9C=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../InformationRepositoryCustom.java | 32 +++---------------- 1 file changed, 5 insertions(+), 27 deletions(-) diff --git a/src/main/java/solitour_backend/solitour/information/repository/InformationRepositoryCustom.java b/src/main/java/solitour_backend/solitour/information/repository/InformationRepositoryCustom.java index 0ad412ad..8244fc04 100644 --- a/src/main/java/solitour_backend/solitour/information/repository/InformationRepositoryCustom.java +++ b/src/main/java/solitour_backend/solitour/information/repository/InformationRepositoryCustom.java @@ -1,9 +1,11 @@ package solitour_backend.solitour.information.repository; import java.util.List; + import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.repository.NoRepositoryBean; +import solitour_backend.solitour.information.dto.request.InformationPageRequest; import solitour_backend.solitour.information.dto.response.InformationBriefResponse; import solitour_backend.solitour.information.dto.response.InformationMainResponse; import solitour_backend.solitour.information.dto.response.InformationRankResponse; @@ -11,34 +13,10 @@ @NoRepositoryBean public interface InformationRepositoryCustom { + String LIKE_COUNT_SORT = "likes"; + String VIEW_COUNT_SORT = "views"; - Page getInformationByParentCategoryFilterZoneCategory(Pageable pageable, - Long parentCategoryId, Long userId, - Long zoneCategoryId); - - Page getInformationByChildCategoryFilterZoneCategory(Pageable pageable, - Long childCategoryId, Long userId, - Long zoneCategoryId); - - Page getInformationByParentCategoryFilterZoneCategoryLikeCount(Pageable pageable, - Long categoryId, - Long userId, - Long zoneCategoryId); - - Page getInformationByChildCategoryFilterZoneCategoryLikeCount(Pageable pageable, - Long categoryId, - Long userId, - Long zoneCategoryId); - - Page getInformationByParentCategoryFilterZoneCategoryViewCount(Pageable pageable, - Long categoryId, - Long userId, - Long zoneCategoryId); - - Page getInformationByChildCategoryFilterZoneCategoryViewCount(Pageable pageable, - Long categoryId, - Long userId, - Long zoneCategoryId); + Page getInformationPageFilterAndOrder(Pageable pageable, InformationPageRequest informationPageRequest, Long userId, Long parentCategoryId); List getInformationRank(); From 94177025a7cd0ab68bc832020e3c692b82276f69 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Sun, 25 Aug 2024 12:45:16 +0900 Subject: [PATCH 146/371] =?UTF-8?q?feat:=20information=20=ED=8E=98?= =?UTF-8?q?=EC=9D=B4=EC=A7=80=EB=84=A4=EC=9D=B4=EC=85=98=20=EC=A0=95?= =?UTF-8?q?=EB=A0=AC=20=ED=95=84=ED=84=B0=20=EC=B6=94=EA=B0=80=20=EA=B8=B0?= =?UTF-8?q?=EC=A1=B4=EC=9D=98=20=EC=BD=94=EB=93=9C=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../repository/GatheringRepositoryImpl.java | 87 +++++++------------ 1 file changed, 31 insertions(+), 56 deletions(-) diff --git a/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryImpl.java b/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryImpl.java index 0d7fbe1e..935666c6 100644 --- a/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryImpl.java +++ b/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryImpl.java @@ -37,21 +37,10 @@ public class GatheringRepositoryImpl extends QuerydslRepositorySupport implements GatheringRepositoryCustom { - @PersistenceContext - private EntityManager entityManager; - - private JPAQueryFactory queryFactory; - public GatheringRepositoryImpl() { super(Gathering.class); } - @PostConstruct - private void init() { - this.queryFactory = new JPAQueryFactory(entityManager); - } - - QGathering gathering = QGathering.gathering; QZoneCategory zoneCategoryChild = QZoneCategory.zoneCategory; QZoneCategory zoneCategoryParent = new QZoneCategory("zoneCategoryParent"); @@ -63,7 +52,6 @@ private void init() { @Override public List getGatheringRecommend(Long gatheringId, Long gatheringCategoryId, Long userId) { - QGreatGathering greatGatheringSub = new QGreatGathering("greatGatheringSub"); return from(gathering) .join(zoneCategoryChild).on(zoneCategoryChild.id.eq(gathering.zoneCategory.id)) @@ -104,14 +92,7 @@ public List getGatheringRecommend(Long gatheringId, Long gathering.endAge, gathering.personCount, gatheringApplicants.count().coalesce(0L).intValue(), - new CaseBuilder() - .when(JPAExpressions.selectOne() - .from(greatGatheringSub) - .where(greatGatheringSub.gathering.id.eq(gathering.id) - .and(greatGatheringSub.user.id.eq(userId))) - .exists()) - .then(true) - .otherwise(false) + isUserGreatGathering(userId) )).limit(3L).fetch(); } @@ -124,18 +105,27 @@ public Page getGatheringPageFilterAndOrder(Pageable page NumberExpression countGreatGathering = countGreatGatheringByGatheringById(); - JPAQuery countQuery = queryFactory - .select(gathering.id.count()) - .from(gathering) + long total = from(gathering) .join(zoneCategoryChild).on(zoneCategoryChild.id.eq(gathering.zoneCategory.id)) .leftJoin(zoneCategoryParent).on(zoneCategoryParent.id.eq(zoneCategoryChild.parentZoneCategory.id)) .leftJoin(bookMarkGathering).on(bookMarkGathering.gathering.id.eq(gathering.id).and(bookMarkGathering.user.id.eq(userId))) .leftJoin(gatheringApplicants).on(gatheringApplicants.gathering.id.eq(gathering.id)) - .where(booleanBuilder); + .where(booleanBuilder) + .select(gathering.id.count()).fetchCount(); - long total = Optional.ofNullable(countQuery.fetchOne()).orElse(0L); - List content = queryFactory + List content = from(gathering) + .join(zoneCategoryChild).on(zoneCategoryChild.id.eq(gathering.zoneCategory.id)) + .leftJoin(zoneCategoryParent).on(zoneCategoryParent.id.eq(zoneCategoryChild.parentZoneCategory.id)) + .leftJoin(bookMarkGathering).on(bookMarkGathering.gathering.id.eq(gathering.id).and(bookMarkGathering.user.id.eq(userId))) + .leftJoin(gatheringApplicants).on(gatheringApplicants.gathering.id.eq(gathering.id)) + .where(booleanBuilder) + .groupBy(gathering.id, zoneCategoryChild.id, zoneCategoryParent.id, category.id, + gathering.title, gathering.viewCount, gathering.user.name, + gathering.scheduleStartDate, gathering.scheduleEndDate, + gathering.deadline, gathering.allowedSex, + gathering.startAge, gathering.endAge, gathering.personCount) + .orderBy(orderSpecifier) .select(Projections.constructor( GatheringBriefResponse.class, gathering.id, @@ -155,27 +145,8 @@ public Page getGatheringPageFilterAndOrder(Pageable page gathering.endAge, gathering.personCount, gatheringApplicants.count().coalesce(0L).intValue(), - new CaseBuilder() - .when(JPAExpressions.selectOne() - .from(greatGathering) - .where(greatGathering.gathering.id.eq(gathering.id) - .and(greatGathering.user.id.eq(userId))) - .exists()) - .then(true) - .otherwise(false) + isUserGreatGathering(userId) )) - .from(gathering) - .join(zoneCategoryChild).on(zoneCategoryChild.id.eq(gathering.zoneCategory.id)) - .leftJoin(zoneCategoryParent).on(zoneCategoryParent.id.eq(zoneCategoryChild.parentZoneCategory.id)) - .leftJoin(bookMarkGathering).on(bookMarkGathering.gathering.id.eq(gathering.id).and(bookMarkGathering.user.id.eq(userId))) - .leftJoin(gatheringApplicants).on(gatheringApplicants.gathering.id.eq(gathering.id)) - .where(booleanBuilder) - .groupBy(gathering.id, zoneCategoryChild.id, zoneCategoryParent.id, category.id, - gathering.title, gathering.viewCount, gathering.user.name, - gathering.scheduleStartDate, gathering.scheduleEndDate, - gathering.deadline, gathering.allowedSex, - gathering.startAge, gathering.endAge, gathering.personCount) - .orderBy(orderSpecifier) .offset(pageable.getOffset()) .limit(pageable.getPageSize()) .fetch(); @@ -183,6 +154,7 @@ public Page getGatheringPageFilterAndOrder(Pageable page return new PageImpl<>(content, pageable, total); } + @Override public List getGatheringRankList() { return from(gathering) @@ -194,8 +166,8 @@ public List getGatheringRankList() { .select(Projections.constructor( GatheringRankResponse.class, gathering.id, - gathering.title - )).fetch(); + gathering.title)) + .fetch(); } @Override @@ -236,14 +208,7 @@ public List getGatheringLikeCountFromCreatedIn3(Long use gathering.endAge, gathering.personCount, gatheringApplicants.count().coalesce(0L).intValue(), - new CaseBuilder() - .when(JPAExpressions.selectOne() - .from(greatGathering) - .where(greatGathering.gathering.id.eq(gathering.id) - .and(greatGathering.user.id.eq(userId))) - .exists()) - .then(true) - .otherwise(false) + isUserGreatGathering(userId) )).limit(6).fetch(); } @@ -319,5 +284,15 @@ private NumberExpression countGreatGatheringByGatheringById() { .intValue(); } + private BooleanExpression isUserGreatGathering(Long userId) { + return new CaseBuilder() + .when(JPAExpressions.selectOne() + .from(greatGathering) + .where(greatGathering.gathering.id.eq(gathering.id) + .and(greatGathering.user.id.eq(userId))) + .exists()) + .then(true) + .otherwise(false); + } } From 5d0372418b7112b04d6a3e2d9f31d7d169352b2d Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Sun, 25 Aug 2024 12:45:29 +0900 Subject: [PATCH 147/371] =?UTF-8?q?feat:=20isLike=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../information/dto/response/InformationBriefResponse.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/solitour_backend/solitour/information/dto/response/InformationBriefResponse.java b/src/main/java/solitour_backend/solitour/information/dto/response/InformationBriefResponse.java index 51e874d3..b1665862 100644 --- a/src/main/java/solitour_backend/solitour/information/dto/response/InformationBriefResponse.java +++ b/src/main/java/solitour_backend/solitour/information/dto/response/InformationBriefResponse.java @@ -15,4 +15,5 @@ public class InformationBriefResponse { private Boolean isBookMark; private String thumbNailImage; private Integer likeCount; + private Boolean isLike; } From 7244d1f862f0c7ca463f7be8a424fc8e6d6c17e0 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Sun, 25 Aug 2024 12:46:02 +0900 Subject: [PATCH 148/371] =?UTF-8?q?feat:=20information=20=ED=8E=98?= =?UTF-8?q?=EC=9D=B4=EC=A7=80=EB=84=A4=EC=9D=B4=EC=85=98=20=EC=A0=95?= =?UTF-8?q?=EB=A0=AC=20=ED=95=84=ED=84=B0=20=20=ED=95=9C=EA=B0=9C=EB=A1=9C?= =?UTF-8?q?=20=ED=95=A9=EC=B9=98=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/InformationController.java | 113 ++---------------- 1 file changed, 13 insertions(+), 100 deletions(-) diff --git a/src/main/java/solitour_backend/solitour/information/controller/InformationController.java b/src/main/java/solitour_backend/solitour/information/controller/InformationController.java index 5e642038..a86085cc 100644 --- a/src/main/java/solitour_backend/solitour/information/controller/InformationController.java +++ b/src/main/java/solitour_backend/solitour/information/controller/InformationController.java @@ -3,8 +3,10 @@ import jakarta.servlet.http.HttpServletRequest; import jakarta.validation.Valid; + import java.util.List; import java.util.Objects; + import lombok.RequiredArgsConstructor; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; @@ -12,21 +14,14 @@ import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.validation.BindingResult; -import org.springframework.web.bind.annotation.DeleteMapping; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.PutMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RequestPart; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; import solitour_backend.solitour.auth.config.Authenticated; import solitour_backend.solitour.auth.support.CookieExtractor; import solitour_backend.solitour.auth.support.JwtTokenProvider; import solitour_backend.solitour.error.Utils; import solitour_backend.solitour.information.dto.request.InformationModifyRequest; +import solitour_backend.solitour.information.dto.request.InformationPageRequest; import solitour_backend.solitour.information.dto.request.InformationRegisterRequest; import solitour_backend.solitour.information.dto.response.InformationBriefResponse; import solitour_backend.solitour.information.dto.response.InformationDetailResponse; @@ -100,103 +95,21 @@ public ResponseEntity deleteInformation(@PathVariable Long informationId) .build(); } - @GetMapping("/parent-category/{parentCategoryId}") - public ResponseEntity> pageInformationByParentCategoryFilterZoneCategory( - @RequestParam(defaultValue = "0") int page, - @RequestParam(required = false, name = "zoneCategory") Long zoneCategoryId, - @PathVariable("parentCategoryId") Long categoryId, - HttpServletRequest request) { - - Long userId = findUser(request); - - Pageable pageable = PageRequest.of(page, PAGE_SIZE); - Page briefInformationPage = informationService.getBriefInformationPageByParentCategoryFilterZoneCategory( - pageable, categoryId, userId, zoneCategoryId); - - return ResponseEntity - .status(HttpStatus.OK) - .body(briefInformationPage); - } - - @GetMapping("/child-category/{childCategoryId}") - public ResponseEntity> pageInformationByChildCategoryFilterZoneCategory( - @RequestParam(defaultValue = "0") int page, - @PathVariable("childCategoryId") Long categoryId, - @RequestParam(required = false, name = "zoneCategory") Long zoneCategoryId, - HttpServletRequest request) { - Long userId = findUser(request); - - Pageable pageable = PageRequest.of(page, PAGE_SIZE); - Page briefInformationPage = informationService.getBriefInformationPageByChildCategoryFilterZoneCategory( - pageable, categoryId, userId, zoneCategoryId); - - return ResponseEntity - .status(HttpStatus.OK) - .body(briefInformationPage); - } - - //지역 카테고리 별 좋아요순 - @GetMapping("/parent-category/{parentCategory}/like-count") - public ResponseEntity> pageInformationByParentCategoryFilterZoneCategoryLikeCount( - @RequestParam(defaultValue = "0") int page, - @RequestParam(required = false, name = "zoneCategory") Long zoneCategoryId, - @PathVariable("parentCategory") Long categoryId, - HttpServletRequest request) { + @GetMapping + public ResponseEntity> pageInformationSortAndFilter(@RequestParam(defaultValue = "0") int page, + @RequestParam(defaultValue = "1") Long parentCategoryId, + @Valid @ModelAttribute InformationPageRequest informationPageRequest, + BindingResult bindingResult, + HttpServletRequest request) { + Utils.validationRequest(bindingResult); Long userId = findUser(request); - Pageable pageable = PageRequest.of(page, PAGE_SIZE); - Page briefInformationPage = informationService.getBriefInformationPageByParentCategoryFilterZoneCategoryLikeCount( - pageable, categoryId, userId, zoneCategoryId); - return ResponseEntity - .status(HttpStatus.OK) - .body(briefInformationPage); - } - @GetMapping("/child-category/{childCategory}/like-count") - public ResponseEntity> pageInformationChildCategoryFilterZoneCategoryLikeCount( - @RequestParam(defaultValue = "0") int page, - @RequestParam(required = false, name = "zoneCategory") Long zoneCategoryId, - @PathVariable("childCategory") Long categoryId, - HttpServletRequest request) { - Long userId = findUser(request); Pageable pageable = PageRequest.of(page, PAGE_SIZE); - Page briefInformationPage = informationService.getBriefInformationPageByChildCategoryFilterZoneCategoryLikeCount( - pageable, categoryId, userId, zoneCategoryId); - return ResponseEntity - .status(HttpStatus.OK) - .body(briefInformationPage); - } - + Page pageInformation = informationService.getPageInformation(pageable, userId, parentCategoryId, informationPageRequest); - //지역 카테고리 별 조회순 - @GetMapping("/parent-category/{parentCategoryId}/view-count") - public ResponseEntity> pageInformationByParentCategoryFilterZoneCategoryViewCount( - @RequestParam(defaultValue = "0") int page, - @RequestParam(required = false, name = "zoneCategory") Long zoneCategoryId, - @PathVariable("parentCategoryId") Long categoryId, - HttpServletRequest request) { - - Long userId = findUser(request); - Pageable pageable = PageRequest.of(page, PAGE_SIZE); - Page briefInformationPage = informationService.getBriefInformationPageByParentCategoryFilterZoneCategoryViewCount( - pageable, categoryId, userId, zoneCategoryId); - return ResponseEntity - .status(HttpStatus.OK) - .body(briefInformationPage); - } - - @GetMapping("/child-category/{childCategoryId}/view-count") - public ResponseEntity> pageInformationByChildCategoryViewCount( - @RequestParam(defaultValue = "0") int page, - @PathVariable("childCategoryId") Long categoryId, - @RequestParam(required = false, name = "zoneCategory") Long zoneCategoryId, - HttpServletRequest request) { - Long userId = findUser(request); - Pageable pageable = PageRequest.of(page, PAGE_SIZE); - Page briefInformationPage = informationService.getBriefInformationPageByChildCategoryFilterZoneCategoryViewCount( - pageable, categoryId, userId, zoneCategoryId); return ResponseEntity .status(HttpStatus.OK) - .body(briefInformationPage); + .body(pageInformation); } From 12fa38dcfc804e430c024ad07b6835f1c689fb70 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Sun, 25 Aug 2024 12:46:16 +0900 Subject: [PATCH 149/371] =?UTF-8?q?feat:=20information=20=ED=8E=98?= =?UTF-8?q?=EC=9D=B4=EC=A7=80=EB=84=A4=EC=9D=B4=EC=85=98=20=EC=A0=95?= =?UTF-8?q?=EB=A0=AC=20=ED=95=84=ED=84=B0=20=20=ED=95=9C=EA=B0=9C=EB=A1=9C?= =?UTF-8?q?=20=ED=95=A9=EC=B9=98=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../repository/InformationRepositoryImpl.java | 289 +++++------------- 1 file changed, 72 insertions(+), 217 deletions(-) diff --git a/src/main/java/solitour_backend/solitour/information/repository/InformationRepositoryImpl.java b/src/main/java/solitour_backend/solitour/information/repository/InformationRepositoryImpl.java index 27794bb3..f6f9cdcf 100644 --- a/src/main/java/solitour_backend/solitour/information/repository/InformationRepositoryImpl.java +++ b/src/main/java/solitour_backend/solitour/information/repository/InformationRepositoryImpl.java @@ -1,10 +1,19 @@ package solitour_backend.solitour.information.repository; +import com.querydsl.core.BooleanBuilder; +import com.querydsl.core.types.OrderSpecifier; import com.querydsl.core.types.Projections; +import com.querydsl.core.types.dsl.BooleanExpression; +import com.querydsl.core.types.dsl.CaseBuilder; +import com.querydsl.core.types.dsl.Expressions; +import com.querydsl.core.types.dsl.NumberExpression; +import com.querydsl.jpa.JPAExpressions; import com.querydsl.jpa.JPQLQuery; + import java.time.LocalDateTime; import java.util.List; import java.util.Objects; + import org.springframework.data.domain.Page; import org.springframework.data.domain.PageImpl; import org.springframework.data.domain.Pageable; @@ -14,6 +23,7 @@ import solitour_backend.solitour.great_information.entity.QGreatInformation; import solitour_backend.solitour.image.entity.QImage; import solitour_backend.solitour.image.image_status.ImageStatus; +import solitour_backend.solitour.information.dto.request.InformationPageRequest; import solitour_backend.solitour.information.dto.response.InformationBriefResponse; import solitour_backend.solitour.information.dto.response.InformationMainResponse; import solitour_backend.solitour.information.dto.response.InformationRankResponse; @@ -37,238 +47,50 @@ public InformationRepositoryImpl() { @Override - public Page getInformationByParentCategoryFilterZoneCategory(Pageable pageable, - Long parentCategoryId, - Long userId, - Long zoneCategoryId) { - JPQLQuery query = from(information) - .join(zoneCategoryChild).on(zoneCategoryChild.id.eq(information.zoneCategory.id)) - .leftJoin(zoneCategoryParent).on(zoneCategoryParent.id.eq(zoneCategoryChild.parentZoneCategory.id)) - .leftJoin(bookMarkInformation) - .on(bookMarkInformation.information.id.eq(information.id).and(bookMarkInformation.user.id.eq(userId))) - .leftJoin(image).on(image.information.id.eq(information.id) - .and(image.imageStatus.eq(ImageStatus.THUMBNAIL))) - .leftJoin(greatInformation).on(greatInformation.information.id.eq(information.id)) - .where(information.category.parentCategory.id.eq(parentCategoryId)); + public Page getInformationPageFilterAndOrder(Pageable pageable, InformationPageRequest informationPageRequest, Long userId, Long parentCategoryId) { + BooleanBuilder whereClause = new BooleanBuilder(); - if (Objects.nonNull(zoneCategoryId)) { - query = query.where(information.zoneCategory.parentZoneCategory.id.eq(zoneCategoryId)); + if (Objects.nonNull(informationPageRequest.getZoneCategoryId())) { + whereClause.and(information.zoneCategory.parentZoneCategory.id.eq(informationPageRequest.getZoneCategoryId())); } - List list = query - .groupBy(information.id, zoneCategoryChild.id, zoneCategoryParent.id, image.id) - .orderBy(information.createdDate.desc()) - .select(Projections.constructor( - InformationBriefResponse.class, - information.id, - information.title, - zoneCategoryParent.name, - zoneCategoryChild.name, - information.viewCount, - bookMarkInformation.user.id.isNotNull(), - image.address, - greatInformation.information.count().coalesce(0L).intValue() - )) - .offset(pageable.getOffset()) - .limit(pageable.getPageSize()) - .fetch(); - - long total = from(information).where(information.category.id.eq(parentCategoryId)).fetchCount(); + BooleanBuilder categoryCondition = new BooleanBuilder(); - return new PageImpl<>(list, pageable, total); - } - @Override - public Page getInformationByChildCategoryFilterZoneCategory(Pageable pageable, - Long childCategoryId, - Long userId, - Long zoneCategoryId) { - JPQLQuery query = from(information) - .join(zoneCategoryChild).on(zoneCategoryChild.id.eq(information.zoneCategory.id)) - .leftJoin(zoneCategoryParent).on(zoneCategoryParent.id.eq(zoneCategoryChild.parentZoneCategory.id)) - .leftJoin(bookMarkInformation) - .on(bookMarkInformation.information.id.eq(information.id).and(bookMarkInformation.user.id.eq(userId))) - .leftJoin(image).on(image.information.id.eq(information.id) - .and(image.imageStatus.eq(ImageStatus.THUMBNAIL))) - .leftJoin(greatInformation).on(greatInformation.information.id.eq(information.id)) - .where(information.category.id.eq(childCategoryId)); - - if (Objects.nonNull(zoneCategoryId)) { - query = query.where(information.zoneCategory.parentZoneCategory.id.eq(zoneCategoryId)); + if (Objects.nonNull(informationPageRequest.getChildCategoryId())) { + whereClause.and(information.category.id.eq(informationPageRequest.getChildCategoryId())); + } else { + categoryCondition.and(category.parentCategory.id.eq(parentCategoryId)); } - List list = query - .groupBy(information.id, zoneCategoryChild.id, zoneCategoryParent.id, image.id) - .orderBy(information.createdDate.desc()) - .select(Projections.constructor( - InformationBriefResponse.class, - information.id, - information.title, - zoneCategoryParent.name, - zoneCategoryChild.name, - information.viewCount, - bookMarkInformation.user.id.isNotNull(), - image.address, - greatInformation.information.count().coalesce(0L).intValue() - )) - .offset(pageable.getOffset()) - .limit(pageable.getPageSize()) - .fetch(); - - long total = from(information).where(information.category.id.eq(childCategoryId)).fetchCount(); - - return new PageImpl<>(list, pageable, total); - } + OrderSpecifier orderSpecifier = getOrderSpecifier(informationPageRequest.getSort()); + NumberExpression countGreatInformation = countGreatInformationByInformationById(); - - @Override - public Page getInformationByParentCategoryFilterZoneCategoryLikeCount(Pageable pageable, - Long categoryId, - Long userId, - Long zoneCategoryId) { - JPQLQuery query = from(information) + long total = from(information) .join(zoneCategoryChild).on(zoneCategoryChild.id.eq(information.zoneCategory.id)) .leftJoin(zoneCategoryParent).on(zoneCategoryParent.id.eq(zoneCategoryChild.parentZoneCategory.id)) .leftJoin(bookMarkInformation) .on(bookMarkInformation.information.id.eq(information.id).and(bookMarkInformation.user.id.eq(userId))) .leftJoin(image).on(image.information.id.eq(information.id) .and(image.imageStatus.eq(ImageStatus.THUMBNAIL))) - .leftJoin(greatInformation).on(greatInformation.information.id.eq(information.id)) - .where(information.category.parentCategory.id.eq(categoryId)); - - if (Objects.nonNull(zoneCategoryId)) { - query = query.where(information.zoneCategory.parentZoneCategory.id.eq(zoneCategoryId)); - } - - List list = query.groupBy(information.id, zoneCategoryChild.id, zoneCategoryParent.id, - image.id) - .orderBy(greatInformation.information.count().desc()) - .select(Projections.constructor( - InformationBriefResponse.class, - information.id, - information.title, - zoneCategoryParent.name, - zoneCategoryChild.name, - information.viewCount, - bookMarkInformation.user.id.isNotNull(), - image.address, - greatInformation.information.count().coalesce(0L).intValue() - )) - .offset(pageable.getOffset()) - .limit(pageable.getPageSize()) - .fetch(); - - long total = from(information).where(information.category.id.eq(categoryId)).fetchCount(); - - return new PageImpl<>(list, pageable, total); - } + .join(category).on(category.id.eq(information.category.id) + .and(categoryCondition)) + .where(whereClause) + .select(information.count()).fetchCount(); - @Override - public Page getInformationByChildCategoryFilterZoneCategoryLikeCount(Pageable pageable, - Long categoryId, - Long userId, - Long zoneCategoryId) { - JPQLQuery query = from(information) - .join(zoneCategoryChild).on(zoneCategoryChild.id.eq(information.zoneCategory.id)) - .leftJoin(zoneCategoryParent).on(zoneCategoryParent.id.eq(zoneCategoryChild.parentZoneCategory.id)) - .leftJoin(bookMarkInformation) - .on(bookMarkInformation.information.id.eq(information.id).and(bookMarkInformation.user.id.eq(userId))) - .leftJoin(image).on(image.information.id.eq(information.id) - .and(image.imageStatus.eq(ImageStatus.THUMBNAIL))) - .leftJoin(greatInformation).on(greatInformation.information.id.eq(information.id)) - .where(information.category.id.eq(categoryId)); - - if (Objects.nonNull(zoneCategoryId)) { - query = query.where(information.zoneCategory.parentZoneCategory.id.eq(zoneCategoryId)); - } - - List list = query - .groupBy(information.id, zoneCategoryChild.id, zoneCategoryParent.id, image.id) - .orderBy(greatInformation.information.count().desc()) - .select(Projections.constructor( - InformationBriefResponse.class, - information.id, - information.title, - zoneCategoryParent.name, - zoneCategoryChild.name, - information.viewCount, - bookMarkInformation.user.id.isNotNull(), - image.address, - greatInformation.information.count().coalesce(0L).intValue() - )) - .offset(pageable.getOffset()) - .limit(pageable.getPageSize()) - .fetch(); - - long total = from(information).where(information.category.id.eq(categoryId)).fetchCount(); - - return new PageImpl<>(list, pageable, total); - } - - @Override - public Page getInformationByParentCategoryFilterZoneCategoryViewCount(Pageable pageable, - Long categoryId, - Long userId, - Long zoneCategoryId) { - JPQLQuery query = from(information) - .join(zoneCategoryChild).on(zoneCategoryChild.id.eq(information.zoneCategory.id)) - .leftJoin(zoneCategoryParent).on(zoneCategoryParent.id.eq(zoneCategoryChild.parentZoneCategory.id)) - .leftJoin(bookMarkInformation) - .on(bookMarkInformation.information.id.eq(information.id).and(bookMarkInformation.user.id.eq(userId))) - .leftJoin(image).on(image.information.id.eq(information.id) - .and(image.imageStatus.eq(ImageStatus.THUMBNAIL))) - .leftJoin(greatInformation).on(greatInformation.information.id.eq(information.id)) - .where(information.category.parentCategory.id.eq(categoryId)); - - if (Objects.nonNull(zoneCategoryId)) { - query = query.where(information.zoneCategory.parentZoneCategory.id.eq(zoneCategoryId)); - } - - List list = query - .groupBy(information.id, zoneCategoryChild.id, zoneCategoryParent.id, image.id) - .orderBy(information.viewCount.desc()) - .select(Projections.constructor( - InformationBriefResponse.class, - information.id, - information.title, - zoneCategoryParent.name, - zoneCategoryChild.name, - information.viewCount, - bookMarkInformation.user.id.isNotNull(), - image.address, - greatInformation.information.count().coalesce(0L).intValue() - )) - .offset(pageable.getOffset()) - .limit(pageable.getPageSize()) - .fetch(); - - long total = from(information).where(information.category.id.eq(categoryId)).fetchCount(); - - return new PageImpl<>(list, pageable, total); - } - - @Override - public Page getInformationByChildCategoryFilterZoneCategoryViewCount(Pageable pageable, - Long categoryId, - Long userId, - Long zoneCategoryId) { - JPQLQuery query = from(information) + List list = from(information) .join(zoneCategoryChild).on(zoneCategoryChild.id.eq(information.zoneCategory.id)) .leftJoin(zoneCategoryParent).on(zoneCategoryParent.id.eq(zoneCategoryChild.parentZoneCategory.id)) .leftJoin(bookMarkInformation) .on(bookMarkInformation.information.id.eq(information.id).and(bookMarkInformation.user.id.eq(userId))) .leftJoin(image).on(image.information.id.eq(information.id) .and(image.imageStatus.eq(ImageStatus.THUMBNAIL))) + .join(category).on(category.id.eq(information.category.id) + .and(categoryCondition)) .leftJoin(greatInformation).on(greatInformation.information.id.eq(information.id)) - .where(information.category.id.eq(categoryId)); - - if (Objects.nonNull(zoneCategoryId)) { - query = query.where(information.zoneCategory.parentZoneCategory.id.eq(zoneCategoryId)); - } - - List list = query + .where(whereClause) .groupBy(information.id, zoneCategoryChild.id, zoneCategoryParent.id, image.id) - .orderBy(information.viewCount.desc()) + .orderBy(orderSpecifier) .select(Projections.constructor( InformationBriefResponse.class, information.id, @@ -278,14 +100,12 @@ public Page getInformationByChildCategoryFilterZoneCat information.viewCount, bookMarkInformation.user.id.isNotNull(), image.address, - greatInformation.information.count().coalesce(0L).intValue() - )) - .offset(pageable.getOffset()) + countGreatInformation, + isUserGreatInformation(userId) + )).offset(pageable.getOffset()) .limit(pageable.getPageSize()) .fetch(); - long total = from(information).where(information.category.id.eq(categoryId)).fetchCount(); - return new PageImpl<>(list, pageable, total); } @@ -315,7 +135,8 @@ public List getInformationLikeCountFromCreatedIn3(Long information.viewCount, bookMarkInformation.user.id.isNotNull(), image.address, - greatInformation.information.count().coalesce(0L).intValue() + countGreatInformationByInformationById(), + isUserGreatInformation(userId) )).limit(6).fetch(); } @@ -343,8 +164,11 @@ public List getInformationRecommend(Long informationId information.viewCount, bookMarkInformation.user.id.isNotNull(), image.address, - greatInformation.information.count().coalesce(0L).intValue() - )).limit(3L).fetch(); + countGreatInformationByInformationById(), + isUserGreatInformation(userId) + )) + .limit(3L) + .fetch(); } @Override @@ -362,5 +186,36 @@ public List getInformationRank() { )).fetch(); } + private OrderSpecifier getOrderSpecifier(String sort) { + if (Objects.nonNull(sort)) { + if (Objects.equals(LIKE_COUNT_SORT, sort)) { + return countGreatInformationByInformationById().desc(); + } else if (Objects.equals(VIEW_COUNT_SORT, sort)) { + return information.viewCount.desc(); + } + } + return information.createdDate.desc(); + } + + private NumberExpression countGreatInformationByInformationById() { + QGreatInformation greatInformationSub = QGreatInformation.greatInformation; + JPQLQuery likeCountSubQuery = JPAExpressions.select(greatInformationSub.count()) + .from(greatInformationSub) + .where(greatInformationSub.information.id.eq(information.id)); + + return Expressions.numberTemplate(Long.class, "{0}", likeCountSubQuery).coalesce(0L).intValue(); + } + + private BooleanExpression isUserGreatInformation(Long userId) { + return new CaseBuilder() + .when(JPAExpressions.selectOne() + .from(greatInformation) + .where(greatInformation.information.id.eq(information.id) + .and(greatInformation.information.id.eq(userId))) + .exists()) + .then(true) + .otherwise(false); + } + } From 7b97058ea5e3dc3617bb49d7e9b84635333e42f1 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Sun, 25 Aug 2024 12:46:20 +0900 Subject: [PATCH 150/371] =?UTF-8?q?feat:=20information=20=ED=8E=98?= =?UTF-8?q?=EC=9D=B4=EC=A7=80=EB=84=A4=EC=9D=B4=EC=85=98=20=EC=A0=95?= =?UTF-8?q?=EB=A0=AC=20=ED=95=84=ED=84=B0=20=20=ED=95=9C=EA=B0=9C=EB=A1=9C?= =?UTF-8?q?=20=ED=95=A9=EC=B9=98=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/InformationService.java | 96 +++++-------------- 1 file changed, 25 insertions(+), 71 deletions(-) diff --git a/src/main/java/solitour_backend/solitour/information/service/InformationService.java b/src/main/java/solitour_backend/solitour/information/service/InformationService.java index d1a00257..cc9e5724 100644 --- a/src/main/java/solitour_backend/solitour/information/service/InformationService.java +++ b/src/main/java/solitour_backend/solitour/information/service/InformationService.java @@ -5,6 +5,7 @@ import java.util.ArrayList; import java.util.List; import java.util.Objects; + import lombok.RequiredArgsConstructor; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; @@ -15,6 +16,7 @@ import solitour_backend.solitour.category.entity.Category; import solitour_backend.solitour.category.exception.CategoryNotExistsException; import solitour_backend.solitour.category.repository.CategoryRepository; +import solitour_backend.solitour.error.exception.RequestValidationFailedException; import solitour_backend.solitour.great_information.repository.GreatInformationRepository; import solitour_backend.solitour.image.dto.mapper.ImageMapper; import solitour_backend.solitour.image.dto.request.ImageDeleteRequest; @@ -30,6 +32,7 @@ import solitour_backend.solitour.info_tag.repository.InfoTagRepository; import solitour_backend.solitour.information.dto.mapper.InformationMapper; import solitour_backend.solitour.information.dto.request.InformationModifyRequest; +import solitour_backend.solitour.information.dto.request.InformationPageRequest; import solitour_backend.solitour.information.dto.request.InformationRegisterRequest; import solitour_backend.solitour.information.dto.response.InformationBriefResponse; import solitour_backend.solitour.information.dto.response.InformationDetailResponse; @@ -59,6 +62,9 @@ import solitour_backend.solitour.zone_category.exception.ZoneCategoryNotExistsException; import solitour_backend.solitour.zone_category.repository.ZoneCategoryRepository; +import static solitour_backend.solitour.information.repository.InformationRepositoryCustom.LIKE_COUNT_SORT; +import static solitour_backend.solitour.information.repository.InformationRepositoryCustom.VIEW_COUNT_SORT; + @Service @Transactional(readOnly = true) @RequiredArgsConstructor @@ -330,88 +336,36 @@ public void deleteInformation(Long id) { } - //default - public Page getBriefInformationPageByParentCategoryFilterZoneCategory(Pageable pageable, - Long parentCategoryId, - Long userId, - Long zoneCategoryId) { - if (!categoryRepository.existsById(parentCategoryId)) { - throw new CategoryNotExistsException("해당하는 id의 category는 없습니다"); - } - if (Objects.nonNull(zoneCategoryId) && !zoneCategoryRepository.existsById(zoneCategoryId)) { - throw new ZoneCategoryNotExistsException("해당하는 id의 zoneCategory는 없습니다"); - } - - return informationRepository.getInformationByParentCategoryFilterZoneCategory(pageable, parentCategoryId, - userId, zoneCategoryId); - } - public Page getBriefInformationPageByChildCategoryFilterZoneCategory(Pageable pageable, - Long childCategoryId, - Long userId, - Long zoneCategoryId) { - if (!categoryRepository.existsById(childCategoryId)) { - throw new CategoryNotExistsException("해당하는 id의 category는 없습니다"); + public Page getPageInformation(Pageable pageable, Long userId, Long parentCategoryId, InformationPageRequest informationPageRequest) { + if (!categoryRepository.existsByIdAndParentCategoryId(parentCategoryId, null)) { + throw new CategoryNotExistsException("해당하는 id의 부모 category 는 없습니다"); } - if (Objects.nonNull(zoneCategoryId) && !zoneCategoryRepository.existsById(zoneCategoryId)) { - throw new ZoneCategoryNotExistsException("해당하는 id의 zoneCategory는 없습니다"); - } - return informationRepository.getInformationByChildCategoryFilterZoneCategory(pageable, childCategoryId, userId, - zoneCategoryId); - } - //지역카테고리별 좋아요순 - public Page getBriefInformationPageByParentCategoryFilterZoneCategoryLikeCount( - Pageable pageable, Long parentCategoryId, Long userId, Long zoneCategoryId) { - if (!categoryRepository.existsById(parentCategoryId)) { - throw new CategoryNotExistsException("해당하는 id의 category는 없습니다"); - } - if (Objects.nonNull(zoneCategoryId) && !zoneCategoryRepository.existsById(zoneCategoryId)) { - throw new ZoneCategoryNotExistsException("해당하는 id의 zoneCategory는 없습니다"); - } - return informationRepository.getInformationByParentCategoryFilterZoneCategoryLikeCount(pageable, - parentCategoryId, userId, zoneCategoryId); - } + if (Objects.nonNull(informationPageRequest.getChildCategoryId())) { + Category category = categoryRepository.findById(informationPageRequest.getChildCategoryId()) + .orElseThrow( + () -> new CategoryNotExistsException("해당하는 id의 category는 없습니다")); - public Page getBriefInformationPageByChildCategoryFilterZoneCategoryLikeCount( - Pageable pageable, Long childCategoryId, Long userId, Long zoneCategoryId) { - if (!categoryRepository.existsById(childCategoryId)) { - throw new CategoryNotExistsException("해당하는 id의 category는 없습니다"); - } - if (Objects.nonNull(zoneCategoryId) && !zoneCategoryRepository.existsById(zoneCategoryId)) { - throw new ZoneCategoryNotExistsException("해당하는 id의 zoneCategory는 없습니다"); + if (!Objects.equals(category.getParentCategory().getId(), parentCategoryId)) { + throw new RequestValidationFailedException("자식 카테고리의 부모 카테고리와 요청한 부모 카테고리가 다릅니다"); + } } - return informationRepository.getInformationByChildCategoryFilterZoneCategoryLikeCount(pageable, childCategoryId, - userId, zoneCategoryId); - } - - //지역카테고리별 조회순 - public Page getBriefInformationPageByParentCategoryFilterZoneCategoryViewCount( - Pageable pageable, Long parentCategoryId, Long userId, Long zoneCategoryId) { - if (!categoryRepository.existsById(parentCategoryId)) { - throw new CategoryNotExistsException("해당하는 id의 category는 없습니다"); - } - if (Objects.nonNull(zoneCategoryId) && !zoneCategoryRepository.existsById(zoneCategoryId)) { - throw new ZoneCategoryNotExistsException("해당하는 id의 zoneCategory는 없습니다"); + if (Objects.nonNull(informationPageRequest.getZoneCategoryId())) { + if (!zoneCategoryRepository.existsById(informationPageRequest.getZoneCategoryId())) { + throw new ZoneCategoryNotExistsException("해당하는 지역 카테고리가 없습니다"); + } } - return informationRepository.getInformationByParentCategoryFilterZoneCategoryViewCount(pageable, - parentCategoryId, userId, zoneCategoryId); - } - - public Page getBriefInformationPageByChildCategoryFilterZoneCategoryViewCount( - Pageable pageable, Long childCategoryId, Long userId, Long zoneCategoryId) { - if (!categoryRepository.existsById(childCategoryId)) { - throw new CategoryNotExistsException("해당하는 id의 category는 없습니다"); - } - if (Objects.nonNull(zoneCategoryId) && !zoneCategoryRepository.existsById(zoneCategoryId)) { - throw new ZoneCategoryNotExistsException("해당하는 id의 zoneCategory는 없습니다"); + if (Objects.nonNull(informationPageRequest.getSort())) { + if (!Objects.equals(LIKE_COUNT_SORT, informationPageRequest.getSort()) || !Objects.equals(VIEW_COUNT_SORT, informationPageRequest.getSort())) { + throw new RequestValidationFailedException("잘못된 정렬 코드입니다."); + } } - return informationRepository.getInformationByChildCategoryFilterZoneCategoryViewCount(pageable, childCategoryId, - userId, zoneCategoryId); + return informationRepository.getInformationPageFilterAndOrder(pageable, informationPageRequest, userId, parentCategoryId); } public List getRankInformation() { From a17617d144b13fa132941b3b17295d73f8ce084b Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Sun, 25 Aug 2024 12:46:32 +0900 Subject: [PATCH 151/371] feat: information page request dto --- .../dto/request/InformationPageRequest.java | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 src/main/java/solitour_backend/solitour/information/dto/request/InformationPageRequest.java diff --git a/src/main/java/solitour_backend/solitour/information/dto/request/InformationPageRequest.java b/src/main/java/solitour_backend/solitour/information/dto/request/InformationPageRequest.java new file mode 100644 index 00000000..c3221822 --- /dev/null +++ b/src/main/java/solitour_backend/solitour/information/dto/request/InformationPageRequest.java @@ -0,0 +1,23 @@ +package solitour_backend.solitour.information.dto.request; + +import jakarta.validation.constraints.Min; +import jakarta.validation.constraints.Size; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +@Getter +@Setter +@AllArgsConstructor +@NoArgsConstructor +public class InformationPageRequest { + @Min(1) + private Long childCategoryId; + + @Size(min = 1, max = 10) + private String sort; + + @Min(1) + private Long zoneCategoryId; +} From 5d2640893acc397e592cf19188863ae72c816fe1 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Sun, 25 Aug 2024 13:09:46 +0900 Subject: [PATCH 152/371] =?UTF-8?q?feat:=20=EB=B6=80=EB=AA=A8=20=EC=B9=B4?= =?UTF-8?q?=ED=85=8C=EA=B3=A0=EB=A6=AC=20=EC=A1=B4=EC=9E=AC=ED=95=98?= =?UTF-8?q?=EB=8A=94=EC=A7=80=20=ED=99=95=EC=9D=B8=ED=95=98=EB=8A=94=20?= =?UTF-8?q?=EB=A9=94=EC=84=9C=EB=93=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../solitour/category/repository/CategoryRepository.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main/java/solitour_backend/solitour/category/repository/CategoryRepository.java b/src/main/java/solitour_backend/solitour/category/repository/CategoryRepository.java index 2600c43b..457b3785 100644 --- a/src/main/java/solitour_backend/solitour/category/repository/CategoryRepository.java +++ b/src/main/java/solitour_backend/solitour/category/repository/CategoryRepository.java @@ -1,10 +1,13 @@ package solitour_backend.solitour.category.repository; import java.util.List; + import org.springframework.data.jpa.repository.JpaRepository; import solitour_backend.solitour.category.entity.Category; public interface CategoryRepository extends JpaRepository { List findAllByParentCategoryId(Long parentCategoryId); + + boolean existsByIdAndParentCategoryId(Long id, Long parentCategoryId); } From 53ac958d4ae0f2054d9f0d51410968c0b83b8b2d Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Sun, 25 Aug 2024 13:09:59 +0900 Subject: [PATCH 153/371] =?UTF-8?q?feat:=20page=20=EA=B0=9D=EC=B2=B4=20?= =?UTF-8?q?=EC=A7=81=EB=A0=AC=ED=99=94=20=EB=AC=B8=EC=A0=9C=20=ED=95=B4?= =?UTF-8?q?=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/solitour_backend/solitour/SolitourApplication.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/solitour_backend/solitour/SolitourApplication.java b/src/main/java/solitour_backend/solitour/SolitourApplication.java index f21385ca..20145527 100644 --- a/src/main/java/solitour_backend/solitour/SolitourApplication.java +++ b/src/main/java/solitour_backend/solitour/SolitourApplication.java @@ -4,10 +4,12 @@ import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.context.properties.ConfigurationPropertiesScan; import org.springframework.data.jpa.repository.config.EnableJpaAuditing; +import org.springframework.data.web.config.EnableSpringDataWebSupport; @SpringBootApplication @EnableJpaAuditing @ConfigurationPropertiesScan +@EnableSpringDataWebSupport(pageSerializationMode = EnableSpringDataWebSupport.PageSerializationMode.VIA_DTO) public class SolitourApplication { public static void main(String[] args) { From 10e0b442804783967eb03db64bc989c448860dcd Mon Sep 17 00:00:00 2001 From: Donghun Won Date: Sun, 25 Aug 2024 16:58:26 +0900 Subject: [PATCH 154/371] =?UTF-8?q?Feat(#91)=20=20:=20=EC=97=AC=ED=96=89?= =?UTF-8?q?=EC=9D=BC=EA=B8=B0=20=ED=8E=98=EC=9D=B4=EC=A7=80=EB=84=A4?= =?UTF-8?q?=EC=9D=B4=EC=85=98=20=20(#106)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Feat : 여행 일기 crud * Feat : 타이틀 이미지 필드 추가 * Feat : 개별 diary 조회, title 이미지 반환값에 추가 * Feat : 여행일기 조회 페이지네이션 * Style: 코드 포맷팅 --- .../BookMarkInformationController.java | 4 +- .../entity/BookMarkInformationRepository.java | 2 +- .../service/BookMarkInformationService.java | 4 +- .../repository/CategoryRepository.java | 1 - .../diary/controller/DiaryController.java | 15 +++- .../diary_day_content/DiaryDayContent.java | 9 --- .../solitour/diary/dto/DiaryContent.java | 49 ++++++++++++ .../diary/dto/DiaryDayContentDetail.java | 14 ++++ .../solitour/diary/dto/DiaryListResponse.java | 39 +++++----- .../solitour/diary/dto/DiaryResponse.java | 21 ++--- .../solitour/diary/entity/Diary.java | 13 +--- .../repository/DiaryDayContentRepository.java | 4 - .../diary/repository/DiaryRepository.java | 2 +- .../repository/DiaryRepositoryCustom.java | 11 +++ .../diary/repository/DiaryRepositoryImpl.java | 76 +++++++++++++++++++ .../solitour/diary/service/DiaryService.java | 12 +-- .../error/GlobalControllerAdvice.java | 6 +- .../RequestValidationFailedException.java | 2 - .../controller/GatheringController.java | 32 +++++--- .../dto/request/GatheringPageRequest.java | 3 +- .../dto/response/GatheringDetailResponse.java | 1 - .../repository/GatheringRepositoryCustom.java | 4 +- .../repository/GatheringRepositoryImpl.java | 32 ++++---- .../gathering/service/GatheringService.java | 56 +++++++++----- .../service/GatheringApplicantsService.java | 7 +- .../GatheringCategoryController.java | 14 ++-- .../dto/mapper/GatheringCategoryMapper.java | 1 - .../service/GatheringCategoryService.java | 7 +- .../image/controller/ImageController.java | 9 +-- .../solitour/image/service/ImageService.java | 2 - .../controller/InformationController.java | 27 ++++--- .../InformationRepositoryCustom.java | 5 +- .../repository/InformationRepositoryImpl.java | 10 +-- .../service/InformationService.java | 17 +++-- 34 files changed, 338 insertions(+), 173 deletions(-) create mode 100644 src/main/java/solitour_backend/solitour/diary/dto/DiaryContent.java create mode 100644 src/main/java/solitour_backend/solitour/diary/dto/DiaryDayContentDetail.java create mode 100644 src/main/java/solitour_backend/solitour/diary/repository/DiaryRepositoryCustom.java create mode 100644 src/main/java/solitour_backend/solitour/diary/repository/DiaryRepositoryImpl.java diff --git a/src/main/java/solitour_backend/solitour/book_mark_information/controller/BookMarkInformationController.java b/src/main/java/solitour_backend/solitour/book_mark_information/controller/BookMarkInformationController.java index 0d573d15..1d9b1081 100644 --- a/src/main/java/solitour_backend/solitour/book_mark_information/controller/BookMarkInformationController.java +++ b/src/main/java/solitour_backend/solitour/book_mark_information/controller/BookMarkInformationController.java @@ -40,8 +40,8 @@ public ResponseEntity createUserBookmark( @Transactional @DeleteMapping() public ResponseEntity deleteUserBookmark(@AuthenticationPrincipal Long userId, - @RequestParam Long bookMarkId) { - service.deleteUserBookmark(userId, bookMarkId); + @RequestParam Long infoId) { + service.deleteUserBookmark(userId, infoId); return ResponseEntity.ok().build(); } diff --git a/src/main/java/solitour_backend/solitour/book_mark_information/entity/BookMarkInformationRepository.java b/src/main/java/solitour_backend/solitour/book_mark_information/entity/BookMarkInformationRepository.java index cbc5d85a..4e4e4610 100644 --- a/src/main/java/solitour_backend/solitour/book_mark_information/entity/BookMarkInformationRepository.java +++ b/src/main/java/solitour_backend/solitour/book_mark_information/entity/BookMarkInformationRepository.java @@ -10,7 +10,7 @@ public interface BookMarkInformationRepository extends JpaRepository findByUserId(Long userId); - Optional findByIdAndUserId(Long bookMarkId, Long userId); + Optional findByInformationIdAndUserId(Long infoId, Long userId); void deleteAllByInformationId(Long informationId); } diff --git a/src/main/java/solitour_backend/solitour/book_mark_information/service/BookMarkInformationService.java b/src/main/java/solitour_backend/solitour/book_mark_information/service/BookMarkInformationService.java index 34666823..f392b8ba 100644 --- a/src/main/java/solitour_backend/solitour/book_mark_information/service/BookMarkInformationService.java +++ b/src/main/java/solitour_backend/solitour/book_mark_information/service/BookMarkInformationService.java @@ -37,8 +37,8 @@ public void createUserBookmark(Long userId, Long infoId) { bookMarkInformationRepository.save(bookMarkInformation); } - public void deleteUserBookmark(Long userId, Long bookMarkId) { - BookMarkInformation bookmark = bookMarkInformationRepository.findByIdAndUserId(bookMarkId, + public void deleteUserBookmark(Long userId, Long infoId) { + BookMarkInformation bookmark = bookMarkInformationRepository.findByInformationIdAndUserId(infoId, userId) .orElseThrow(() -> new EntityNotFoundException("해당하는 북마크가 없습니다")); diff --git a/src/main/java/solitour_backend/solitour/category/repository/CategoryRepository.java b/src/main/java/solitour_backend/solitour/category/repository/CategoryRepository.java index 457b3785..479fdb09 100644 --- a/src/main/java/solitour_backend/solitour/category/repository/CategoryRepository.java +++ b/src/main/java/solitour_backend/solitour/category/repository/CategoryRepository.java @@ -1,7 +1,6 @@ package solitour_backend.solitour.category.repository; import java.util.List; - import org.springframework.data.jpa.repository.JpaRepository; import solitour_backend.solitour.category.entity.Category; diff --git a/src/main/java/solitour_backend/solitour/diary/controller/DiaryController.java b/src/main/java/solitour_backend/solitour/diary/controller/DiaryController.java index 27a86f52..d5cf9c42 100644 --- a/src/main/java/solitour_backend/solitour/diary/controller/DiaryController.java +++ b/src/main/java/solitour_backend/solitour/diary/controller/DiaryController.java @@ -1,6 +1,9 @@ package solitour_backend.solitour.diary.controller; import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.DeleteMapping; @@ -14,10 +17,9 @@ import org.springframework.web.bind.annotation.RestController; import solitour_backend.solitour.auth.config.Authenticated; import solitour_backend.solitour.auth.config.AuthenticationPrincipal; -import solitour_backend.solitour.diary.dto.DiaryListResponse; +import solitour_backend.solitour.diary.dto.DiaryContent; import solitour_backend.solitour.diary.dto.DiaryRequest; import solitour_backend.solitour.diary.dto.DiaryResponse; -import solitour_backend.solitour.diary.entity.Diary; import solitour_backend.solitour.diary.service.DiaryService; @RestController @@ -26,11 +28,16 @@ public class DiaryController { private final DiaryService diaryService; + public static final int PAGE_SIZE = 6; + @Authenticated @GetMapping() - public ResponseEntity getAllDiary(@AuthenticationPrincipal Long userId) { - DiaryListResponse response = diaryService.getAllDiary(userId); + public ResponseEntity> getAllDiary(@RequestParam(defaultValue = "0") int page, + @AuthenticationPrincipal Long userId) { + Pageable pageable = PageRequest.of(page, PAGE_SIZE); + + Page response = diaryService.getAllDiary(pageable, userId); return ResponseEntity.ok(response); } diff --git a/src/main/java/solitour_backend/solitour/diary/diary_day_content/DiaryDayContent.java b/src/main/java/solitour_backend/solitour/diary/diary_day_content/DiaryDayContent.java index f3317710..4a630075 100644 --- a/src/main/java/solitour_backend/solitour/diary/diary_day_content/DiaryDayContent.java +++ b/src/main/java/solitour_backend/solitour/diary/diary_day_content/DiaryDayContent.java @@ -11,23 +11,14 @@ import jakarta.persistence.JoinColumn; import jakarta.persistence.ManyToOne; import jakarta.persistence.Table; -import java.time.LocalDateTime; -import java.util.List; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; -import lombok.Setter; -import org.springframework.data.annotation.CreatedDate; -import org.springframework.data.annotation.LastModifiedDate; import org.springframework.data.jpa.domain.support.AuditingEntityListener; -import solitour_backend.solitour.diary.dto.DiaryRequest.DiaryDayRequest; import solitour_backend.solitour.diary.entity.Diary; import solitour_backend.solitour.diary.feeling_status.FeelingStatus; import solitour_backend.solitour.diary.feeling_status.FeelingStatusConverter; -import solitour_backend.solitour.gathering.entity.AllowedSex; -import solitour_backend.solitour.gathering.entity.AllowedSexConverter; -import solitour_backend.solitour.user.entity.User; @Entity @Getter diff --git a/src/main/java/solitour_backend/solitour/diary/dto/DiaryContent.java b/src/main/java/solitour_backend/solitour/diary/dto/DiaryContent.java new file mode 100644 index 00000000..836f4d78 --- /dev/null +++ b/src/main/java/solitour_backend/solitour/diary/dto/DiaryContent.java @@ -0,0 +1,49 @@ +package solitour_backend.solitour.diary.dto; + +import java.time.LocalDateTime; +import java.util.List; +import java.util.stream.Collectors; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import solitour_backend.solitour.diary.diary_day_content.DiaryDayContent; +import solitour_backend.solitour.diary.entity.Diary; + +@Getter +@Builder +@AllArgsConstructor +public class DiaryContent { + private Long diaryId; + private String title; + private String titleImage; + private LocalDateTime startDatetime; + private LocalDateTime endDatetime; + private DiaryDayContentResponse diaryDayContentResponses; + + public static DiaryContent from(Diary diary) { + return DiaryContent.builder() + .diaryId(diary.getId()) + .title(diary.getTitle()) + .titleImage(diary.getTitleImage()) + .startDatetime(diary.getStartDatetime()) + .endDatetime(diary.getEndDatetime()) + .diaryDayContentResponses(new DiaryDayContentResponse(diary.getDiaryDayContent())) + .build(); + } + + @Getter + public static class DiaryDayContentResponse { + private final List diaryDayContentDetail; + + public DiaryDayContentResponse(List diaryDayContent) { + this.diaryDayContentDetail = diaryDayContent.stream() + .map(diaryDayContentDetail -> + new DiaryDayContentDetail( + diaryDayContentDetail.getContent(), + diaryDayContentDetail.getFeelingStatus().name(), + diaryDayContentDetail.getPlace() + ) + ).collect(Collectors.toList()); + } + } +} diff --git a/src/main/java/solitour_backend/solitour/diary/dto/DiaryDayContentDetail.java b/src/main/java/solitour_backend/solitour/diary/dto/DiaryDayContentDetail.java new file mode 100644 index 00000000..3d64d6d4 --- /dev/null +++ b/src/main/java/solitour_backend/solitour/diary/dto/DiaryDayContentDetail.java @@ -0,0 +1,14 @@ +package solitour_backend.solitour.diary.dto; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; + +@Getter +@Builder +@AllArgsConstructor +public class DiaryDayContentDetail { + private String content; + private String feelingStatus; + private String place; +} diff --git a/src/main/java/solitour_backend/solitour/diary/dto/DiaryListResponse.java b/src/main/java/solitour_backend/solitour/diary/dto/DiaryListResponse.java index 3a505191..f0874032 100644 --- a/src/main/java/solitour_backend/solitour/diary/dto/DiaryListResponse.java +++ b/src/main/java/solitour_backend/solitour/diary/dto/DiaryListResponse.java @@ -12,17 +12,17 @@ public class DiaryListResponse { private final List diaryContentResponse; - public DiaryListResponse(List diaries) { + public DiaryListResponse(List> diaries) { - diaryContentResponse= diaries.stream().map( - diary -> DiaryContent.builder() - .diaryId(diary.getId()) - .title(diary.getTitle()) - .titleImage(diary.getTitleImage()) - .startDatetime(diary.getStartDatetime()) - .endDatetime(diary.getEndDatetime()) - .diaryDayContentResponses(new DiaryDayContentResponse(diary.getDiaryDayContent())).build() - ).collect(Collectors.toList()); + diaryContentResponse = diaries.stream().flatMap(List::stream).map( + diary -> DiaryContent.builder() + .diaryId(diary.getId()) + .title(diary.getTitle()) + .titleImage(diary.getTitleImage()) + .startDatetime(diary.getStartDatetime()) + .endDatetime(diary.getEndDatetime()) + .diaryDayContentResponses(new DiaryDayContentResponse(diary.getDiaryDayContent())).build() + ).collect(Collectors.toList()); } @@ -42,18 +42,19 @@ private static class DiaryDayContentResponse { private final List diaryDayContentDetail; - private DiaryDayContentResponse(List diaryDayContent) { - this.diaryDayContentDetail = diaryDayContent.stream() - .map(diaryDayContentDetail -> - DiaryDayContentDetail.builder() - .content(diaryDayContentDetail.getContent()) - .feelingStatus(diaryDayContentDetail.getFeelingStatus().name()) - .place(diaryDayContentDetail.getPlace()) - .build() - ).collect(Collectors.toList()); + private DiaryDayContentResponse(List diaryDayContent) { + this.diaryDayContentDetail = diaryDayContent.stream() + .map(diaryDayContentDetail -> + DiaryDayContentDetail.builder() + .content(diaryDayContentDetail.getContent()) + .feelingStatus(diaryDayContentDetail.getFeelingStatus().name()) + .place(diaryDayContentDetail.getPlace()) + .build() + ).collect(Collectors.toList()); } } + @Getter @Builder private static class DiaryDayContentDetail { diff --git a/src/main/java/solitour_backend/solitour/diary/dto/DiaryResponse.java b/src/main/java/solitour_backend/solitour/diary/dto/DiaryResponse.java index 5ac7ec9b..1ac8d45e 100644 --- a/src/main/java/solitour_backend/solitour/diary/dto/DiaryResponse.java +++ b/src/main/java/solitour_backend/solitour/diary/dto/DiaryResponse.java @@ -14,7 +14,7 @@ public class DiaryResponse { public DiaryResponse(Diary diary) { - diaryContentResponse= DiaryContent.builder() + diaryContentResponse = DiaryContent.builder() .diaryId(diary.getId()) .title(diary.getTitle()) .titleImage(diary.getTitleImage()) @@ -40,18 +40,19 @@ private static class DiaryDayContentResponse { private final List diaryDayContentDetail; - private DiaryDayContentResponse(List diaryDayContent) { - this.diaryDayContentDetail = diaryDayContent.stream() - .map(diaryDayContentDetail -> - DiaryDayContentDetail.builder() - .content(diaryDayContentDetail.getContent()) - .feelingStatus(diaryDayContentDetail.getFeelingStatus().name()) - .place(diaryDayContentDetail.getPlace()) - .build() - ).collect(Collectors.toList()); + private DiaryDayContentResponse(List diaryDayContent) { + this.diaryDayContentDetail = diaryDayContent.stream() + .map(diaryDayContentDetail -> + DiaryDayContentDetail.builder() + .content(diaryDayContentDetail.getContent()) + .feelingStatus(diaryDayContentDetail.getFeelingStatus().name()) + .place(diaryDayContentDetail.getPlace()) + .build() + ).collect(Collectors.toList()); } } + @Getter @Builder private static class DiaryDayContentDetail { diff --git a/src/main/java/solitour_backend/solitour/diary/entity/Diary.java b/src/main/java/solitour_backend/solitour/diary/entity/Diary.java index 59df6a8f..c9b174b5 100644 --- a/src/main/java/solitour_backend/solitour/diary/entity/Diary.java +++ b/src/main/java/solitour_backend/solitour/diary/entity/Diary.java @@ -2,7 +2,6 @@ import jakarta.persistence.CascadeType; import jakarta.persistence.Column; -import jakarta.persistence.Convert; import jakarta.persistence.Entity; import jakarta.persistence.EntityListeners; import jakarta.persistence.FetchType; @@ -19,22 +18,12 @@ import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; -import lombok.Setter; import org.springframework.data.annotation.CreatedDate; import org.springframework.data.annotation.LastModifiedDate; import org.springframework.data.jpa.domain.support.AuditingEntityListener; import solitour_backend.solitour.diary.diary_day_content.DiaryDayContent; import solitour_backend.solitour.diary.dto.DiaryRequest; -import solitour_backend.solitour.diary.dto.DiaryRequest.DiaryDayRequest; -import solitour_backend.solitour.diary.feeling_status.FeelingStatus; -import solitour_backend.solitour.diary.feeling_status.FeelingStatusConverter; -import solitour_backend.solitour.gathering.entity.AllowedSex; -import solitour_backend.solitour.gathering.entity.AllowedSexConverter; -import solitour_backend.solitour.gathering_category.entity.GatheringCategory; -import solitour_backend.solitour.place.entity.Place; import solitour_backend.solitour.user.entity.User; -import solitour_backend.solitour.user.user_status.UserStatusConverter; -import solitour_backend.solitour.zone_category.entity.ZoneCategory; @Entity @@ -67,7 +56,7 @@ public class Diary { @Column(name = "diary_end_date") private LocalDateTime endDatetime; - @OneToMany(fetch = FetchType.LAZY,cascade = CascadeType.ALL, orphanRemoval = true, mappedBy = "diary") + @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true, mappedBy = "diary") private List diaryDayContent; @CreatedDate diff --git a/src/main/java/solitour_backend/solitour/diary/repository/DiaryDayContentRepository.java b/src/main/java/solitour_backend/solitour/diary/repository/DiaryDayContentRepository.java index 836f4370..d006c104 100644 --- a/src/main/java/solitour_backend/solitour/diary/repository/DiaryDayContentRepository.java +++ b/src/main/java/solitour_backend/solitour/diary/repository/DiaryDayContentRepository.java @@ -1,11 +1,7 @@ package solitour_backend.solitour.diary.repository; -import java.util.Optional; import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.jpa.repository.Query; import solitour_backend.solitour.diary.diary_day_content.DiaryDayContent; -import solitour_backend.solitour.diary.entity.Diary; -import solitour_backend.solitour.user.entity.User; public interface DiaryDayContentRepository extends JpaRepository { } diff --git a/src/main/java/solitour_backend/solitour/diary/repository/DiaryRepository.java b/src/main/java/solitour_backend/solitour/diary/repository/DiaryRepository.java index efd2dd58..3e0fc381 100644 --- a/src/main/java/solitour_backend/solitour/diary/repository/DiaryRepository.java +++ b/src/main/java/solitour_backend/solitour/diary/repository/DiaryRepository.java @@ -5,7 +5,7 @@ import org.springframework.data.jpa.repository.Query; import solitour_backend.solitour.diary.entity.Diary; -public interface DiaryRepository extends JpaRepository { +public interface DiaryRepository extends JpaRepository, DiaryRepositoryCustom { @Query("SELECT d FROM Diary d WHERE d.user.id = :userId") List findByUserId(Long userId); diff --git a/src/main/java/solitour_backend/solitour/diary/repository/DiaryRepositoryCustom.java b/src/main/java/solitour_backend/solitour/diary/repository/DiaryRepositoryCustom.java new file mode 100644 index 00000000..c82238e1 --- /dev/null +++ b/src/main/java/solitour_backend/solitour/diary/repository/DiaryRepositoryCustom.java @@ -0,0 +1,11 @@ +package solitour_backend.solitour.diary.repository; + +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.repository.NoRepositoryBean; +import solitour_backend.solitour.diary.dto.DiaryContent; + +@NoRepositoryBean +public interface DiaryRepositoryCustom { + Page getAllDiaryPageFilterAndOrder(Pageable pageable, Long userId); +} diff --git a/src/main/java/solitour_backend/solitour/diary/repository/DiaryRepositoryImpl.java b/src/main/java/solitour_backend/solitour/diary/repository/DiaryRepositoryImpl.java new file mode 100644 index 00000000..97aa245e --- /dev/null +++ b/src/main/java/solitour_backend/solitour/diary/repository/DiaryRepositoryImpl.java @@ -0,0 +1,76 @@ +package solitour_backend.solitour.diary.repository; + +import com.querydsl.jpa.impl.JPAQueryFactory; +import jakarta.annotation.PostConstruct; +import jakarta.persistence.EntityManager; +import jakarta.persistence.PersistenceContext; +import java.util.List; +import java.util.stream.Collectors; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageImpl; +import org.springframework.data.domain.Pageable; +import org.springframework.data.jpa.repository.support.QuerydslRepositorySupport; +import solitour_backend.solitour.diary.diary_day_content.QDiaryDayContent; +import solitour_backend.solitour.diary.dto.DiaryContent; +import solitour_backend.solitour.diary.dto.DiaryContent.DiaryDayContentResponse; +import solitour_backend.solitour.diary.entity.Diary; +import solitour_backend.solitour.diary.entity.QDiary; +import solitour_backend.solitour.user.entity.QUser; + +public class DiaryRepositoryImpl extends QuerydslRepositorySupport implements DiaryRepositoryCustom { + + @PersistenceContext + private EntityManager entityManager; + + private JPAQueryFactory queryFactory; + + public DiaryRepositoryImpl() { + super(Diary.class); + } + + @PostConstruct + private void init() { + this.queryFactory = new JPAQueryFactory(entityManager); + } + + + QDiary diary = QDiary.diary; + QDiaryDayContent diaryDayContent = QDiaryDayContent.diaryDayContent; + QUser user = QUser.user; + + @Override + public Page getAllDiaryPageFilterAndOrder(Pageable pageable, Long userId) { + + List diaries = queryFactory + .selectFrom(diary) + .distinct() + .join(diary.diaryDayContent, diaryDayContent) + .join(diary.user, user) + .where(diary.user.id.eq(userId)) + .orderBy(diary.createdAt.desc()) + .offset(pageable.getOffset()) + .limit(pageable.getPageSize()) + .fetch(); + + List diaryContents = diaries.stream() + .map(diary -> DiaryContent.builder() + .diaryId(diary.getId()) + .title(diary.getTitle()) + .titleImage(diary.getTitleImage()) + .startDatetime(diary.getStartDatetime()) + .endDatetime(diary.getEndDatetime()) + .diaryDayContentResponses(new DiaryDayContentResponse( + diary.getDiaryDayContent() + )) + .build()).collect(Collectors.toList()); + + long totalCount = queryFactory.selectFrom(diary) + .distinct() + .join(diary.diaryDayContent, diaryDayContent) + .join(diary.user, user) + .where(diary.user.id.eq(userId)) + .fetchCount(); + + return new PageImpl<>(diaryContents, pageable, totalCount); + } +} diff --git a/src/main/java/solitour_backend/solitour/diary/service/DiaryService.java b/src/main/java/solitour_backend/solitour/diary/service/DiaryService.java index e3fbe3bc..53427d34 100644 --- a/src/main/java/solitour_backend/solitour/diary/service/DiaryService.java +++ b/src/main/java/solitour_backend/solitour/diary/service/DiaryService.java @@ -1,12 +1,13 @@ package solitour_backend.solitour.diary.service; import java.time.LocalDateTime; -import java.util.List; import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import solitour_backend.solitour.diary.diary_day_content.DiaryDayContent; -import solitour_backend.solitour.diary.dto.DiaryListResponse; +import solitour_backend.solitour.diary.dto.DiaryContent; import solitour_backend.solitour.diary.dto.DiaryRequest; import solitour_backend.solitour.diary.dto.DiaryRequest.DiaryDayRequest; import solitour_backend.solitour.diary.dto.DiaryResponse; @@ -58,9 +59,8 @@ private void saveDiaryDayContent(Diary savedDiary, DiaryRequest request) { } } - public DiaryListResponse getAllDiary(Long userId) { - List diaries = diaryRepository.findByUserId(userId); - return new DiaryListResponse(diaries); + public Page getAllDiary(Pageable pageable, Long userId) { + return diaryRepository.getAllDiaryPageFilterAndOrder(pageable, userId); } @@ -68,7 +68,7 @@ public DiaryResponse getDiary(Long userId, Long diaryId) { Diary diary = diaryRepository.findById(diaryId) .orElseThrow(() -> new IllegalArgumentException("해당 일기가 존재하지 않습니다.")); - if(!diary.getUser().getId().equals(userId)){ + if (!diary.getUser().getId().equals(userId)) { throw new IllegalArgumentException("해당 일기에 대한 권한이 없습니다."); } diff --git a/src/main/java/solitour_backend/solitour/error/GlobalControllerAdvice.java b/src/main/java/solitour_backend/solitour/error/GlobalControllerAdvice.java index a73f8fad..ebf7071e 100644 --- a/src/main/java/solitour_backend/solitour/error/GlobalControllerAdvice.java +++ b/src/main/java/solitour_backend/solitour/error/GlobalControllerAdvice.java @@ -9,7 +9,11 @@ import solitour_backend.solitour.gathering.exception.GatheringCategoryNotExistsException; import solitour_backend.solitour.gathering.exception.GatheringDeleteException; import solitour_backend.solitour.gathering.exception.GatheringNotExistsException; -import solitour_backend.solitour.gathering_applicants.exception.*; +import solitour_backend.solitour.gathering_applicants.exception.GatheringApplicantsAlreadyExistsException; +import solitour_backend.solitour.gathering_applicants.exception.GatheringApplicantsAlreadyFullPeopleException; +import solitour_backend.solitour.gathering_applicants.exception.GatheringApplicantsManagerException; +import solitour_backend.solitour.gathering_applicants.exception.GatheringApplicantsNotExistsException; +import solitour_backend.solitour.gathering_applicants.exception.GatheringNotManagerException; import solitour_backend.solitour.image.exception.ImageAlreadyExistsException; import solitour_backend.solitour.image.exception.ImageNotExistsException; import solitour_backend.solitour.image.exception.ImageRequestValidationFailedException; diff --git a/src/main/java/solitour_backend/solitour/error/exception/RequestValidationFailedException.java b/src/main/java/solitour_backend/solitour/error/exception/RequestValidationFailedException.java index f179eed6..cb5d1fde 100644 --- a/src/main/java/solitour_backend/solitour/error/exception/RequestValidationFailedException.java +++ b/src/main/java/solitour_backend/solitour/error/exception/RequestValidationFailedException.java @@ -1,9 +1,7 @@ package solitour_backend.solitour.error.exception; import jakarta.validation.ValidationException; - import java.util.stream.Collectors; - import org.springframework.validation.BindingResult; public class RequestValidationFailedException extends ValidationException { diff --git a/src/main/java/solitour_backend/solitour/gathering/controller/GatheringController.java b/src/main/java/solitour_backend/solitour/gathering/controller/GatheringController.java index 2cd67adf..ba5151c8 100644 --- a/src/main/java/solitour_backend/solitour/gathering/controller/GatheringController.java +++ b/src/main/java/solitour_backend/solitour/gathering/controller/GatheringController.java @@ -1,12 +1,12 @@ package solitour_backend.solitour.gathering.controller; +import static solitour_backend.solitour.information.controller.InformationController.PAGE_SIZE; + import jakarta.servlet.http.HttpServletRequest; import jakarta.validation.Valid; - import java.time.LocalDateTime; import java.util.List; import java.util.Objects; - import lombok.RequiredArgsConstructor; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; @@ -14,7 +14,16 @@ import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.validation.BindingResult; -import org.springframework.web.bind.annotation.*; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.ModelAttribute; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; import solitour_backend.solitour.auth.config.AuthenticationPrincipal; import solitour_backend.solitour.auth.support.CookieExtractor; import solitour_backend.solitour.auth.support.JwtTokenProvider; @@ -29,8 +38,6 @@ import solitour_backend.solitour.gathering.dto.response.GatheringResponse; import solitour_backend.solitour.gathering.service.GatheringService; -import static solitour_backend.solitour.information.controller.InformationController.PAGE_SIZE; - @RestController @RequiredArgsConstructor @RequestMapping("/api/gatherings") @@ -110,15 +117,17 @@ public ResponseEntity deleteGathering(@PathVariable Long gatheringId, Http @GetMapping - public ResponseEntity> pageGatheringSortAndFilter(@RequestParam(defaultValue = "0") int page, - @Valid @ModelAttribute GatheringPageRequest gatheringPageRequest, - BindingResult bindingResult, - HttpServletRequest request) { + public ResponseEntity> pageGatheringSortAndFilter( + @RequestParam(defaultValue = "0") int page, + @Valid @ModelAttribute GatheringPageRequest gatheringPageRequest, + BindingResult bindingResult, + HttpServletRequest request) { Utils.validationRequest(bindingResult); Long userId = findUser(request); Pageable pageable = PageRequest.of(page, PAGE_SIZE); - Page pageGathering = gatheringService.getPageGathering(pageable, gatheringPageRequest, userId); + Page pageGathering = gatheringService.getPageGathering(pageable, gatheringPageRequest, + userId); return ResponseEntity .status(HttpStatus.OK) @@ -138,7 +147,8 @@ public ResponseEntity> getGatheringRankOrderByLikes( public ResponseEntity> getHomeGathering(HttpServletRequest request) { Long userId = findUser(request); - List gatheringOrderByLikesFilterByCreate3After = gatheringService.getGatheringOrderByLikesFilterByCreate3After(userId); + List gatheringOrderByLikesFilterByCreate3After = gatheringService.getGatheringOrderByLikesFilterByCreate3After( + userId); return ResponseEntity .status(HttpStatus.OK) diff --git a/src/main/java/solitour_backend/solitour/gathering/dto/request/GatheringPageRequest.java b/src/main/java/solitour_backend/solitour/gathering/dto/request/GatheringPageRequest.java index a75dd2f6..bd6deb0a 100644 --- a/src/main/java/solitour_backend/solitour/gathering/dto/request/GatheringPageRequest.java +++ b/src/main/java/solitour_backend/solitour/gathering/dto/request/GatheringPageRequest.java @@ -2,6 +2,7 @@ import com.fasterxml.jackson.annotation.JsonFormat; import jakarta.validation.constraints.Min; +import java.time.LocalDate; import lombok.AllArgsConstructor; import lombok.Getter; import lombok.NoArgsConstructor; @@ -9,8 +10,6 @@ import org.springframework.format.annotation.DateTimeFormat; import solitour_backend.solitour.gathering.entity.AllowedSex; -import java.time.LocalDate; - @Getter @Setter @AllArgsConstructor diff --git a/src/main/java/solitour_backend/solitour/gathering/dto/response/GatheringDetailResponse.java b/src/main/java/solitour_backend/solitour/gathering/dto/response/GatheringDetailResponse.java index 00f9fa0d..f08ffcb3 100644 --- a/src/main/java/solitour_backend/solitour/gathering/dto/response/GatheringDetailResponse.java +++ b/src/main/java/solitour_backend/solitour/gathering/dto/response/GatheringDetailResponse.java @@ -2,7 +2,6 @@ import java.time.LocalDateTime; import java.util.List; - import lombok.AllArgsConstructor; import lombok.Getter; import solitour_backend.solitour.gathering.entity.AllowedSex; diff --git a/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryCustom.java b/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryCustom.java index 7463330c..bee8bc18 100644 --- a/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryCustom.java +++ b/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryCustom.java @@ -1,7 +1,6 @@ package solitour_backend.solitour.gathering.repository; import java.util.List; - import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.repository.NoRepositoryBean; @@ -16,7 +15,8 @@ public interface GatheringRepositoryCustom { List getGatheringRecommend(Long informationId, Long gatheringCategoryId, Long userId); - Page getGatheringPageFilterAndOrder(Pageable pageable, GatheringPageRequest gatheringPageRequest, Long userId); + Page getGatheringPageFilterAndOrder(Pageable pageable, + GatheringPageRequest gatheringPageRequest, Long userId); List getGatheringRankList(); diff --git a/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryImpl.java b/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryImpl.java index 935666c6..503cdc72 100644 --- a/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryImpl.java +++ b/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryImpl.java @@ -3,22 +3,18 @@ import com.querydsl.core.BooleanBuilder; import com.querydsl.core.types.OrderSpecifier; import com.querydsl.core.types.Projections; - +import com.querydsl.core.types.dsl.BooleanExpression; +import com.querydsl.core.types.dsl.CaseBuilder; +import com.querydsl.core.types.dsl.Expressions; +import com.querydsl.core.types.dsl.NumberExpression; +import com.querydsl.core.types.dsl.PathBuilder; +import com.querydsl.jpa.JPAExpressions; +import com.querydsl.jpa.JPQLQuery; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.LocalTime; import java.util.List; import java.util.Objects; -import java.util.Optional; - -import com.querydsl.core.types.dsl.*; -import com.querydsl.jpa.JPAExpressions; -import com.querydsl.jpa.JPQLQuery; -import com.querydsl.jpa.impl.JPAQuery; -import com.querydsl.jpa.impl.JPAQueryFactory; -import jakarta.annotation.PostConstruct; -import jakarta.persistence.EntityManager; -import jakarta.persistence.PersistenceContext; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageImpl; import org.springframework.data.domain.Pageable; @@ -98,7 +94,9 @@ public List getGatheringRecommend(Long gatheringId, Long @Override - public Page getGatheringPageFilterAndOrder(Pageable pageable, GatheringPageRequest gatheringPageRequest, Long userId) { + public Page getGatheringPageFilterAndOrder(Pageable pageable, + GatheringPageRequest gatheringPageRequest, + Long userId) { BooleanBuilder booleanBuilder = makeWhereSQL(gatheringPageRequest); OrderSpecifier orderSpecifier = getOrderSpecifier(gatheringPageRequest.getSort()); @@ -108,16 +106,17 @@ public Page getGatheringPageFilterAndOrder(Pageable page long total = from(gathering) .join(zoneCategoryChild).on(zoneCategoryChild.id.eq(gathering.zoneCategory.id)) .leftJoin(zoneCategoryParent).on(zoneCategoryParent.id.eq(zoneCategoryChild.parentZoneCategory.id)) - .leftJoin(bookMarkGathering).on(bookMarkGathering.gathering.id.eq(gathering.id).and(bookMarkGathering.user.id.eq(userId))) + .leftJoin(bookMarkGathering) + .on(bookMarkGathering.gathering.id.eq(gathering.id).and(bookMarkGathering.user.id.eq(userId))) .leftJoin(gatheringApplicants).on(gatheringApplicants.gathering.id.eq(gathering.id)) .where(booleanBuilder) .select(gathering.id.count()).fetchCount(); - List content = from(gathering) .join(zoneCategoryChild).on(zoneCategoryChild.id.eq(gathering.zoneCategory.id)) .leftJoin(zoneCategoryParent).on(zoneCategoryParent.id.eq(zoneCategoryChild.parentZoneCategory.id)) - .leftJoin(bookMarkGathering).on(bookMarkGathering.gathering.id.eq(gathering.id).and(bookMarkGathering.user.id.eq(userId))) + .leftJoin(bookMarkGathering) + .on(bookMarkGathering.gathering.id.eq(gathering.id).and(bookMarkGathering.user.id.eq(userId))) .leftJoin(gatheringApplicants).on(gatheringApplicants.gathering.id.eq(gathering.id)) .where(booleanBuilder) .groupBy(gathering.id, zoneCategoryChild.id, zoneCategoryParent.id, category.id, @@ -239,7 +238,8 @@ private BooleanBuilder makeWhereSQL(GatheringPageRequest gatheringPageRequest) { whereClause.and(gathering.startAge.goe(userMaxBirthYear)).and(gathering.endAge.loe(userMinBirthYear)); } - if (Objects.nonNull(gatheringPageRequest.getStartDate()) && Objects.nonNull(gatheringPageRequest.getEndDate())) { + if (Objects.nonNull(gatheringPageRequest.getStartDate()) && Objects.nonNull( + gatheringPageRequest.getEndDate())) { whereClause.and(gathering.scheduleStartDate.goe(gatheringPageRequest.getStartDate().atStartOfDay())) .and(gathering.scheduleEndDate.loe(gatheringPageRequest.getEndDate().atTime(LocalTime.MAX))); } diff --git a/src/main/java/solitour_backend/solitour/gathering/service/GatheringService.java b/src/main/java/solitour_backend/solitour/gathering/service/GatheringService.java index 9191b494..8844c374 100644 --- a/src/main/java/solitour_backend/solitour/gathering/service/GatheringService.java +++ b/src/main/java/solitour_backend/solitour/gathering/service/GatheringService.java @@ -1,9 +1,11 @@ package solitour_backend.solitour.gathering.service; +import static solitour_backend.solitour.gathering.repository.GatheringRepositoryCustom.LIKE_COUNT_SORT; +import static solitour_backend.solitour.gathering.repository.GatheringRepositoryCustom.VIEW_COUNT_SORT; + import java.util.ArrayList; import java.util.List; import java.util.Objects; - import lombok.RequiredArgsConstructor; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; @@ -57,9 +59,6 @@ import solitour_backend.solitour.zone_category.exception.ZoneCategoryNotExistsException; import solitour_backend.solitour.zone_category.repository.ZoneCategoryRepository; -import static solitour_backend.solitour.gathering.repository.GatheringRepositoryCustom.LIKE_COUNT_SORT; -import static solitour_backend.solitour.gathering.repository.GatheringRepositoryCustom.VIEW_COUNT_SORT; - @Service @Transactional(readOnly = true) @@ -106,19 +105,25 @@ public GatheringDetailResponse getGatheringDetail(Long userId, Long gatheringId) } GatheringCategory gatheringCategory = gathering.getGatheringCategory(); - GatheringCategoryResponse gatheringCategoryResponse = gatheringCategoryMapper.mapToCategoryResponse(gatheringCategory); + GatheringCategoryResponse gatheringCategoryResponse = gatheringCategoryMapper.mapToCategoryResponse( + gatheringCategory); PlaceResponse placeResponse = placeMapper.mapToPlaceResponse(gathering.getPlace()); - ZoneCategoryResponse zoneCategoryResponse = zoneCategoryMapper.mapToZoneCategoryResponse(gathering.getZoneCategory()); + ZoneCategoryResponse zoneCategoryResponse = zoneCategoryMapper.mapToZoneCategoryResponse( + gathering.getZoneCategory()); int likeCount = greatGatheringRepository.countByGatheringId(gathering.getId()); - List gatheringApplicantsResponses = gatheringApplicantsMapper.mapToGatheringApplicantsResponses(gatheringApplicantsRepository.findAllByGathering_IdAndUserIdNot(gathering.getId(), gathering.getUser().getId())); + List gatheringApplicantsResponses = gatheringApplicantsMapper.mapToGatheringApplicantsResponses( + gatheringApplicantsRepository.findAllByGathering_IdAndUserIdNot(gathering.getId(), + gathering.getUser().getId())); - int nowPersonCount = gatheringApplicantsRepository.countAllByGathering_IdAndGatheringStatus(gathering.getId(), GatheringStatus.CONSENT); + int nowPersonCount = gatheringApplicantsRepository.countAllByGathering_IdAndGatheringStatus(gathering.getId(), + GatheringStatus.CONSENT); - boolean isLike = greatGatheringRepository.existsByGatheringIdAndUserIdAndIsDeletedFalse(gathering.getId(), userId); + boolean isLike = greatGatheringRepository.existsByGatheringIdAndUserIdAndIsDeletedFalse(gathering.getId(), + userId); List gatheringRecommend = gatheringRepository.getGatheringRecommend(gathering.getId(), gathering.getGatheringCategory().getId(), userId); @@ -164,16 +169,19 @@ public GatheringResponse registerGathering(Long userId, GatheringRegisterRequest User user = userRepository.findById(userId) .orElseThrow( () -> new UserNotExistsException("해당하는 id의 User 가 없습니다")); - GatheringCategory gatheringCategory = gatheringCategoryRepository.findById(gatheringRegisterRequest.getGatheringCategoryId()) + GatheringCategory gatheringCategory = gatheringCategoryRepository.findById( + gatheringRegisterRequest.getGatheringCategoryId()) .orElseThrow( () -> new GatheringCategoryNotExistsException("해당하는 id의 category 가 없습니다")); - ZoneCategory parentZoneCategory = zoneCategoryRepository.findByParentZoneCategoryIdAndName(null, gatheringRegisterRequest.getZoneCategoryNameParent()) + ZoneCategory parentZoneCategory = zoneCategoryRepository.findByParentZoneCategoryIdAndName(null, + gatheringRegisterRequest.getZoneCategoryNameParent()) .orElseThrow( () -> new ZoneCategoryNotExistsException("해당하는 name의 ZoneCategory 없습니다")); - ZoneCategory childZoneCategory = zoneCategoryRepository.findByParentZoneCategoryIdAndName(parentZoneCategory.getId(), gatheringRegisterRequest.getZoneCategoryNameChild()) + ZoneCategory childZoneCategory = zoneCategoryRepository.findByParentZoneCategoryIdAndName( + parentZoneCategory.getId(), gatheringRegisterRequest.getZoneCategoryNameChild()) .orElseThrow( () -> new ZoneCategoryNotExistsException("해당하는 name의 ZoneCategory 없습니다")); @@ -227,15 +235,18 @@ public GatheringResponse modifyGathering(Long userId, Long gatheringId, throw new GatheringNotManagerException("해당 유저는 권한이 없습니다"); } - GatheringCategory gatheringCategory = gatheringCategoryRepository.findById(gatheringModifyRequest.getGatheringCategoryId()) + GatheringCategory gatheringCategory = gatheringCategoryRepository.findById( + gatheringModifyRequest.getGatheringCategoryId()) .orElseThrow( () -> new GatheringCategoryNotExistsException("모임 카테고리가 존재 하지 않습니다") ); - ZoneCategory parentZoneCategory = zoneCategoryRepository.findByParentZoneCategoryIdAndName(null, gatheringModifyRequest.getZoneCategoryNameParent()) + ZoneCategory parentZoneCategory = zoneCategoryRepository.findByParentZoneCategoryIdAndName(null, + gatheringModifyRequest.getZoneCategoryNameParent()) .orElseThrow( () -> new ZoneCategoryNotExistsException("부모 지역 카테고리가 존재 하지 않습니다") ); - ZoneCategory childZoneCategory = zoneCategoryRepository.findByParentZoneCategoryIdAndName(parentZoneCategory.getId(), gatheringModifyRequest.getZoneCategoryNameChild()) + ZoneCategory childZoneCategory = zoneCategoryRepository.findByParentZoneCategoryIdAndName( + parentZoneCategory.getId(), gatheringModifyRequest.getZoneCategoryNameChild()) .orElseThrow( () -> new ZoneCategoryNotExistsException("자식 지역 카테고리가 존재 하지 않습니다") ); @@ -301,7 +312,8 @@ public void deleteGathering(Long gatheringId, Long userId) { } - public Page getPageGathering(Pageable pageable, GatheringPageRequest gatheringPageRequest, Long userId) { + public Page getPageGathering(Pageable pageable, GatheringPageRequest gatheringPageRequest, + Long userId) { validateGatheringPageRequest(gatheringPageRequest); return gatheringRepository.getGatheringPageFilterAndOrder(pageable, gatheringPageRequest, userId); @@ -336,23 +348,27 @@ private void validateGatheringPageRequest(GatheringPageRequest gatheringPageRequ if (gatheringPageRequest.getStartAge() > gatheringPageRequest.getEndAge()) { throw new RequestValidationFailedException("시작 나이가 끝 나이보다 클 수 없습니다."); } - } else if (Objects.nonNull(gatheringPageRequest.getStartAge()) || Objects.nonNull(gatheringPageRequest.getEndAge())) { + } else if (Objects.nonNull(gatheringPageRequest.getStartAge()) || Objects.nonNull( + gatheringPageRequest.getEndAge())) { throw new RequestValidationFailedException("시작 나이와 끝 나이는 둘 다 입력되거나 둘 다 비어 있어야 합니다."); } // 정렬 방식 검증 if (Objects.nonNull(gatheringPageRequest.getSort())) { - if (!LIKE_COUNT_SORT.equals(gatheringPageRequest.getSort()) && !VIEW_COUNT_SORT.equals(gatheringPageRequest.getSort())) { + if (!LIKE_COUNT_SORT.equals(gatheringPageRequest.getSort()) && !VIEW_COUNT_SORT.equals( + gatheringPageRequest.getSort())) { throw new RequestValidationFailedException("잘못된 정렬 코드입니다."); } } // 날짜 검증 - if (Objects.nonNull(gatheringPageRequest.getStartDate()) && Objects.nonNull(gatheringPageRequest.getEndDate())) { + if (Objects.nonNull(gatheringPageRequest.getStartDate()) && Objects.nonNull( + gatheringPageRequest.getEndDate())) { if (gatheringPageRequest.getStartDate().isAfter(gatheringPageRequest.getEndDate())) { throw new RequestValidationFailedException("시작 날짜가 종료 날짜보다 나중일 수 없습니다."); } - } else if (Objects.nonNull(gatheringPageRequest.getStartDate()) || Objects.nonNull(gatheringPageRequest.getEndDate())) { + } else if (Objects.nonNull(gatheringPageRequest.getStartDate()) || Objects.nonNull( + gatheringPageRequest.getEndDate())) { throw new RequestValidationFailedException("시작 날짜와 종료 날짜는 둘 다 입력되거나 둘 다 비어 있어야 합니다."); } } diff --git a/src/main/java/solitour_backend/solitour/gathering_applicants/service/GatheringApplicantsService.java b/src/main/java/solitour_backend/solitour/gathering_applicants/service/GatheringApplicantsService.java index 44cabd8a..30dea7f5 100644 --- a/src/main/java/solitour_backend/solitour/gathering_applicants/service/GatheringApplicantsService.java +++ b/src/main/java/solitour_backend/solitour/gathering_applicants/service/GatheringApplicantsService.java @@ -1,7 +1,6 @@ package solitour_backend.solitour.gathering_applicants.service; import java.util.Objects; - import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -11,7 +10,11 @@ import solitour_backend.solitour.gathering_applicants.dto.request.GatheringApplicantsModifyRequest; import solitour_backend.solitour.gathering_applicants.entity.GatheringApplicants; import solitour_backend.solitour.gathering_applicants.entity.GatheringStatus; -import solitour_backend.solitour.gathering_applicants.exception.*; +import solitour_backend.solitour.gathering_applicants.exception.GatheringApplicantsAlreadyExistsException; +import solitour_backend.solitour.gathering_applicants.exception.GatheringApplicantsAlreadyFullPeopleException; +import solitour_backend.solitour.gathering_applicants.exception.GatheringApplicantsManagerException; +import solitour_backend.solitour.gathering_applicants.exception.GatheringApplicantsNotExistsException; +import solitour_backend.solitour.gathering_applicants.exception.GatheringNotManagerException; import solitour_backend.solitour.gathering_applicants.repository.GatheringApplicantsRepository; import solitour_backend.solitour.user.entity.User; import solitour_backend.solitour.user.entity.UserRepository; diff --git a/src/main/java/solitour_backend/solitour/gathering_category/controller/GatheringCategoryController.java b/src/main/java/solitour_backend/solitour/gathering_category/controller/GatheringCategoryController.java index 7ade5fba..4ccae990 100644 --- a/src/main/java/solitour_backend/solitour/gathering_category/controller/GatheringCategoryController.java +++ b/src/main/java/solitour_backend/solitour/gathering_category/controller/GatheringCategoryController.java @@ -1,9 +1,7 @@ package solitour_backend.solitour.gathering_category.controller; import jakarta.validation.Valid; - import java.util.List; - import lombok.RequiredArgsConstructor; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -48,8 +46,9 @@ public ResponseEntity getCategory(@PathVariable Long } @PostMapping - public ResponseEntity registerCategory(@Valid @RequestBody CategoryRegisterRequest categoryRegisterRequest, - BindingResult bindingResult) { + public ResponseEntity registerCategory( + @Valid @RequestBody CategoryRegisterRequest categoryRegisterRequest, + BindingResult bindingResult) { Utils.validationRequest(bindingResult); GatheringCategoryResponse categoryResponse = gatheringCategoryService.registerCategory( @@ -61,9 +60,10 @@ public ResponseEntity registerCategory(@Valid @Reques } @PutMapping("/{id}") - public ResponseEntity modifyCategory(@Valid @RequestBody GatheringCategoryModifyRequest gatheringCategoryModifyRequest, - BindingResult bindingResult, - @PathVariable Long id) { + public ResponseEntity modifyCategory( + @Valid @RequestBody GatheringCategoryModifyRequest gatheringCategoryModifyRequest, + BindingResult bindingResult, + @PathVariable Long id) { if (bindingResult.hasErrors()) { throw new RequestValidationFailedException(bindingResult); } diff --git a/src/main/java/solitour_backend/solitour/gathering_category/dto/mapper/GatheringCategoryMapper.java b/src/main/java/solitour_backend/solitour/gathering_category/dto/mapper/GatheringCategoryMapper.java index 63eae28b..52be5ae4 100644 --- a/src/main/java/solitour_backend/solitour/gathering_category/dto/mapper/GatheringCategoryMapper.java +++ b/src/main/java/solitour_backend/solitour/gathering_category/dto/mapper/GatheringCategoryMapper.java @@ -1,7 +1,6 @@ package solitour_backend.solitour.gathering_category.dto.mapper; import java.util.List; - import org.mapstruct.Mapper; import org.mapstruct.ReportingPolicy; import solitour_backend.solitour.gathering_category.dto.response.GatheringCategoryResponse; diff --git a/src/main/java/solitour_backend/solitour/gathering_category/service/GatheringCategoryService.java b/src/main/java/solitour_backend/solitour/gathering_category/service/GatheringCategoryService.java index a3cfdab6..eae4af03 100644 --- a/src/main/java/solitour_backend/solitour/gathering_category/service/GatheringCategoryService.java +++ b/src/main/java/solitour_backend/solitour/gathering_category/service/GatheringCategoryService.java @@ -1,13 +1,12 @@ package solitour_backend.solitour.gathering_category.service; import java.util.List; - import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import solitour_backend.solitour.gathering_category.dto.mapper.GatheringCategoryMapper; import solitour_backend.solitour.category.dto.request.CategoryRegisterRequest; import solitour_backend.solitour.category.exception.CategoryNotExistsException; +import solitour_backend.solitour.gathering_category.dto.mapper.GatheringCategoryMapper; import solitour_backend.solitour.gathering_category.dto.request.GatheringCategoryModifyRequest; import solitour_backend.solitour.gathering_category.dto.response.GatheringCategoryResponse; import solitour_backend.solitour.gathering_category.entity.GatheringCategory; @@ -24,7 +23,6 @@ public class GatheringCategoryService { @Transactional public GatheringCategoryResponse registerCategory(CategoryRegisterRequest categoryRegisterRequest) { - GatheringCategory category = new GatheringCategory(categoryRegisterRequest.getName()); GatheringCategory saveCategory = gatheringCategoryRepository.save(category); @@ -48,7 +46,8 @@ public List getCategories() { } @Transactional - public GatheringCategoryResponse modifyCategory(Long id, GatheringCategoryModifyRequest gatheringCategoryModifyRequest) { + public GatheringCategoryResponse modifyCategory(Long id, + GatheringCategoryModifyRequest gatheringCategoryModifyRequest) { GatheringCategory category = gatheringCategoryRepository.findById(id).orElseThrow(); category.setName(gatheringCategoryModifyRequest.getName()); diff --git a/src/main/java/solitour_backend/solitour/image/controller/ImageController.java b/src/main/java/solitour_backend/solitour/image/controller/ImageController.java index e3860cfd..0952cf7d 100644 --- a/src/main/java/solitour_backend/solitour/image/controller/ImageController.java +++ b/src/main/java/solitour_backend/solitour/image/controller/ImageController.java @@ -3,7 +3,6 @@ import lombok.RequiredArgsConstructor; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; -import org.springframework.validation.BindingResult; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; @@ -12,12 +11,8 @@ import org.springframework.web.multipart.MultipartFile; import solitour_backend.solitour.auth.config.Authenticated; import solitour_backend.solitour.auth.config.AuthenticationPrincipal; -import solitour_backend.solitour.error.Utils; import solitour_backend.solitour.image.dto.response.ImageResponse; import solitour_backend.solitour.image.service.ImageService; -import solitour_backend.solitour.user_image.dto.UserImageRequest; -import solitour_backend.solitour.user_image.dto.UserImageResponse; -import solitour_backend.solitour.user_image.service.UserImageService; @RestController @RequiredArgsConstructor @@ -29,11 +24,11 @@ public class ImageController { @Authenticated @PostMapping - public ResponseEntity uploadImage(@RequestParam Long id, + public ResponseEntity uploadImage(@AuthenticationPrincipal Long userId, @RequestPart("image") MultipartFile userImage, @RequestParam String type, @RequestParam String imageStatus) { - ImageResponse imageResponse = imageService.uploadImage(id, userImage, type, + ImageResponse imageResponse = imageService.uploadImage(userId, userImage, type, imageStatus); return ResponseEntity diff --git a/src/main/java/solitour_backend/solitour/image/service/ImageService.java b/src/main/java/solitour_backend/solitour/image/service/ImageService.java index b0fa0b7d..7f1b6764 100644 --- a/src/main/java/solitour_backend/solitour/image/service/ImageService.java +++ b/src/main/java/solitour_backend/solitour/image/service/ImageService.java @@ -10,8 +10,6 @@ import solitour_backend.solitour.image.image_status.ImageStatus; import solitour_backend.solitour.image.repository.ImageRepository; import solitour_backend.solitour.image.s3.S3Uploader; -import solitour_backend.solitour.user_image.dto.UserImageResponse; -import solitour_backend.solitour.user_image.entity.UserImage; import solitour_backend.solitour.user_image.entity.UserImageRepository; @RequiredArgsConstructor diff --git a/src/main/java/solitour_backend/solitour/information/controller/InformationController.java b/src/main/java/solitour_backend/solitour/information/controller/InformationController.java index a86085cc..50b69069 100644 --- a/src/main/java/solitour_backend/solitour/information/controller/InformationController.java +++ b/src/main/java/solitour_backend/solitour/information/controller/InformationController.java @@ -3,10 +3,8 @@ import jakarta.servlet.http.HttpServletRequest; import jakarta.validation.Valid; - import java.util.List; import java.util.Objects; - import lombok.RequiredArgsConstructor; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; @@ -14,7 +12,16 @@ import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.validation.BindingResult; -import org.springframework.web.bind.annotation.*; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.ModelAttribute; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RequestPart; +import org.springframework.web.bind.annotation.RestController; import org.springframework.web.multipart.MultipartFile; import solitour_backend.solitour.auth.config.Authenticated; import solitour_backend.solitour.auth.support.CookieExtractor; @@ -96,16 +103,18 @@ public ResponseEntity deleteInformation(@PathVariable Long informationId) } @GetMapping - public ResponseEntity> pageInformationSortAndFilter(@RequestParam(defaultValue = "0") int page, - @RequestParam(defaultValue = "1") Long parentCategoryId, - @Valid @ModelAttribute InformationPageRequest informationPageRequest, - BindingResult bindingResult, - HttpServletRequest request) { + public ResponseEntity> pageInformationSortAndFilter( + @RequestParam(defaultValue = "0") int page, + @RequestParam(defaultValue = "1") Long parentCategoryId, + @Valid @ModelAttribute InformationPageRequest informationPageRequest, + BindingResult bindingResult, + HttpServletRequest request) { Utils.validationRequest(bindingResult); Long userId = findUser(request); Pageable pageable = PageRequest.of(page, PAGE_SIZE); - Page pageInformation = informationService.getPageInformation(pageable, userId, parentCategoryId, informationPageRequest); + Page pageInformation = informationService.getPageInformation(pageable, userId, + parentCategoryId, informationPageRequest); return ResponseEntity .status(HttpStatus.OK) diff --git a/src/main/java/solitour_backend/solitour/information/repository/InformationRepositoryCustom.java b/src/main/java/solitour_backend/solitour/information/repository/InformationRepositoryCustom.java index 8244fc04..84d6bde0 100644 --- a/src/main/java/solitour_backend/solitour/information/repository/InformationRepositoryCustom.java +++ b/src/main/java/solitour_backend/solitour/information/repository/InformationRepositoryCustom.java @@ -1,7 +1,6 @@ package solitour_backend.solitour.information.repository; import java.util.List; - import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.repository.NoRepositoryBean; @@ -16,7 +15,9 @@ public interface InformationRepositoryCustom { String LIKE_COUNT_SORT = "likes"; String VIEW_COUNT_SORT = "views"; - Page getInformationPageFilterAndOrder(Pageable pageable, InformationPageRequest informationPageRequest, Long userId, Long parentCategoryId); + Page getInformationPageFilterAndOrder(Pageable pageable, + InformationPageRequest informationPageRequest, + Long userId, Long parentCategoryId); List getInformationRank(); diff --git a/src/main/java/solitour_backend/solitour/information/repository/InformationRepositoryImpl.java b/src/main/java/solitour_backend/solitour/information/repository/InformationRepositoryImpl.java index f6f9cdcf..ae94cfa0 100644 --- a/src/main/java/solitour_backend/solitour/information/repository/InformationRepositoryImpl.java +++ b/src/main/java/solitour_backend/solitour/information/repository/InformationRepositoryImpl.java @@ -9,11 +9,9 @@ import com.querydsl.core.types.dsl.NumberExpression; import com.querydsl.jpa.JPAExpressions; import com.querydsl.jpa.JPQLQuery; - import java.time.LocalDateTime; import java.util.List; import java.util.Objects; - import org.springframework.data.domain.Page; import org.springframework.data.domain.PageImpl; import org.springframework.data.domain.Pageable; @@ -47,16 +45,18 @@ public InformationRepositoryImpl() { @Override - public Page getInformationPageFilterAndOrder(Pageable pageable, InformationPageRequest informationPageRequest, Long userId, Long parentCategoryId) { + public Page getInformationPageFilterAndOrder(Pageable pageable, + InformationPageRequest informationPageRequest, + Long userId, Long parentCategoryId) { BooleanBuilder whereClause = new BooleanBuilder(); if (Objects.nonNull(informationPageRequest.getZoneCategoryId())) { - whereClause.and(information.zoneCategory.parentZoneCategory.id.eq(informationPageRequest.getZoneCategoryId())); + whereClause.and( + information.zoneCategory.parentZoneCategory.id.eq(informationPageRequest.getZoneCategoryId())); } BooleanBuilder categoryCondition = new BooleanBuilder(); - if (Objects.nonNull(informationPageRequest.getChildCategoryId())) { whereClause.and(information.category.id.eq(informationPageRequest.getChildCategoryId())); } else { diff --git a/src/main/java/solitour_backend/solitour/information/service/InformationService.java b/src/main/java/solitour_backend/solitour/information/service/InformationService.java index cc9e5724..76d291c1 100644 --- a/src/main/java/solitour_backend/solitour/information/service/InformationService.java +++ b/src/main/java/solitour_backend/solitour/information/service/InformationService.java @@ -1,11 +1,13 @@ package solitour_backend.solitour.information.service; +import static solitour_backend.solitour.information.repository.InformationRepositoryCustom.LIKE_COUNT_SORT; +import static solitour_backend.solitour.information.repository.InformationRepositoryCustom.VIEW_COUNT_SORT; + import java.time.LocalDate; import java.time.LocalDateTime; import java.util.ArrayList; import java.util.List; import java.util.Objects; - import lombok.RequiredArgsConstructor; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; @@ -62,9 +64,6 @@ import solitour_backend.solitour.zone_category.exception.ZoneCategoryNotExistsException; import solitour_backend.solitour.zone_category.repository.ZoneCategoryRepository; -import static solitour_backend.solitour.information.repository.InformationRepositoryCustom.LIKE_COUNT_SORT; -import static solitour_backend.solitour.information.repository.InformationRepositoryCustom.VIEW_COUNT_SORT; - @Service @Transactional(readOnly = true) @RequiredArgsConstructor @@ -337,12 +336,12 @@ public void deleteInformation(Long id) { } - public Page getPageInformation(Pageable pageable, Long userId, Long parentCategoryId, InformationPageRequest informationPageRequest) { + public Page getPageInformation(Pageable pageable, Long userId, Long parentCategoryId, + InformationPageRequest informationPageRequest) { if (!categoryRepository.existsByIdAndParentCategoryId(parentCategoryId, null)) { throw new CategoryNotExistsException("해당하는 id의 부모 category 는 없습니다"); } - if (Objects.nonNull(informationPageRequest.getChildCategoryId())) { Category category = categoryRepository.findById(informationPageRequest.getChildCategoryId()) .orElseThrow( @@ -360,12 +359,14 @@ public Page getPageInformation(Pageable pageable, Long } if (Objects.nonNull(informationPageRequest.getSort())) { - if (!Objects.equals(LIKE_COUNT_SORT, informationPageRequest.getSort()) || !Objects.equals(VIEW_COUNT_SORT, informationPageRequest.getSort())) { + if (!Objects.equals(LIKE_COUNT_SORT, informationPageRequest.getSort()) || !Objects.equals(VIEW_COUNT_SORT, + informationPageRequest.getSort())) { throw new RequestValidationFailedException("잘못된 정렬 코드입니다."); } } - return informationRepository.getInformationPageFilterAndOrder(pageable, informationPageRequest, userId, parentCategoryId); + return informationRepository.getInformationPageFilterAndOrder(pageable, informationPageRequest, userId, + parentCategoryId); } public List getRankInformation() { From 84429ae2b428a464e8316de06b1b4c1d081e8df2 Mon Sep 17 00:00:00 2001 From: Donghun Won Date: Sun, 25 Aug 2024 17:27:57 +0900 Subject: [PATCH 155/371] =?UTF-8?q?Feat(#95)=20:=20=EC=A0=95=EB=B3=B4=20?= =?UTF-8?q?=EC=A2=8B=EC=95=84=EC=9A=94=20(#107)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Style : 코드 import 포맷팅 * Feat : 정보 좋아요 기능 좋아요 개수 조회 좋아요 좋아요 취소 * Style : 코드 포맷핑 * Feat : 정보 좋아요 삭제 시 요청 parameter수정 --- .../controller/GreatInformationController.java | 11 ++++++----- .../repository/GreatInformationRepository.java | 2 +- .../service/GreatInformationService.java | 6 +++--- .../place/dto/request/PlaceModifyRequest.java | 1 - 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/main/java/solitour_backend/solitour/great_information/controller/GreatInformationController.java b/src/main/java/solitour_backend/solitour/great_information/controller/GreatInformationController.java index 2a48e312..c9ca8d7e 100644 --- a/src/main/java/solitour_backend/solitour/great_information/controller/GreatInformationController.java +++ b/src/main/java/solitour_backend/solitour/great_information/controller/GreatInformationController.java @@ -10,6 +10,7 @@ import org.springframework.web.bind.annotation.RestController; import solitour_backend.solitour.auth.config.AuthenticationPrincipal; import solitour_backend.solitour.great_information.dto.response.GreatInformationResponse; +import solitour_backend.solitour.great_information.entity.GreatInformation; import solitour_backend.solitour.great_information.service.GreatInformationService; @RestController @@ -27,17 +28,17 @@ public ResponseEntity getInformationGreatCount(@Authen } @PostMapping() - public ResponseEntity createInformationGreat(@AuthenticationPrincipal Long userId, + public ResponseEntity createInformationGreat(@AuthenticationPrincipal Long userId, @RequestParam Long infoId) { - service.createInformationGreat(userId, infoId); + GreatInformation greatInformation = service.createInformationGreat(userId, infoId); - return ResponseEntity.ok().build(); + return ResponseEntity.ok(greatInformation.getId()); } @DeleteMapping() public ResponseEntity deleteInformationGreat(@AuthenticationPrincipal Long userId, - @RequestParam Long greatId) { - service.deleteInformationGreat(userId, greatId); + @RequestParam Long infoId) { + service.deleteInformationGreat(userId, infoId); return ResponseEntity.ok().build(); } diff --git a/src/main/java/solitour_backend/solitour/great_information/repository/GreatInformationRepository.java b/src/main/java/solitour_backend/solitour/great_information/repository/GreatInformationRepository.java index 60d6448c..9ab26b4e 100644 --- a/src/main/java/solitour_backend/solitour/great_information/repository/GreatInformationRepository.java +++ b/src/main/java/solitour_backend/solitour/great_information/repository/GreatInformationRepository.java @@ -10,7 +10,7 @@ public interface GreatInformationRepository extends JpaRepository findByIdAndUserId(Long greatInformationId, Long userId); + Optional findByInformationIdAndUserId(Long informationId, Long userId); void deleteAllByInformationId(Long informationId); } diff --git a/src/main/java/solitour_backend/solitour/great_information/service/GreatInformationService.java b/src/main/java/solitour_backend/solitour/great_information/service/GreatInformationService.java index 28db2eb9..75c0d826 100644 --- a/src/main/java/solitour_backend/solitour/great_information/service/GreatInformationService.java +++ b/src/main/java/solitour_backend/solitour/great_information/service/GreatInformationService.java @@ -33,14 +33,14 @@ public GreatInformation createInformationGreat(Long userId, Long infoId) { Information information = informationRepository.findById(infoId) .orElseThrow(() -> new IllegalArgumentException("해당 정보가 없습니다.")); - return greatInformationRepository.findByIdAndUserId(infoId, userId) + return greatInformationRepository.findByInformationIdAndUserId(infoId, userId) .orElseGet( () -> greatInformationRepository.save(new GreatInformation(user, information))); } @Transactional - public void deleteInformationGreat(Long userId, Long bookMarkId) { - GreatInformation greatInformation = greatInformationRepository.findByIdAndUserId(bookMarkId, + public void deleteInformationGreat(Long userId, Long infoId) { + GreatInformation greatInformation = greatInformationRepository.findByInformationIdAndUserId(infoId, userId) .orElseThrow(() -> new EntityNotFoundException("해당 정보에는 좋아요를 하지 않았습니다")); diff --git a/src/main/java/solitour_backend/solitour/place/dto/request/PlaceModifyRequest.java b/src/main/java/solitour_backend/solitour/place/dto/request/PlaceModifyRequest.java index 36c02f37..ebf8f9bf 100644 --- a/src/main/java/solitour_backend/solitour/place/dto/request/PlaceModifyRequest.java +++ b/src/main/java/solitour_backend/solitour/place/dto/request/PlaceModifyRequest.java @@ -5,7 +5,6 @@ import jakarta.annotation.Nullable; import jakarta.validation.constraints.Digits; import jakarta.validation.constraints.NotBlank; -import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.Size; import java.math.BigDecimal; import lombok.Getter; From a237f282fd132d3f3ea41a26a5f9fd19bac2ac9c Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Mon, 26 Aug 2024 15:29:06 +0900 Subject: [PATCH 156/371] =?UTF-8?q?fix:=20@NotNull=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../solitour/place/dto/request/PlaceModifyRequest.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/solitour_backend/solitour/place/dto/request/PlaceModifyRequest.java b/src/main/java/solitour_backend/solitour/place/dto/request/PlaceModifyRequest.java index ebf8f9bf..36c02f37 100644 --- a/src/main/java/solitour_backend/solitour/place/dto/request/PlaceModifyRequest.java +++ b/src/main/java/solitour_backend/solitour/place/dto/request/PlaceModifyRequest.java @@ -5,6 +5,7 @@ import jakarta.annotation.Nullable; import jakarta.validation.constraints.Digits; import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.Size; import java.math.BigDecimal; import lombok.Getter; From 341cf6cc6142a36fafd81a07f8fc44e8025c1b52 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Mon, 26 Aug 2024 15:29:30 +0900 Subject: [PATCH 157/371] =?UTF-8?q?fix:=20repository=20->=20JpaRepository?= =?UTF-8?q?=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../solitour/user_image/entity/UserImageRepository.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/solitour_backend/solitour/user_image/entity/UserImageRepository.java b/src/main/java/solitour_backend/solitour/user_image/entity/UserImageRepository.java index a05bb1fd..a15bee77 100644 --- a/src/main/java/solitour_backend/solitour/user_image/entity/UserImageRepository.java +++ b/src/main/java/solitour_backend/solitour/user_image/entity/UserImageRepository.java @@ -1,8 +1,8 @@ package solitour_backend.solitour.user_image.entity; -import org.springframework.data.repository.Repository; +import org.springframework.data.jpa.repository.JpaRepository; -public interface UserImageRepository extends Repository { +public interface UserImageRepository extends JpaRepository { UserImage save(UserImage userImage); From 7ec5d69e5e08889d2297d82d92f4b0b6372d676d Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Mon, 26 Aug 2024 15:29:52 +0900 Subject: [PATCH 158/371] =?UTF-8?q?feat:=20isDeleted=20=ED=95=84=EB=93=9C?= =?UTF-8?q?=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../book_mark_information/entity/BookMarkInformation.java | 3 +++ .../solitour/great_information/entity/GreatInformation.java | 3 +++ 2 files changed, 6 insertions(+) diff --git a/src/main/java/solitour_backend/solitour/book_mark_information/entity/BookMarkInformation.java b/src/main/java/solitour_backend/solitour/book_mark_information/entity/BookMarkInformation.java index 47eb51be..f038cdde 100644 --- a/src/main/java/solitour_backend/solitour/book_mark_information/entity/BookMarkInformation.java +++ b/src/main/java/solitour_backend/solitour/book_mark_information/entity/BookMarkInformation.java @@ -33,6 +33,9 @@ public class BookMarkInformation { @JoinColumn(name = "information_id") private Information information; + @Column(name = "is_deleted") + private Boolean isDeleted; + public BookMarkInformation(User user, Information information) { this.user = user; this.information = information; diff --git a/src/main/java/solitour_backend/solitour/great_information/entity/GreatInformation.java b/src/main/java/solitour_backend/solitour/great_information/entity/GreatInformation.java index 4aa9407c..c3a3a35f 100644 --- a/src/main/java/solitour_backend/solitour/great_information/entity/GreatInformation.java +++ b/src/main/java/solitour_backend/solitour/great_information/entity/GreatInformation.java @@ -33,6 +33,9 @@ public class GreatInformation { @JoinColumn(name = "information_id") private Information information; + @Column(name = "is_deleted") + private Boolean isDeleted; + public GreatInformation(User user, Information information) { this.user = user; this.information = information; From d6a2ef82b3106c075284c48cf78b9ad4d2bb55a8 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Mon, 26 Aug 2024 15:33:54 +0900 Subject: [PATCH 159/371] =?UTF-8?q?feat:=20=EC=A0=95=EB=B3=B4=20=EC=83=81?= =?UTF-8?q?=EC=84=B8=20response=20dto=20=ED=95=84=EB=93=9C=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../information/dto/response/InformationDetailResponse.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/solitour_backend/solitour/information/dto/response/InformationDetailResponse.java b/src/main/java/solitour_backend/solitour/information/dto/response/InformationDetailResponse.java index 574c7e84..2c8a3337 100644 --- a/src/main/java/solitour_backend/solitour/information/dto/response/InformationDetailResponse.java +++ b/src/main/java/solitour_backend/solitour/information/dto/response/InformationDetailResponse.java @@ -29,6 +29,7 @@ public class InformationDetailResponse { private List imageResponses; private int likeCount; - + private String userImage; + private Boolean isLike; private List recommendInformation; } From 029a713320c1f5b9d1297f1a2f8d5a04eaa23612 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Mon, 26 Aug 2024 15:34:08 +0900 Subject: [PATCH 160/371] =?UTF-8?q?feat:=20=EC=A0=95=EB=B3=B4=20=EB=A9=94?= =?UTF-8?q?=EC=9D=B8=20=EC=9D=91=EB=8B=B5=20response=20=ED=95=84=EB=93=9C?= =?UTF-8?q?=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../information/dto/response/InformationMainResponse.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/solitour_backend/solitour/information/dto/response/InformationMainResponse.java b/src/main/java/solitour_backend/solitour/information/dto/response/InformationMainResponse.java index 4c870d9f..e94c5357 100644 --- a/src/main/java/solitour_backend/solitour/information/dto/response/InformationMainResponse.java +++ b/src/main/java/solitour_backend/solitour/information/dto/response/InformationMainResponse.java @@ -15,4 +15,5 @@ public class InformationMainResponse { private Boolean isBookMark; private String thumbNailImage; private Integer likeCount; + private Boolean isLike; } From 944549866e2928a0c26ce3fb554a3280cda1bb93 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Mon, 26 Aug 2024 15:34:40 +0900 Subject: [PATCH 161/371] =?UTF-8?q?feat:=20=EB=B6=81=EB=A7=88=ED=81=AC?= =?UTF-8?q?=EC=99=80=20=EC=A2=8B=EC=95=84=EC=9A=94=20=EC=82=AD=EC=A0=9C?= =?UTF-8?q?=EB=90=98=EC=A7=80=20=EC=95=8A=EC=9D=80=20=EA=B2=83=20where=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../repository/InformationRepositoryImpl.java | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/src/main/java/solitour_backend/solitour/information/repository/InformationRepositoryImpl.java b/src/main/java/solitour_backend/solitour/information/repository/InformationRepositoryImpl.java index ae94cfa0..7d7cada8 100644 --- a/src/main/java/solitour_backend/solitour/information/repository/InformationRepositoryImpl.java +++ b/src/main/java/solitour_backend/solitour/information/repository/InformationRepositoryImpl.java @@ -70,7 +70,7 @@ public Page getInformationPageFilterAndOrder(Pageable .join(zoneCategoryChild).on(zoneCategoryChild.id.eq(information.zoneCategory.id)) .leftJoin(zoneCategoryParent).on(zoneCategoryParent.id.eq(zoneCategoryChild.parentZoneCategory.id)) .leftJoin(bookMarkInformation) - .on(bookMarkInformation.information.id.eq(information.id).and(bookMarkInformation.user.id.eq(userId))) + .on(bookMarkInformation.information.id.eq(information.id).and(bookMarkInformation.user.id.eq(userId).and(bookMarkInformation.isDeleted.isFalse()))) .leftJoin(image).on(image.information.id.eq(information.id) .and(image.imageStatus.eq(ImageStatus.THUMBNAIL))) .join(category).on(category.id.eq(information.category.id) @@ -82,7 +82,7 @@ public Page getInformationPageFilterAndOrder(Pageable .join(zoneCategoryChild).on(zoneCategoryChild.id.eq(information.zoneCategory.id)) .leftJoin(zoneCategoryParent).on(zoneCategoryParent.id.eq(zoneCategoryChild.parentZoneCategory.id)) .leftJoin(bookMarkInformation) - .on(bookMarkInformation.information.id.eq(information.id).and(bookMarkInformation.user.id.eq(userId))) + .on(bookMarkInformation.information.id.eq(information.id).and(bookMarkInformation.user.id.eq(userId).and(bookMarkInformation.isDeleted.isFalse()))) .leftJoin(image).on(image.information.id.eq(information.id) .and(image.imageStatus.eq(ImageStatus.THUMBNAIL))) .join(category).on(category.id.eq(information.category.id) @@ -116,7 +116,7 @@ public List getInformationLikeCountFromCreatedIn3(Long .leftJoin(zoneCategoryChild).on(zoneCategoryChild.id.eq(information.zoneCategory.id)) .leftJoin(zoneCategoryParent).on(zoneCategoryParent.id.eq(zoneCategoryChild.parentZoneCategory.id)) .leftJoin(bookMarkInformation) - .on(bookMarkInformation.information.id.eq(information.id).and(bookMarkInformation.user.id.eq(userId))) + .on(bookMarkInformation.information.id.eq(information.id).and(bookMarkInformation.user.id.eq(userId).and(bookMarkInformation.isDeleted.isFalse()))) .leftJoin(image) .on(image.information.id.eq(information.id).and(image.imageStatus.eq(ImageStatus.THUMBNAIL))) .leftJoin(greatInformation).on(greatInformation.information.id.eq(information.id)) @@ -148,7 +148,7 @@ public List getInformationRecommend(Long informationId .join(zoneCategoryChild).on(zoneCategoryChild.id.eq(information.zoneCategory.id)) .leftJoin(zoneCategoryParent).on(zoneCategoryParent.id.eq(zoneCategoryChild.parentZoneCategory.id)) .leftJoin(bookMarkInformation) - .on(bookMarkInformation.information.id.eq(information.id).and(bookMarkInformation.user.id.eq(userId))) + .on(bookMarkInformation.information.id.eq(information.id).and(bookMarkInformation.user.id.eq(userId).and(bookMarkInformation.isDeleted.isFalse()))) .leftJoin(image).on(image.information.id.eq(information.id) .and(image.imageStatus.eq(ImageStatus.THUMBNAIL))) .leftJoin(greatInformation).on(greatInformation.information.id.eq(information.id)) @@ -199,9 +199,11 @@ private OrderSpecifier getOrderSpecifier(String sort) { private NumberExpression countGreatInformationByInformationById() { QGreatInformation greatInformationSub = QGreatInformation.greatInformation; - JPQLQuery likeCountSubQuery = JPAExpressions.select(greatInformationSub.count()) + JPQLQuery likeCountSubQuery = JPAExpressions + .select(greatInformationSub.count()) .from(greatInformationSub) - .where(greatInformationSub.information.id.eq(information.id)); + .where(greatInformationSub.information.id.eq(information.id) + .and(greatInformationSub.isDeleted.isFalse())); return Expressions.numberTemplate(Long.class, "{0}", likeCountSubQuery).coalesce(0L).intValue(); } @@ -211,7 +213,8 @@ private BooleanExpression isUserGreatInformation(Long userId) { .when(JPAExpressions.selectOne() .from(greatInformation) .where(greatInformation.information.id.eq(information.id) - .and(greatInformation.information.id.eq(userId))) + .and(greatInformation.information.id.eq(userId)) + .and(greatInformation.isDeleted.isFalse())) .exists()) .then(true) .otherwise(false); From 1c57c6d53db74796ecea3703fc6d7e4568d35532 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Mon, 26 Aug 2024 15:35:05 +0900 Subject: [PATCH 162/371] =?UTF-8?q?feat:=20=EC=A0=95=EB=B3=B4=20=EC=83=81?= =?UTF-8?q?=EC=84=B8=20=EC=A1=B0=ED=9A=8C=20service=20dto=20=ED=95=84?= =?UTF-8?q?=EB=93=9C=20=EC=88=98=EC=A0=95=EC=9C=BC=EB=A1=9C=20=EC=9D=B8?= =?UTF-8?q?=ED=95=B4=20=EC=B6=94=EA=B0=80=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../solitour/information/service/InformationService.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/main/java/solitour_backend/solitour/information/service/InformationService.java b/src/main/java/solitour_backend/solitour/information/service/InformationService.java index 76d291c1..772e5994 100644 --- a/src/main/java/solitour_backend/solitour/information/service/InformationService.java +++ b/src/main/java/solitour_backend/solitour/information/service/InformationService.java @@ -58,6 +58,8 @@ import solitour_backend.solitour.user.entity.User; import solitour_backend.solitour.user.entity.UserRepository; import solitour_backend.solitour.user.exception.UserNotExistsException; +import solitour_backend.solitour.user_image.entity.UserImage; +import solitour_backend.solitour.user_image.entity.UserImageRepository; import solitour_backend.solitour.zone_category.dto.mapper.ZoneCategoryMapper; import solitour_backend.solitour.zone_category.dto.response.ZoneCategoryResponse; import solitour_backend.solitour.zone_category.entity.ZoneCategory; @@ -85,6 +87,7 @@ public class InformationService { private final UserMapper userMapper; private final GreatInformationRepository greatInformationRepository; private final BookMarkInformationRepository bookMarkInformationRepository; + private final UserImageRepository userImageRepository; public static final String IMAGE_PATH = "information"; private final ImageRepository imageRepository; @@ -183,6 +186,9 @@ public InformationDetailResponse getDetailInformation(Long userId, Long informat List informationRecommend = informationRepository.getInformationRecommend( information.getId(), information.getCategory().getId(), userId); + boolean isLike = greatInformationRepository.existsByInformationIdAndUserIdAndIsDeletedFalse(information.getId(), userId); + UserImage userImage = userImageRepository.findById(userId).orElseThrow(); + return new InformationDetailResponse( information.getTitle(), @@ -197,6 +203,8 @@ public InformationDetailResponse getDetailInformation(Long userId, Long informat zoneCategoryResponse, imageResponseList, likeCount, + userImage.getAddress(), + isLike, informationRecommend); } From 0c7478dbdc2346ad96f16d0a097444042eafad9b Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Mon, 26 Aug 2024 15:35:28 +0900 Subject: [PATCH 163/371] =?UTF-8?q?feat:=20=EC=A2=8B=EC=95=84=EC=9A=94=20?= =?UTF-8?q?=EC=A0=95=EB=B3=B4=20id,=20=EC=9C=A0=EC=A0=80=20id,=20=EC=82=AD?= =?UTF-8?q?=EC=A0=9C=20=EB=90=98=EC=A7=80=20=EC=95=8A=EC=9D=80=EA=B2=83=20?= =?UTF-8?q?=EC=9E=88=EB=8A=94=EC=A7=80=20=ED=99=95=EC=9D=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../repository/GreatInformationRepository.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main/java/solitour_backend/solitour/great_information/repository/GreatInformationRepository.java b/src/main/java/solitour_backend/solitour/great_information/repository/GreatInformationRepository.java index 9ab26b4e..ef70f695 100644 --- a/src/main/java/solitour_backend/solitour/great_information/repository/GreatInformationRepository.java +++ b/src/main/java/solitour_backend/solitour/great_information/repository/GreatInformationRepository.java @@ -1,6 +1,7 @@ package solitour_backend.solitour.great_information.repository; import java.util.Optional; + import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; import solitour_backend.solitour.great_information.entity.GreatInformation; @@ -13,4 +14,6 @@ public interface GreatInformationRepository extends JpaRepository findByInformationIdAndUserId(Long informationId, Long userId); void deleteAllByInformationId(Long informationId); + + boolean existsByInformationIdAndUserIdAndIsDeletedFalse(Long informationId, Long userId); } From 3e6912c51fde194e70f61703bcfa0c873a0a7b36 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Mon, 26 Aug 2024 15:35:44 +0900 Subject: [PATCH 164/371] =?UTF-8?q?feat:=20=EB=B6=81=EB=A7=88=ED=81=AC=20?= =?UTF-8?q?=EC=A2=8B=EC=95=84=EC=9A=94=20=EC=82=AD=EC=A0=9C=20=EB=90=98?= =?UTF-8?q?=EC=A7=80=20=EC=95=8A=EC=9D=80=20=EA=B2=83=20where=20=EC=A0=88?= =?UTF-8?q?=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../gathering/repository/GatheringRepositoryImpl.java | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryImpl.java b/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryImpl.java index 503cdc72..412c3a79 100644 --- a/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryImpl.java +++ b/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryImpl.java @@ -53,7 +53,7 @@ public List getGatheringRecommend(Long gatheringId, Long .join(zoneCategoryChild).on(zoneCategoryChild.id.eq(gathering.zoneCategory.id)) .leftJoin(zoneCategoryParent).on(zoneCategoryParent.id.eq(zoneCategoryChild.parentZoneCategory.id)) .leftJoin(bookMarkGathering) - .on(bookMarkGathering.gathering.id.eq(gathering.id).and(bookMarkGathering.user.id.eq(userId))) + .on(bookMarkGathering.gathering.id.eq(gathering.id).and(bookMarkGathering.user.id.eq(userId)).and(bookMarkGathering.isDeleted.isFalse())) .leftJoin(category).on(category.id.eq(gathering.gatheringCategory.id)) .leftJoin(gatheringApplicants).on(gatheringApplicants.gathering.id.eq(gathering.id)) .where(gathering.isFinish.eq(Boolean.FALSE) @@ -116,7 +116,7 @@ public Page getGatheringPageFilterAndOrder(Pageable page .join(zoneCategoryChild).on(zoneCategoryChild.id.eq(gathering.zoneCategory.id)) .leftJoin(zoneCategoryParent).on(zoneCategoryParent.id.eq(zoneCategoryChild.parentZoneCategory.id)) .leftJoin(bookMarkGathering) - .on(bookMarkGathering.gathering.id.eq(gathering.id).and(bookMarkGathering.user.id.eq(userId))) + .on(bookMarkGathering.gathering.id.eq(gathering.id).and(bookMarkGathering.user.id.eq(userId)).and(bookMarkGathering.isDeleted.isFalse())) .leftJoin(gatheringApplicants).on(gatheringApplicants.gathering.id.eq(gathering.id)) .where(booleanBuilder) .groupBy(gathering.id, zoneCategoryChild.id, zoneCategoryParent.id, category.id, @@ -176,7 +176,7 @@ public List getGatheringLikeCountFromCreatedIn3(Long use .join(zoneCategoryChild).on(zoneCategoryChild.id.eq(gathering.zoneCategory.id)) .leftJoin(zoneCategoryParent).on(zoneCategoryParent.id.eq(zoneCategoryChild.parentZoneCategory.id)) .leftJoin(bookMarkGathering) - .on(bookMarkGathering.gathering.id.eq(gathering.id).and(bookMarkGathering.user.id.eq(userId))) + .on(bookMarkGathering.gathering.id.eq(gathering.id).and(bookMarkGathering.user.id.eq(userId)).and(bookMarkGathering.isDeleted.isFalse())) .leftJoin(category).on(category.id.eq(gathering.gatheringCategory.id)) .leftJoin(gatheringApplicants).on(gatheringApplicants.gathering.id.eq(gathering.id)) .where(gathering.isFinish.eq(Boolean.FALSE) @@ -289,7 +289,8 @@ private BooleanExpression isUserGreatGathering(Long userId) { .when(JPAExpressions.selectOne() .from(greatGathering) .where(greatGathering.gathering.id.eq(gathering.id) - .and(greatGathering.user.id.eq(userId))) + .and(greatGathering.user.id.eq(userId)) + .and(greatGathering.isDeleted.isFalse())) .exists()) .then(true) .otherwise(false); From 5672b8bc05a38392cf81778a9f0f9e31d258686c Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Wed, 28 Aug 2024 00:05:02 +0900 Subject: [PATCH 165/371] =?UTF-8?q?feat:=20isDeleted=20=ED=95=84=EB=93=9C?= =?UTF-8?q?=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../solitour/book_mark_gathering/entity/BookMarkGathering.java | 2 -- .../book_mark_information/entity/BookMarkInformation.java | 3 --- .../solitour/great_gathering/entity/GreatGathering.java | 3 --- .../solitour/great_information/entity/GreatInformation.java | 3 --- 4 files changed, 11 deletions(-) diff --git a/src/main/java/solitour_backend/solitour/book_mark_gathering/entity/BookMarkGathering.java b/src/main/java/solitour_backend/solitour/book_mark_gathering/entity/BookMarkGathering.java index 8cac38be..549b32d4 100644 --- a/src/main/java/solitour_backend/solitour/book_mark_gathering/entity/BookMarkGathering.java +++ b/src/main/java/solitour_backend/solitour/book_mark_gathering/entity/BookMarkGathering.java @@ -34,6 +34,4 @@ public class BookMarkGathering { @JoinColumn(name = "gathering_id") private Gathering gathering; - @Column(name = "is_deleted") - private Boolean isDeleted; } diff --git a/src/main/java/solitour_backend/solitour/book_mark_information/entity/BookMarkInformation.java b/src/main/java/solitour_backend/solitour/book_mark_information/entity/BookMarkInformation.java index f038cdde..47eb51be 100644 --- a/src/main/java/solitour_backend/solitour/book_mark_information/entity/BookMarkInformation.java +++ b/src/main/java/solitour_backend/solitour/book_mark_information/entity/BookMarkInformation.java @@ -33,9 +33,6 @@ public class BookMarkInformation { @JoinColumn(name = "information_id") private Information information; - @Column(name = "is_deleted") - private Boolean isDeleted; - public BookMarkInformation(User user, Information information) { this.user = user; this.information = information; diff --git a/src/main/java/solitour_backend/solitour/great_gathering/entity/GreatGathering.java b/src/main/java/solitour_backend/solitour/great_gathering/entity/GreatGathering.java index 31ce2ee1..7ed4a264 100644 --- a/src/main/java/solitour_backend/solitour/great_gathering/entity/GreatGathering.java +++ b/src/main/java/solitour_backend/solitour/great_gathering/entity/GreatGathering.java @@ -35,7 +35,4 @@ public class GreatGathering { @JoinColumn(name = "gathering_id") private Gathering gathering; - @Column(name = "is_deleted") - private Boolean isDeleted; - } diff --git a/src/main/java/solitour_backend/solitour/great_information/entity/GreatInformation.java b/src/main/java/solitour_backend/solitour/great_information/entity/GreatInformation.java index c3a3a35f..4aa9407c 100644 --- a/src/main/java/solitour_backend/solitour/great_information/entity/GreatInformation.java +++ b/src/main/java/solitour_backend/solitour/great_information/entity/GreatInformation.java @@ -33,9 +33,6 @@ public class GreatInformation { @JoinColumn(name = "information_id") private Information information; - @Column(name = "is_deleted") - private Boolean isDeleted; - public GreatInformation(User user, Information information) { this.user = user; this.information = information; From 77ed979ad9b08a269ac33688132871087af05418 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Wed, 28 Aug 2024 00:05:58 +0900 Subject: [PATCH 166/371] =?UTF-8?q?feat:=20gathering=20default=20false=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80=EB=A1=9C=20=EC=9D=B8=ED=95=9C=20=EC=BD=94?= =?UTF-8?q?=EB=93=9C=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../solitour_backend/solitour/gathering/entity/Gathering.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/solitour_backend/solitour/gathering/entity/Gathering.java b/src/main/java/solitour_backend/solitour/gathering/entity/Gathering.java index bdd802ff..39df37f1 100644 --- a/src/main/java/solitour_backend/solitour/gathering/entity/Gathering.java +++ b/src/main/java/solitour_backend/solitour/gathering/entity/Gathering.java @@ -116,6 +116,5 @@ public Gathering(User user, ZoneCategory zoneCategory, GatheringCategory gatheri this.allowedSex = allowedSex; this.startAge = startAge; this.endAge = endAge; - this.isDeleted = false; } } From 57d7a8500d255817414a42fa427a811098484ce9 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Wed, 28 Aug 2024 00:06:31 +0900 Subject: [PATCH 167/371] =?UTF-8?q?feat:=20isApplicants=20=EC=9D=B4=20?= =?UTF-8?q?=EB=AA=A8=EC=9E=84=EC=97=90=20=EC=B0=B8=EC=97=AC=20=EC=8B=A0?= =?UTF-8?q?=EC=B2=AD=EC=9D=84=20=ED=96=88=EB=8A=94=EC=A7=80=20=ED=95=84?= =?UTF-8?q?=EB=93=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../gathering/dto/response/GatheringDetailResponse.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/solitour_backend/solitour/gathering/dto/response/GatheringDetailResponse.java b/src/main/java/solitour_backend/solitour/gathering/dto/response/GatheringDetailResponse.java index f08ffcb3..fb5243d1 100644 --- a/src/main/java/solitour_backend/solitour/gathering/dto/response/GatheringDetailResponse.java +++ b/src/main/java/solitour_backend/solitour/gathering/dto/response/GatheringDetailResponse.java @@ -45,4 +45,6 @@ public class GatheringDetailResponse { private List gatheringApplicantsResponses; private List gatheringRecommend; + + private Boolean isApplicants; } From 0206fb85be41c5537f9242fbf826dfb64549ab53 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Wed, 28 Aug 2024 00:07:44 +0900 Subject: [PATCH 168/371] =?UTF-8?q?feat:=20isDeleted=20=EC=82=AD=EC=A0=9C?= =?UTF-8?q?=EB=A1=9C=20=EC=9D=B8=ED=95=9C=20=EC=BD=94=EB=93=9C=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 --- .../great_gathering/repository/GreatGatheringRepository.java | 2 +- .../repository/GreatInformationRepository.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/solitour_backend/solitour/great_gathering/repository/GreatGatheringRepository.java b/src/main/java/solitour_backend/solitour/great_gathering/repository/GreatGatheringRepository.java index 15f75dd2..c0a81cc3 100644 --- a/src/main/java/solitour_backend/solitour/great_gathering/repository/GreatGatheringRepository.java +++ b/src/main/java/solitour_backend/solitour/great_gathering/repository/GreatGatheringRepository.java @@ -9,5 +9,5 @@ public interface GreatGatheringRepository extends JpaRepository Date: Wed, 28 Aug 2024 00:11:57 +0900 Subject: [PATCH 169/371] =?UTF-8?q?style:=20=EC=BD=94=EB=93=9C=20=EC=8A=A4?= =?UTF-8?q?=ED=83=80=EC=9D=BC=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/InformationController.java | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/main/java/solitour_backend/solitour/information/controller/InformationController.java b/src/main/java/solitour_backend/solitour/information/controller/InformationController.java index 50b69069..d1e8c355 100644 --- a/src/main/java/solitour_backend/solitour/information/controller/InformationController.java +++ b/src/main/java/solitour_backend/solitour/information/controller/InformationController.java @@ -3,8 +3,10 @@ import jakarta.servlet.http.HttpServletRequest; import jakarta.validation.Valid; + import java.util.List; import java.util.Objects; + import lombok.RequiredArgsConstructor; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; @@ -49,11 +51,10 @@ public class InformationController { @PostMapping @Authenticated - public ResponseEntity createInformation( - @Valid @RequestPart("request") InformationRegisterRequest informationRegisterRequest, - @RequestPart("thumbNailImage") MultipartFile thumbnail, - @RequestPart("contentImages") List contentImages, - BindingResult bindingResult) { + public ResponseEntity createInformation(@Valid @RequestPart("request") InformationRegisterRequest informationRegisterRequest, + @RequestPart("thumbNailImage") MultipartFile thumbnail, + @RequestPart("contentImages") List contentImages, + BindingResult bindingResult) { Utils.validationRequest(bindingResult); InformationResponse informationResponse = informationService.registerInformation( informationRegisterRequest, thumbnail, contentImages); @@ -103,12 +104,11 @@ public ResponseEntity deleteInformation(@PathVariable Long informationId) } @GetMapping - public ResponseEntity> pageInformationSortAndFilter( - @RequestParam(defaultValue = "0") int page, - @RequestParam(defaultValue = "1") Long parentCategoryId, - @Valid @ModelAttribute InformationPageRequest informationPageRequest, - BindingResult bindingResult, - HttpServletRequest request) { + public ResponseEntity> pageInformationSortAndFilter(@RequestParam(defaultValue = "0") int page, + @RequestParam(defaultValue = "1") Long parentCategoryId, + @Valid @ModelAttribute InformationPageRequest informationPageRequest, + BindingResult bindingResult, + HttpServletRequest request) { Utils.validationRequest(bindingResult); Long userId = findUser(request); From 6e4272114800ecb8915853eb856abbf9d08931d4 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Wed, 28 Aug 2024 00:12:37 +0900 Subject: [PATCH 170/371] =?UTF-8?q?refactor:=20isDeleted=20=EC=B9=BC?= =?UTF-8?q?=EB=9F=BC=20=EC=82=AD=EC=A0=9C=EB=A1=9C=20=EC=9D=B8=ED=95=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 --- .../repository/GatheringRepositoryImpl.java | 21 ++++++------ .../repository/InformationRepositoryImpl.java | 34 ++++++++----------- 2 files changed, 24 insertions(+), 31 deletions(-) diff --git a/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryImpl.java b/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryImpl.java index 412c3a79..47e4dda8 100644 --- a/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryImpl.java +++ b/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryImpl.java @@ -10,11 +10,13 @@ import com.querydsl.core.types.dsl.PathBuilder; import com.querydsl.jpa.JPAExpressions; import com.querydsl.jpa.JPQLQuery; + import java.time.LocalDate; import java.time.LocalDateTime; import java.time.LocalTime; import java.util.List; import java.util.Objects; + import org.springframework.data.domain.Page; import org.springframework.data.domain.PageImpl; import org.springframework.data.domain.Pageable; @@ -53,15 +55,13 @@ public List getGatheringRecommend(Long gatheringId, Long .join(zoneCategoryChild).on(zoneCategoryChild.id.eq(gathering.zoneCategory.id)) .leftJoin(zoneCategoryParent).on(zoneCategoryParent.id.eq(zoneCategoryChild.parentZoneCategory.id)) .leftJoin(bookMarkGathering) - .on(bookMarkGathering.gathering.id.eq(gathering.id).and(bookMarkGathering.user.id.eq(userId)).and(bookMarkGathering.isDeleted.isFalse())) + .on(bookMarkGathering.gathering.id.eq(gathering.id).and(bookMarkGathering.user.id.eq(userId))) .leftJoin(category).on(category.id.eq(gathering.gatheringCategory.id)) - .leftJoin(gatheringApplicants).on(gatheringApplicants.gathering.id.eq(gathering.id)) + .leftJoin(gatheringApplicants).on(gatheringApplicants.gathering.id.eq(gathering.id).and(gatheringApplicants.gatheringStatus.eq(GatheringStatus.CONSENT))) .where(gathering.isFinish.eq(Boolean.FALSE) .and(gathering.gatheringCategory.id.eq(gatheringCategoryId)) .and(gathering.id.ne(gatheringId)) .and(gathering.isDeleted.eq(Boolean.FALSE)) - .and(gatheringApplicants.gatheringStatus.eq(GatheringStatus.CONSENT) - .or(gatheringApplicants.gatheringStatus.isNull())) ) .groupBy(gathering.id, zoneCategoryChild.id, zoneCategoryParent.id, category.id, gathering.title, gathering.viewCount, gathering.user.name, @@ -116,7 +116,7 @@ public Page getGatheringPageFilterAndOrder(Pageable page .join(zoneCategoryChild).on(zoneCategoryChild.id.eq(gathering.zoneCategory.id)) .leftJoin(zoneCategoryParent).on(zoneCategoryParent.id.eq(zoneCategoryChild.parentZoneCategory.id)) .leftJoin(bookMarkGathering) - .on(bookMarkGathering.gathering.id.eq(gathering.id).and(bookMarkGathering.user.id.eq(userId)).and(bookMarkGathering.isDeleted.isFalse())) + .on(bookMarkGathering.gathering.id.eq(gathering.id).and(bookMarkGathering.user.id.eq(userId))) .leftJoin(gatheringApplicants).on(gatheringApplicants.gathering.id.eq(gathering.id)) .where(booleanBuilder) .groupBy(gathering.id, zoneCategoryChild.id, zoneCategoryParent.id, category.id, @@ -176,9 +176,9 @@ public List getGatheringLikeCountFromCreatedIn3(Long use .join(zoneCategoryChild).on(zoneCategoryChild.id.eq(gathering.zoneCategory.id)) .leftJoin(zoneCategoryParent).on(zoneCategoryParent.id.eq(zoneCategoryChild.parentZoneCategory.id)) .leftJoin(bookMarkGathering) - .on(bookMarkGathering.gathering.id.eq(gathering.id).and(bookMarkGathering.user.id.eq(userId)).and(bookMarkGathering.isDeleted.isFalse())) + .on(bookMarkGathering.gathering.id.eq(gathering.id).and(bookMarkGathering.user.id.eq(userId))) .leftJoin(category).on(category.id.eq(gathering.gatheringCategory.id)) - .leftJoin(gatheringApplicants).on(gatheringApplicants.gathering.id.eq(gathering.id)) + .leftJoin(gatheringApplicants).on(gatheringApplicants.gathering.id.eq(gathering.id).and(gatheringApplicants.gatheringStatus.eq(GatheringStatus.CONSENT))) .where(gathering.isFinish.eq(Boolean.FALSE) .and(gathering.isDeleted.eq(Boolean.FALSE)) .and(gathering.createdAt.after(LocalDateTime.now().minusMonths(3)))) @@ -277,8 +277,8 @@ private NumberExpression countGreatGatheringByGatheringById() { JPQLQuery likeCountSubQuery = JPAExpressions .select(greatGatheringSub.count()) .from(greatGatheringSub) - .where(greatGatheringSub.gathering.id.eq(gathering.id) - .and(greatGatheringSub.isDeleted.isFalse())); + .where(greatGatheringSub.gathering.id.eq(gathering.id)); + return Expressions.numberTemplate(Long.class, "{0}", likeCountSubQuery) .coalesce(0L) .intValue(); @@ -289,8 +289,7 @@ private BooleanExpression isUserGreatGathering(Long userId) { .when(JPAExpressions.selectOne() .from(greatGathering) .where(greatGathering.gathering.id.eq(gathering.id) - .and(greatGathering.user.id.eq(userId)) - .and(greatGathering.isDeleted.isFalse())) + .and(greatGathering.user.id.eq(userId))) .exists()) .then(true) .otherwise(false); diff --git a/src/main/java/solitour_backend/solitour/information/repository/InformationRepositoryImpl.java b/src/main/java/solitour_backend/solitour/information/repository/InformationRepositoryImpl.java index 7d7cada8..af99ec44 100644 --- a/src/main/java/solitour_backend/solitour/information/repository/InformationRepositoryImpl.java +++ b/src/main/java/solitour_backend/solitour/information/repository/InformationRepositoryImpl.java @@ -9,9 +9,11 @@ import com.querydsl.core.types.dsl.NumberExpression; import com.querydsl.jpa.JPAExpressions; import com.querydsl.jpa.JPQLQuery; + import java.time.LocalDateTime; import java.util.List; import java.util.Objects; + import org.springframework.data.domain.Page; import org.springframework.data.domain.PageImpl; import org.springframework.data.domain.Pageable; @@ -51,8 +53,7 @@ public Page getInformationPageFilterAndOrder(Pageable BooleanBuilder whereClause = new BooleanBuilder(); if (Objects.nonNull(informationPageRequest.getZoneCategoryId())) { - whereClause.and( - information.zoneCategory.parentZoneCategory.id.eq(informationPageRequest.getZoneCategoryId())); + whereClause.and(information.zoneCategory.parentZoneCategory.id.eq(informationPageRequest.getZoneCategoryId())); } BooleanBuilder categoryCondition = new BooleanBuilder(); @@ -70,11 +71,9 @@ public Page getInformationPageFilterAndOrder(Pageable .join(zoneCategoryChild).on(zoneCategoryChild.id.eq(information.zoneCategory.id)) .leftJoin(zoneCategoryParent).on(zoneCategoryParent.id.eq(zoneCategoryChild.parentZoneCategory.id)) .leftJoin(bookMarkInformation) - .on(bookMarkInformation.information.id.eq(information.id).and(bookMarkInformation.user.id.eq(userId).and(bookMarkInformation.isDeleted.isFalse()))) - .leftJoin(image).on(image.information.id.eq(information.id) - .and(image.imageStatus.eq(ImageStatus.THUMBNAIL))) - .join(category).on(category.id.eq(information.category.id) - .and(categoryCondition)) + .on(bookMarkInformation.information.id.eq(information.id).and(bookMarkInformation.user.id.eq(userId))) + .leftJoin(image).on(image.information.id.eq(information.id).and(image.imageStatus.eq(ImageStatus.THUMBNAIL))) + .join(category).on(category.id.eq(information.category.id).and(categoryCondition)) .where(whereClause) .select(information.count()).fetchCount(); @@ -82,11 +81,9 @@ public Page getInformationPageFilterAndOrder(Pageable .join(zoneCategoryChild).on(zoneCategoryChild.id.eq(information.zoneCategory.id)) .leftJoin(zoneCategoryParent).on(zoneCategoryParent.id.eq(zoneCategoryChild.parentZoneCategory.id)) .leftJoin(bookMarkInformation) - .on(bookMarkInformation.information.id.eq(information.id).and(bookMarkInformation.user.id.eq(userId).and(bookMarkInformation.isDeleted.isFalse()))) - .leftJoin(image).on(image.information.id.eq(information.id) - .and(image.imageStatus.eq(ImageStatus.THUMBNAIL))) - .join(category).on(category.id.eq(information.category.id) - .and(categoryCondition)) + .on(bookMarkInformation.information.id.eq(information.id).and(bookMarkInformation.user.id.eq(userId))) + .leftJoin(image).on(image.information.id.eq(information.id).and(image.imageStatus.eq(ImageStatus.THUMBNAIL))) + .join(category).on(category.id.eq(information.category.id).and(categoryCondition)) .leftJoin(greatInformation).on(greatInformation.information.id.eq(information.id)) .where(whereClause) .groupBy(information.id, zoneCategoryChild.id, zoneCategoryParent.id, image.id) @@ -116,7 +113,7 @@ public List getInformationLikeCountFromCreatedIn3(Long .leftJoin(zoneCategoryChild).on(zoneCategoryChild.id.eq(information.zoneCategory.id)) .leftJoin(zoneCategoryParent).on(zoneCategoryParent.id.eq(zoneCategoryChild.parentZoneCategory.id)) .leftJoin(bookMarkInformation) - .on(bookMarkInformation.information.id.eq(information.id).and(bookMarkInformation.user.id.eq(userId).and(bookMarkInformation.isDeleted.isFalse()))) + .on(bookMarkInformation.information.id.eq(information.id).and(bookMarkInformation.user.id.eq(userId))) .leftJoin(image) .on(image.information.id.eq(information.id).and(image.imageStatus.eq(ImageStatus.THUMBNAIL))) .leftJoin(greatInformation).on(greatInformation.information.id.eq(information.id)) @@ -142,13 +139,12 @@ public List getInformationLikeCountFromCreatedIn3(Long } @Override - public List getInformationRecommend(Long informationId, Long childCategoryId, - Long userId) { + public List getInformationRecommend(Long informationId, Long childCategoryId, Long userId) { return from(information) .join(zoneCategoryChild).on(zoneCategoryChild.id.eq(information.zoneCategory.id)) .leftJoin(zoneCategoryParent).on(zoneCategoryParent.id.eq(zoneCategoryChild.parentZoneCategory.id)) .leftJoin(bookMarkInformation) - .on(bookMarkInformation.information.id.eq(information.id).and(bookMarkInformation.user.id.eq(userId).and(bookMarkInformation.isDeleted.isFalse()))) + .on(bookMarkInformation.information.id.eq(information.id).and(bookMarkInformation.user.id.eq(userId))) .leftJoin(image).on(image.information.id.eq(information.id) .and(image.imageStatus.eq(ImageStatus.THUMBNAIL))) .leftJoin(greatInformation).on(greatInformation.information.id.eq(information.id)) @@ -202,8 +198,7 @@ private NumberExpression countGreatInformationByInformationById() { JPQLQuery likeCountSubQuery = JPAExpressions .select(greatInformationSub.count()) .from(greatInformationSub) - .where(greatInformationSub.information.id.eq(information.id) - .and(greatInformationSub.isDeleted.isFalse())); + .where(greatInformationSub.information.id.eq(information.id)); return Expressions.numberTemplate(Long.class, "{0}", likeCountSubQuery).coalesce(0L).intValue(); } @@ -213,8 +208,7 @@ private BooleanExpression isUserGreatInformation(Long userId) { .when(JPAExpressions.selectOne() .from(greatInformation) .where(greatInformation.information.id.eq(information.id) - .and(greatInformation.information.id.eq(userId)) - .and(greatInformation.isDeleted.isFalse())) + .and(greatInformation.information.id.eq(userId))) .exists()) .then(true) .otherwise(false); From 9d1a8d4e92d8a951ec89461379c6a4558b492d98 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Wed, 28 Aug 2024 00:14:51 +0900 Subject: [PATCH 171/371] =?UTF-8?q?fix:=20=EB=AA=A8=EC=9E=84=20=EB=93=B1?= =?UTF-8?q?=EB=A1=9D=ED=95=A0=EB=95=8C=20=EB=AA=A8=EC=9E=84=20=EC=9E=91?= =?UTF-8?q?=EC=84=B1=EC=9E=90=EB=8F=84=20=EB=AA=A8=EC=9E=84=20=EC=8B=A0?= =?UTF-8?q?=EC=B2=AD=20save?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../gathering/service/GatheringService.java | 51 ++++++++++--------- 1 file changed, 26 insertions(+), 25 deletions(-) diff --git a/src/main/java/solitour_backend/solitour/gathering/service/GatheringService.java b/src/main/java/solitour_backend/solitour/gathering/service/GatheringService.java index 8844c374..7a7310bd 100644 --- a/src/main/java/solitour_backend/solitour/gathering/service/GatheringService.java +++ b/src/main/java/solitour_backend/solitour/gathering/service/GatheringService.java @@ -6,6 +6,7 @@ import java.util.ArrayList; import java.util.List; import java.util.Objects; + import lombok.RequiredArgsConstructor; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; @@ -87,7 +88,7 @@ public GatheringDetailResponse getGatheringDetail(Long userId, Long gatheringId) .orElseThrow( () -> new GatheringNotExistsException("해당하는 id의 gathering 이 존재 하지 않습니다")); - if (gathering.getIsDeleted()) { + if (Boolean.TRUE.equals(gathering.getIsDeleted())) { throw new GatheringDeleteException("해당하는 모임은 삭제가 되었습니다"); } @@ -105,28 +106,28 @@ public GatheringDetailResponse getGatheringDetail(Long userId, Long gatheringId) } GatheringCategory gatheringCategory = gathering.getGatheringCategory(); - GatheringCategoryResponse gatheringCategoryResponse = gatheringCategoryMapper.mapToCategoryResponse( - gatheringCategory); + GatheringCategoryResponse gatheringCategoryResponse = gatheringCategoryMapper.mapToCategoryResponse(gatheringCategory); PlaceResponse placeResponse = placeMapper.mapToPlaceResponse(gathering.getPlace()); - ZoneCategoryResponse zoneCategoryResponse = zoneCategoryMapper.mapToZoneCategoryResponse( - gathering.getZoneCategory()); + ZoneCategoryResponse zoneCategoryResponse = zoneCategoryMapper.mapToZoneCategoryResponse(gathering.getZoneCategory()); int likeCount = greatGatheringRepository.countByGatheringId(gathering.getId()); - List gatheringApplicantsResponses = gatheringApplicantsMapper.mapToGatheringApplicantsResponses( - gatheringApplicantsRepository.findAllByGathering_IdAndUserIdNot(gathering.getId(), - gathering.getUser().getId())); + List gatheringApplicantsResponses = null; + + boolean isApplicants = gatheringApplicantsRepository.existsByGatheringIdAndUserId(gathering.getId(), userId); + + if (gathering.getUser().getId().equals(userId)) { + gatheringApplicantsResponses = gatheringApplicantsMapper.mapToGatheringApplicantsResponses(gatheringApplicantsRepository.findAllByGathering_IdAndUserIdNot(gathering.getId(), gathering.getUser().getId())); + } int nowPersonCount = gatheringApplicantsRepository.countAllByGathering_IdAndGatheringStatus(gathering.getId(), GatheringStatus.CONSENT); - boolean isLike = greatGatheringRepository.existsByGatheringIdAndUserIdAndIsDeletedFalse(gathering.getId(), - userId); + boolean isLike = greatGatheringRepository.existsByGatheringIdAndUserId(gathering.getId(), userId); - List gatheringRecommend = gatheringRepository.getGatheringRecommend(gathering.getId(), - gathering.getGatheringCategory().getId(), userId); + List gatheringRecommend = gatheringRepository.getGatheringRecommend(gathering.getId(), gathering.getGatheringCategory().getId(), userId); return new GatheringDetailResponse( gathering.getTitle(), @@ -150,7 +151,8 @@ public GatheringDetailResponse getGatheringDetail(Long userId, Long gatheringId) nowPersonCount, isLike, gatheringApplicantsResponses, - gatheringRecommend + gatheringRecommend, + isApplicants ); } @@ -168,7 +170,7 @@ public GatheringResponse registerGathering(Long userId, GatheringRegisterRequest Place savePlace = placeRepository.save(place); User user = userRepository.findById(userId) .orElseThrow( - () -> new UserNotExistsException("해당하는 id의 User 가 없습니다")); + () -> new UserNotExistsException("해당하는 id 의 User 가 없습니다")); GatheringCategory gatheringCategory = gatheringCategoryRepository.findById( gatheringRegisterRequest.getGatheringCategoryId()) .orElseThrow( @@ -178,12 +180,12 @@ public GatheringResponse registerGathering(Long userId, GatheringRegisterRequest gatheringRegisterRequest.getZoneCategoryNameParent()) .orElseThrow( () -> - new ZoneCategoryNotExistsException("해당하는 name의 ZoneCategory 없습니다")); + new ZoneCategoryNotExistsException("해당하는 name 의 ZoneCategory 없습니다")); ZoneCategory childZoneCategory = zoneCategoryRepository.findByParentZoneCategoryIdAndName( parentZoneCategory.getId(), gatheringRegisterRequest.getZoneCategoryNameChild()) .orElseThrow( - () -> new ZoneCategoryNotExistsException("해당하는 name의 ZoneCategory 없습니다")); + () -> new ZoneCategoryNotExistsException("해당하는 name 의 ZoneCategory 없습니다")); Gathering gathering = new Gathering( @@ -208,7 +210,8 @@ public GatheringResponse registerGathering(Long userId, GatheringRegisterRequest List tags = tagMapper.mapToTags(gatheringRegisterRequest.getTagRegisterRequests()); List saveTags = tagRepository.saveAll(tags); - new GatheringApplicants(gathering, user, GatheringStatus.CONSENT); + GatheringApplicants gatheringApplicants = new GatheringApplicants(gathering, user, GatheringStatus.CONSENT); + gatheringApplicantsRepository.save(gatheringApplicants); for (Tag tag : saveTags) { gatheringTagRepository.save(new GatheringTag(tag, saveGathering)); @@ -217,8 +220,7 @@ public GatheringResponse registerGathering(Long userId, GatheringRegisterRequest } @Transactional - public GatheringResponse modifyGathering(Long userId, Long gatheringId, - GatheringModifyRequest gatheringModifyRequest) { + public GatheringResponse modifyGathering(Long userId, Long gatheringId, GatheringModifyRequest gatheringModifyRequest) { User user = userRepository.findById(userId) .orElseThrow( () -> new UserNotExistsException("해당하는 id의 User 가 없습니다")); @@ -227,7 +229,7 @@ public GatheringResponse modifyGathering(Long userId, Long gatheringId, .orElseThrow( () -> new GatheringNotExistsException("해당하는 id의 gathering 이 존재 하지 않습니다")); - if (gathering.getIsDeleted()) { + if (Boolean.TRUE.equals(gathering.getIsDeleted())) { throw new GatheringDeleteException("해당하는 모임은 삭제가 되었습니다"); } @@ -304,7 +306,7 @@ public void deleteGathering(Long gatheringId, Long userId) { throw new GatheringNotManagerException("해당 유저는 권한이 없습니다"); } - if (gathering.getIsDeleted()) { + if (Boolean.TRUE.equals(gathering.getIsDeleted())) { return; } @@ -355,15 +357,14 @@ private void validateGatheringPageRequest(GatheringPageRequest gatheringPageRequ // 정렬 방식 검증 if (Objects.nonNull(gatheringPageRequest.getSort())) { - if (!LIKE_COUNT_SORT.equals(gatheringPageRequest.getSort()) && !VIEW_COUNT_SORT.equals( - gatheringPageRequest.getSort())) { + if (!LIKE_COUNT_SORT.equals(gatheringPageRequest.getSort()) && !VIEW_COUNT_SORT.equals(gatheringPageRequest.getSort())) { throw new RequestValidationFailedException("잘못된 정렬 코드입니다."); } } // 날짜 검증 - if (Objects.nonNull(gatheringPageRequest.getStartDate()) && Objects.nonNull( - gatheringPageRequest.getEndDate())) { + if (Objects.nonNull(gatheringPageRequest.getStartDate()) && Objects.nonNull(gatheringPageRequest.getEndDate())) { + if (gatheringPageRequest.getStartDate().isAfter(gatheringPageRequest.getEndDate())) { throw new RequestValidationFailedException("시작 날짜가 종료 날짜보다 나중일 수 없습니다."); } From 3e271c73f7d4821a86e6d050cc2408e6fb3ff3af Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Wed, 28 Aug 2024 00:17:40 +0900 Subject: [PATCH 172/371] =?UTF-8?q?style:=20=EC=BD=94=EB=93=9C=20=EC=8A=A4?= =?UTF-8?q?=ED=83=80=EC=9D=BC=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../gathering/controller/GatheringController.java | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/main/java/solitour_backend/solitour/gathering/controller/GatheringController.java b/src/main/java/solitour_backend/solitour/gathering/controller/GatheringController.java index ba5151c8..15b09d1e 100644 --- a/src/main/java/solitour_backend/solitour/gathering/controller/GatheringController.java +++ b/src/main/java/solitour_backend/solitour/gathering/controller/GatheringController.java @@ -4,9 +4,11 @@ import jakarta.servlet.http.HttpServletRequest; import jakarta.validation.Valid; + import java.time.LocalDateTime; import java.util.List; import java.util.Objects; + import lombok.RequiredArgsConstructor; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; @@ -96,8 +98,8 @@ public ResponseEntity updateGathering(@AuthenticationPrincipa if (gatheringModifyRequest.getDeadline().isBefore(LocalDateTime.now())) { throw new RequestValidationFailedException("마감일은 현재 시간보다 이후여야 합니다."); } - GatheringResponse gatheringResponse = gatheringService.modifyGathering(userId, gatheringId, - gatheringModifyRequest); + + GatheringResponse gatheringResponse = gatheringService.modifyGathering(userId, gatheringId, gatheringModifyRequest); return ResponseEntity .status(HttpStatus.CREATED) @@ -117,11 +119,10 @@ public ResponseEntity deleteGathering(@PathVariable Long gatheringId, Http @GetMapping - public ResponseEntity> pageGatheringSortAndFilter( - @RequestParam(defaultValue = "0") int page, - @Valid @ModelAttribute GatheringPageRequest gatheringPageRequest, - BindingResult bindingResult, - HttpServletRequest request) { + public ResponseEntity> pageGatheringSortAndFilter(@RequestParam(defaultValue = "0") int page, + @Valid @ModelAttribute GatheringPageRequest gatheringPageRequest, + BindingResult bindingResult, + HttpServletRequest request) { Utils.validationRequest(bindingResult); Long userId = findUser(request); From 37605593915298b94f9b7ad34fc7d006b31e5d26 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Wed, 28 Aug 2024 00:19:20 +0900 Subject: [PATCH 173/371] =?UTF-8?q?style:=20=EC=BD=94=EB=93=9C=20=EC=8A=A4?= =?UTF-8?q?=ED=83=80=EC=9D=BC=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/InformationService.java | 39 +++++++++++-------- 1 file changed, 22 insertions(+), 17 deletions(-) diff --git a/src/main/java/solitour_backend/solitour/information/service/InformationService.java b/src/main/java/solitour_backend/solitour/information/service/InformationService.java index 772e5994..25ce42aa 100644 --- a/src/main/java/solitour_backend/solitour/information/service/InformationService.java +++ b/src/main/java/solitour_backend/solitour/information/service/InformationService.java @@ -8,6 +8,7 @@ import java.util.ArrayList; import java.util.List; import java.util.Objects; + import lombok.RequiredArgsConstructor; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; @@ -160,12 +161,13 @@ public InformationResponse registerInformation(InformationRegisterRequest inform public InformationDetailResponse getDetailInformation(Long userId, Long informationId) { - Information information = informationRepository.findById(informationId).orElseThrow( - () -> new InformationNotExistsException("해당하는 id의 information이 존재하지 않습니다.")); + Information information = informationRepository.findById(informationId) + .orElseThrow( + () -> + new InformationNotExistsException("해당하는 id 의 information 이 존재하지 않습니다.")); List infoTags = infoTagRepository.findAllByInformationId(information.getId()); - UserPostingResponse userPostingResponse = userMapper.mapToUserPostingResponse( - information.getUser()); + UserPostingResponse userPostingResponse = userMapper.mapToUserPostingResponse(information.getUser()); List tagResponses = new ArrayList<>(); if (!infoTags.isEmpty()) { @@ -184,10 +186,12 @@ public InformationDetailResponse getDetailInformation(Long userId, Long informat int likeCount = greatInformationRepository.countByInformationId(information.getId()); - List informationRecommend = informationRepository.getInformationRecommend( - information.getId(), information.getCategory().getId(), userId); - boolean isLike = greatInformationRepository.existsByInformationIdAndUserIdAndIsDeletedFalse(information.getId(), userId); - UserImage userImage = userImageRepository.findById(userId).orElseThrow(); + List informationRecommend = informationRepository.getInformationRecommend(information.getId(), information.getCategory().getId(), userId); + + boolean isLike = greatInformationRepository.existsByInformationIdAndUserId(information.getId(), userId); + + //TODO + UserImage userImage = userImageRepository.findById(userId).orElse(null); return new InformationDetailResponse( @@ -203,17 +207,16 @@ public InformationDetailResponse getDetailInformation(Long userId, Long informat zoneCategoryResponse, imageResponseList, likeCount, - userImage.getAddress(), + Objects.requireNonNull(userImage).getAddress(), isLike, informationRecommend); } @Transactional - public InformationResponse modifyInformation(Long id, InformationModifyRequest informationModifyRequest, - MultipartFile thumbNail, List contentImages) { + public InformationResponse modifyInformation(Long id, InformationModifyRequest informationModifyRequest, MultipartFile thumbNail, List contentImages) { Information information = informationRepository.findById(id) .orElseThrow( - () -> new InformationNotExistsException("해당하는 id의 information이 존재하지 않습니다.")); + () -> new InformationNotExistsException("해당하는 id의 information 이 존재하지 않습니다.")); information.setTitle(informationModifyRequest.getTitle()); information.setAddress(informationModifyRequest.getAddress()); information.setContent(informationModifyRequest.getContent()); @@ -290,8 +293,8 @@ public InformationResponse modifyInformation(Long id, InformationModifyRequest i if (Objects.nonNull(contentImages)) { for (MultipartFile multipartFile : contentImages) { String upload = s3Uploader.upload(multipartFile, IMAGE_PATH, information.getId()); - Image contentImage = new Image(ImageStatus.CONTENT, information, upload, - LocalDate.now()); + Image contentImage = new Image(ImageStatus.CONTENT, information, upload, LocalDate.now()); + imageRepository.save(contentImage); } } @@ -317,8 +320,10 @@ public InformationResponse modifyInformation(Long id, InformationModifyRequest i @Transactional public void deleteInformation(Long id) { - Information information = informationRepository.findById(id).orElseThrow( - () -> new InformationNotExistsException("해당하는 id의 information이 존재하지 않습니다.")); + Information information = informationRepository.findById(id) + .orElseThrow( + () -> + new InformationNotExistsException("해당하는 id의 information 이 존재하지 않습니다.")); List infoTags = infoTagRepository.findAllByInformationId(information.getId()); infoTagRepository.deleteAllByInformationId(information.getId()); @@ -353,7 +358,7 @@ public Page getPageInformation(Pageable pageable, Long if (Objects.nonNull(informationPageRequest.getChildCategoryId())) { Category category = categoryRepository.findById(informationPageRequest.getChildCategoryId()) .orElseThrow( - () -> new CategoryNotExistsException("해당하는 id의 category는 없습니다")); + () -> new CategoryNotExistsException("해당하는 id의 category 는 없습니다")); if (!Objects.equals(category.getParentCategory().getId(), parentCategoryId)) { throw new RequestValidationFailedException("자식 카테고리의 부모 카테고리와 요청한 부모 카테고리가 다릅니다"); From 98d0536788bcbb493265ac0017df723a53f0452b Mon Sep 17 00:00:00 2001 From: Donghun Won Date: Wed, 28 Aug 2024 19:11:59 +0900 Subject: [PATCH 174/371] =?UTF-8?q?Feat(#110)=20:=20mypage=20=EC=A0=95?= =?UTF-8?q?=EB=B3=B4,=20=EB=AA=A8=EC=9E=84=20=EC=A1=B0=ED=9A=8C=20=20(#111?= =?UTF-8?q?)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Feat : 마이페이지 프로필 이미지 변경 * Feat : 마이페이지 내가 작성한 정보, 구독한 정보 조회 * Style : 코드 포맷팅 * Feat : 마이페이지 모임조회 내가 작성한 모임 조회 내가 신청한 모임 조회 내가 북마크한 모임 조회 * Feat : 유저 모임 가입 상태 필드 추가 * Style : 코드 포맷팅 --- .../solitour/auth/service/OauthService.java | 2 +- .../service/BookMarkInformationService.java | 2 +- .../solitour/diary/service/DiaryService.java | 2 +- .../controller/GatheringController.java | 14 +- .../response/GatheringApplicantResponse.java | 35 ++ .../dto/response/GatheringBriefResponse.java | 1 - .../repository/GatheringRepositoryImpl.java | 8 +- .../gathering/service/GatheringService.java | 25 +- .../service/GatheringApplicantsService.java | 2 +- .../GreatInformationRepository.java | 1 - .../service/GreatInformationService.java | 2 +- .../controller/InformationController.java | 22 +- .../repository/InformationRepositoryImpl.java | 14 +- .../service/InformationService.java | 10 +- .../user/controller/UserController.java | 91 ++++- .../solitour/user/entity/User.java | 4 + .../UserRepository.java | 5 +- .../user/repository/UserRepositoryCustom.java | 23 ++ .../user/repository/UserRepositoryImpl.java | 328 ++++++++++++++++++ .../solitour/user/service/UserService.java | 40 ++- .../solitour/user_image/entity/UserImage.java | 4 +- .../entity/UserImageRepository.java | 1 - .../user_image/service/UserImageService.java | 1 - 23 files changed, 563 insertions(+), 74 deletions(-) create mode 100644 src/main/java/solitour_backend/solitour/gathering/dto/response/GatheringApplicantResponse.java rename src/main/java/solitour_backend/solitour/user/{entity => repository}/UserRepository.java (85%) create mode 100644 src/main/java/solitour_backend/solitour/user/repository/UserRepositoryCustom.java create mode 100644 src/main/java/solitour_backend/solitour/user/repository/UserRepositoryImpl.java diff --git a/src/main/java/solitour_backend/solitour/auth/service/OauthService.java b/src/main/java/solitour_backend/solitour/auth/service/OauthService.java index 0bb75d06..298dcdf9 100644 --- a/src/main/java/solitour_backend/solitour/auth/service/OauthService.java +++ b/src/main/java/solitour_backend/solitour/auth/service/OauthService.java @@ -23,7 +23,7 @@ import solitour_backend.solitour.auth.support.kakao.KakaoProvider; import solitour_backend.solitour.auth.support.kakao.dto.KakaoUserResponse; import solitour_backend.solitour.user.entity.User; -import solitour_backend.solitour.user.entity.UserRepository; +import solitour_backend.solitour.user.repository.UserRepository; import solitour_backend.solitour.user.user_status.UserStatus; import solitour_backend.solitour.user_image.entity.UserImage; import solitour_backend.solitour.user_image.service.UserImageService; diff --git a/src/main/java/solitour_backend/solitour/book_mark_information/service/BookMarkInformationService.java b/src/main/java/solitour_backend/solitour/book_mark_information/service/BookMarkInformationService.java index f392b8ba..22eb0dae 100644 --- a/src/main/java/solitour_backend/solitour/book_mark_information/service/BookMarkInformationService.java +++ b/src/main/java/solitour_backend/solitour/book_mark_information/service/BookMarkInformationService.java @@ -11,7 +11,7 @@ import solitour_backend.solitour.information.entity.Information; import solitour_backend.solitour.information.repository.InformationRepository; import solitour_backend.solitour.user.entity.User; -import solitour_backend.solitour.user.entity.UserRepository; +import solitour_backend.solitour.user.repository.UserRepository; @Service @RequiredArgsConstructor diff --git a/src/main/java/solitour_backend/solitour/diary/service/DiaryService.java b/src/main/java/solitour_backend/solitour/diary/service/DiaryService.java index 53427d34..669d53fe 100644 --- a/src/main/java/solitour_backend/solitour/diary/service/DiaryService.java +++ b/src/main/java/solitour_backend/solitour/diary/service/DiaryService.java @@ -16,7 +16,7 @@ import solitour_backend.solitour.diary.repository.DiaryDayContentRepository; import solitour_backend.solitour.diary.repository.DiaryRepository; import solitour_backend.solitour.user.entity.User; -import solitour_backend.solitour.user.entity.UserRepository; +import solitour_backend.solitour.user.repository.UserRepository; @Service diff --git a/src/main/java/solitour_backend/solitour/gathering/controller/GatheringController.java b/src/main/java/solitour_backend/solitour/gathering/controller/GatheringController.java index 15b09d1e..42b8be84 100644 --- a/src/main/java/solitour_backend/solitour/gathering/controller/GatheringController.java +++ b/src/main/java/solitour_backend/solitour/gathering/controller/GatheringController.java @@ -4,11 +4,9 @@ import jakarta.servlet.http.HttpServletRequest; import jakarta.validation.Valid; - import java.time.LocalDateTime; import java.util.List; import java.util.Objects; - import lombok.RequiredArgsConstructor; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; @@ -99,7 +97,8 @@ public ResponseEntity updateGathering(@AuthenticationPrincipa throw new RequestValidationFailedException("마감일은 현재 시간보다 이후여야 합니다."); } - GatheringResponse gatheringResponse = gatheringService.modifyGathering(userId, gatheringId, gatheringModifyRequest); + GatheringResponse gatheringResponse = gatheringService.modifyGathering(userId, gatheringId, + gatheringModifyRequest); return ResponseEntity .status(HttpStatus.CREATED) @@ -119,10 +118,11 @@ public ResponseEntity deleteGathering(@PathVariable Long gatheringId, Http @GetMapping - public ResponseEntity> pageGatheringSortAndFilter(@RequestParam(defaultValue = "0") int page, - @Valid @ModelAttribute GatheringPageRequest gatheringPageRequest, - BindingResult bindingResult, - HttpServletRequest request) { + public ResponseEntity> pageGatheringSortAndFilter( + @RequestParam(defaultValue = "0") int page, + @Valid @ModelAttribute GatheringPageRequest gatheringPageRequest, + BindingResult bindingResult, + HttpServletRequest request) { Utils.validationRequest(bindingResult); Long userId = findUser(request); diff --git a/src/main/java/solitour_backend/solitour/gathering/dto/response/GatheringApplicantResponse.java b/src/main/java/solitour_backend/solitour/gathering/dto/response/GatheringApplicantResponse.java new file mode 100644 index 00000000..33b4a5e4 --- /dev/null +++ b/src/main/java/solitour_backend/solitour/gathering/dto/response/GatheringApplicantResponse.java @@ -0,0 +1,35 @@ +package solitour_backend.solitour.gathering.dto.response; + +import java.time.LocalDateTime; +import lombok.AllArgsConstructor; +import lombok.Getter; +import solitour_backend.solitour.gathering.entity.AllowedSex; + +@Getter +@AllArgsConstructor +public class GatheringApplicantResponse { + private Long gatheringId; + private String title; + private String zoneCategoryParentName; + private String zoneCategoryChildName; + private Integer viewCount; + private Boolean isBookMark; + private Integer likeCount; + + private String gatheringCategoryName; + private String userName; + + private LocalDateTime scheduleStartDate; + private LocalDateTime scheduleEndDate; + + private LocalDateTime deadline; + + private AllowedSex allowedSex; + + private Integer startAge; + private Integer endAge; + private Integer personCount; + private Integer nowPersonCount; + private Boolean isLike; + private String gatheringStatus; +} diff --git a/src/main/java/solitour_backend/solitour/gathering/dto/response/GatheringBriefResponse.java b/src/main/java/solitour_backend/solitour/gathering/dto/response/GatheringBriefResponse.java index 1f9f942f..2d34c161 100644 --- a/src/main/java/solitour_backend/solitour/gathering/dto/response/GatheringBriefResponse.java +++ b/src/main/java/solitour_backend/solitour/gathering/dto/response/GatheringBriefResponse.java @@ -32,5 +32,4 @@ public class GatheringBriefResponse { private Integer nowPersonCount; private Boolean isLike; - } diff --git a/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryImpl.java b/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryImpl.java index 47e4dda8..298a6309 100644 --- a/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryImpl.java +++ b/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryImpl.java @@ -10,13 +10,11 @@ import com.querydsl.core.types.dsl.PathBuilder; import com.querydsl.jpa.JPAExpressions; import com.querydsl.jpa.JPQLQuery; - import java.time.LocalDate; import java.time.LocalDateTime; import java.time.LocalTime; import java.util.List; import java.util.Objects; - import org.springframework.data.domain.Page; import org.springframework.data.domain.PageImpl; import org.springframework.data.domain.Pageable; @@ -57,7 +55,8 @@ public List getGatheringRecommend(Long gatheringId, Long .leftJoin(bookMarkGathering) .on(bookMarkGathering.gathering.id.eq(gathering.id).and(bookMarkGathering.user.id.eq(userId))) .leftJoin(category).on(category.id.eq(gathering.gatheringCategory.id)) - .leftJoin(gatheringApplicants).on(gatheringApplicants.gathering.id.eq(gathering.id).and(gatheringApplicants.gatheringStatus.eq(GatheringStatus.CONSENT))) + .leftJoin(gatheringApplicants).on(gatheringApplicants.gathering.id.eq(gathering.id) + .and(gatheringApplicants.gatheringStatus.eq(GatheringStatus.CONSENT))) .where(gathering.isFinish.eq(Boolean.FALSE) .and(gathering.gatheringCategory.id.eq(gatheringCategoryId)) .and(gathering.id.ne(gatheringId)) @@ -178,7 +177,8 @@ public List getGatheringLikeCountFromCreatedIn3(Long use .leftJoin(bookMarkGathering) .on(bookMarkGathering.gathering.id.eq(gathering.id).and(bookMarkGathering.user.id.eq(userId))) .leftJoin(category).on(category.id.eq(gathering.gatheringCategory.id)) - .leftJoin(gatheringApplicants).on(gatheringApplicants.gathering.id.eq(gathering.id).and(gatheringApplicants.gatheringStatus.eq(GatheringStatus.CONSENT))) + .leftJoin(gatheringApplicants).on(gatheringApplicants.gathering.id.eq(gathering.id) + .and(gatheringApplicants.gatheringStatus.eq(GatheringStatus.CONSENT))) .where(gathering.isFinish.eq(Boolean.FALSE) .and(gathering.isDeleted.eq(Boolean.FALSE)) .and(gathering.createdAt.after(LocalDateTime.now().minusMonths(3)))) diff --git a/src/main/java/solitour_backend/solitour/gathering/service/GatheringService.java b/src/main/java/solitour_backend/solitour/gathering/service/GatheringService.java index 7a7310bd..81635f59 100644 --- a/src/main/java/solitour_backend/solitour/gathering/service/GatheringService.java +++ b/src/main/java/solitour_backend/solitour/gathering/service/GatheringService.java @@ -6,7 +6,6 @@ import java.util.ArrayList; import java.util.List; import java.util.Objects; - import lombok.RequiredArgsConstructor; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; @@ -52,8 +51,8 @@ import solitour_backend.solitour.user.dto.UserPostingResponse; import solitour_backend.solitour.user.dto.mapper.UserMapper; import solitour_backend.solitour.user.entity.User; -import solitour_backend.solitour.user.entity.UserRepository; import solitour_backend.solitour.user.exception.UserNotExistsException; +import solitour_backend.solitour.user.repository.UserRepository; import solitour_backend.solitour.zone_category.dto.mapper.ZoneCategoryMapper; import solitour_backend.solitour.zone_category.dto.response.ZoneCategoryResponse; import solitour_backend.solitour.zone_category.entity.ZoneCategory; @@ -106,11 +105,13 @@ public GatheringDetailResponse getGatheringDetail(Long userId, Long gatheringId) } GatheringCategory gatheringCategory = gathering.getGatheringCategory(); - GatheringCategoryResponse gatheringCategoryResponse = gatheringCategoryMapper.mapToCategoryResponse(gatheringCategory); + GatheringCategoryResponse gatheringCategoryResponse = gatheringCategoryMapper.mapToCategoryResponse( + gatheringCategory); PlaceResponse placeResponse = placeMapper.mapToPlaceResponse(gathering.getPlace()); - ZoneCategoryResponse zoneCategoryResponse = zoneCategoryMapper.mapToZoneCategoryResponse(gathering.getZoneCategory()); + ZoneCategoryResponse zoneCategoryResponse = zoneCategoryMapper.mapToZoneCategoryResponse( + gathering.getZoneCategory()); int likeCount = greatGatheringRepository.countByGatheringId(gathering.getId()); @@ -119,7 +120,9 @@ public GatheringDetailResponse getGatheringDetail(Long userId, Long gatheringId) boolean isApplicants = gatheringApplicantsRepository.existsByGatheringIdAndUserId(gathering.getId(), userId); if (gathering.getUser().getId().equals(userId)) { - gatheringApplicantsResponses = gatheringApplicantsMapper.mapToGatheringApplicantsResponses(gatheringApplicantsRepository.findAllByGathering_IdAndUserIdNot(gathering.getId(), gathering.getUser().getId())); + gatheringApplicantsResponses = gatheringApplicantsMapper.mapToGatheringApplicantsResponses( + gatheringApplicantsRepository.findAllByGathering_IdAndUserIdNot(gathering.getId(), + gathering.getUser().getId())); } int nowPersonCount = gatheringApplicantsRepository.countAllByGathering_IdAndGatheringStatus(gathering.getId(), @@ -127,7 +130,8 @@ public GatheringDetailResponse getGatheringDetail(Long userId, Long gatheringId) boolean isLike = greatGatheringRepository.existsByGatheringIdAndUserId(gathering.getId(), userId); - List gatheringRecommend = gatheringRepository.getGatheringRecommend(gathering.getId(), gathering.getGatheringCategory().getId(), userId); + List gatheringRecommend = gatheringRepository.getGatheringRecommend(gathering.getId(), + gathering.getGatheringCategory().getId(), userId); return new GatheringDetailResponse( gathering.getTitle(), @@ -220,7 +224,8 @@ public GatheringResponse registerGathering(Long userId, GatheringRegisterRequest } @Transactional - public GatheringResponse modifyGathering(Long userId, Long gatheringId, GatheringModifyRequest gatheringModifyRequest) { + public GatheringResponse modifyGathering(Long userId, Long gatheringId, + GatheringModifyRequest gatheringModifyRequest) { User user = userRepository.findById(userId) .orElseThrow( () -> new UserNotExistsException("해당하는 id의 User 가 없습니다")); @@ -357,13 +362,15 @@ private void validateGatheringPageRequest(GatheringPageRequest gatheringPageRequ // 정렬 방식 검증 if (Objects.nonNull(gatheringPageRequest.getSort())) { - if (!LIKE_COUNT_SORT.equals(gatheringPageRequest.getSort()) && !VIEW_COUNT_SORT.equals(gatheringPageRequest.getSort())) { + if (!LIKE_COUNT_SORT.equals(gatheringPageRequest.getSort()) && !VIEW_COUNT_SORT.equals( + gatheringPageRequest.getSort())) { throw new RequestValidationFailedException("잘못된 정렬 코드입니다."); } } // 날짜 검증 - if (Objects.nonNull(gatheringPageRequest.getStartDate()) && Objects.nonNull(gatheringPageRequest.getEndDate())) { + if (Objects.nonNull(gatheringPageRequest.getStartDate()) && Objects.nonNull( + gatheringPageRequest.getEndDate())) { if (gatheringPageRequest.getStartDate().isAfter(gatheringPageRequest.getEndDate())) { throw new RequestValidationFailedException("시작 날짜가 종료 날짜보다 나중일 수 없습니다."); diff --git a/src/main/java/solitour_backend/solitour/gathering_applicants/service/GatheringApplicantsService.java b/src/main/java/solitour_backend/solitour/gathering_applicants/service/GatheringApplicantsService.java index 30dea7f5..ec68b974 100644 --- a/src/main/java/solitour_backend/solitour/gathering_applicants/service/GatheringApplicantsService.java +++ b/src/main/java/solitour_backend/solitour/gathering_applicants/service/GatheringApplicantsService.java @@ -17,8 +17,8 @@ import solitour_backend.solitour.gathering_applicants.exception.GatheringNotManagerException; import solitour_backend.solitour.gathering_applicants.repository.GatheringApplicantsRepository; import solitour_backend.solitour.user.entity.User; -import solitour_backend.solitour.user.entity.UserRepository; import solitour_backend.solitour.user.exception.UserNotExistsException; +import solitour_backend.solitour.user.repository.UserRepository; @Service @Transactional diff --git a/src/main/java/solitour_backend/solitour/great_information/repository/GreatInformationRepository.java b/src/main/java/solitour_backend/solitour/great_information/repository/GreatInformationRepository.java index aa9877a1..8ce2e6ee 100644 --- a/src/main/java/solitour_backend/solitour/great_information/repository/GreatInformationRepository.java +++ b/src/main/java/solitour_backend/solitour/great_information/repository/GreatInformationRepository.java @@ -1,7 +1,6 @@ package solitour_backend.solitour.great_information.repository; import java.util.Optional; - import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; import solitour_backend.solitour.great_information.entity.GreatInformation; diff --git a/src/main/java/solitour_backend/solitour/great_information/service/GreatInformationService.java b/src/main/java/solitour_backend/solitour/great_information/service/GreatInformationService.java index 75c0d826..d583da6f 100644 --- a/src/main/java/solitour_backend/solitour/great_information/service/GreatInformationService.java +++ b/src/main/java/solitour_backend/solitour/great_information/service/GreatInformationService.java @@ -10,7 +10,7 @@ import solitour_backend.solitour.information.entity.Information; import solitour_backend.solitour.information.repository.InformationRepository; import solitour_backend.solitour.user.entity.User; -import solitour_backend.solitour.user.entity.UserRepository; +import solitour_backend.solitour.user.repository.UserRepository; @Service @RequiredArgsConstructor diff --git a/src/main/java/solitour_backend/solitour/information/controller/InformationController.java b/src/main/java/solitour_backend/solitour/information/controller/InformationController.java index d1e8c355..50b69069 100644 --- a/src/main/java/solitour_backend/solitour/information/controller/InformationController.java +++ b/src/main/java/solitour_backend/solitour/information/controller/InformationController.java @@ -3,10 +3,8 @@ import jakarta.servlet.http.HttpServletRequest; import jakarta.validation.Valid; - import java.util.List; import java.util.Objects; - import lombok.RequiredArgsConstructor; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; @@ -51,10 +49,11 @@ public class InformationController { @PostMapping @Authenticated - public ResponseEntity createInformation(@Valid @RequestPart("request") InformationRegisterRequest informationRegisterRequest, - @RequestPart("thumbNailImage") MultipartFile thumbnail, - @RequestPart("contentImages") List contentImages, - BindingResult bindingResult) { + public ResponseEntity createInformation( + @Valid @RequestPart("request") InformationRegisterRequest informationRegisterRequest, + @RequestPart("thumbNailImage") MultipartFile thumbnail, + @RequestPart("contentImages") List contentImages, + BindingResult bindingResult) { Utils.validationRequest(bindingResult); InformationResponse informationResponse = informationService.registerInformation( informationRegisterRequest, thumbnail, contentImages); @@ -104,11 +103,12 @@ public ResponseEntity deleteInformation(@PathVariable Long informationId) } @GetMapping - public ResponseEntity> pageInformationSortAndFilter(@RequestParam(defaultValue = "0") int page, - @RequestParam(defaultValue = "1") Long parentCategoryId, - @Valid @ModelAttribute InformationPageRequest informationPageRequest, - BindingResult bindingResult, - HttpServletRequest request) { + public ResponseEntity> pageInformationSortAndFilter( + @RequestParam(defaultValue = "0") int page, + @RequestParam(defaultValue = "1") Long parentCategoryId, + @Valid @ModelAttribute InformationPageRequest informationPageRequest, + BindingResult bindingResult, + HttpServletRequest request) { Utils.validationRequest(bindingResult); Long userId = findUser(request); diff --git a/src/main/java/solitour_backend/solitour/information/repository/InformationRepositoryImpl.java b/src/main/java/solitour_backend/solitour/information/repository/InformationRepositoryImpl.java index af99ec44..e95fc2f1 100644 --- a/src/main/java/solitour_backend/solitour/information/repository/InformationRepositoryImpl.java +++ b/src/main/java/solitour_backend/solitour/information/repository/InformationRepositoryImpl.java @@ -9,11 +9,9 @@ import com.querydsl.core.types.dsl.NumberExpression; import com.querydsl.jpa.JPAExpressions; import com.querydsl.jpa.JPQLQuery; - import java.time.LocalDateTime; import java.util.List; import java.util.Objects; - import org.springframework.data.domain.Page; import org.springframework.data.domain.PageImpl; import org.springframework.data.domain.Pageable; @@ -53,7 +51,8 @@ public Page getInformationPageFilterAndOrder(Pageable BooleanBuilder whereClause = new BooleanBuilder(); if (Objects.nonNull(informationPageRequest.getZoneCategoryId())) { - whereClause.and(information.zoneCategory.parentZoneCategory.id.eq(informationPageRequest.getZoneCategoryId())); + whereClause.and( + information.zoneCategory.parentZoneCategory.id.eq(informationPageRequest.getZoneCategoryId())); } BooleanBuilder categoryCondition = new BooleanBuilder(); @@ -72,7 +71,8 @@ public Page getInformationPageFilterAndOrder(Pageable .leftJoin(zoneCategoryParent).on(zoneCategoryParent.id.eq(zoneCategoryChild.parentZoneCategory.id)) .leftJoin(bookMarkInformation) .on(bookMarkInformation.information.id.eq(information.id).and(bookMarkInformation.user.id.eq(userId))) - .leftJoin(image).on(image.information.id.eq(information.id).and(image.imageStatus.eq(ImageStatus.THUMBNAIL))) + .leftJoin(image) + .on(image.information.id.eq(information.id).and(image.imageStatus.eq(ImageStatus.THUMBNAIL))) .join(category).on(category.id.eq(information.category.id).and(categoryCondition)) .where(whereClause) .select(information.count()).fetchCount(); @@ -82,7 +82,8 @@ public Page getInformationPageFilterAndOrder(Pageable .leftJoin(zoneCategoryParent).on(zoneCategoryParent.id.eq(zoneCategoryChild.parentZoneCategory.id)) .leftJoin(bookMarkInformation) .on(bookMarkInformation.information.id.eq(information.id).and(bookMarkInformation.user.id.eq(userId))) - .leftJoin(image).on(image.information.id.eq(information.id).and(image.imageStatus.eq(ImageStatus.THUMBNAIL))) + .leftJoin(image) + .on(image.information.id.eq(information.id).and(image.imageStatus.eq(ImageStatus.THUMBNAIL))) .join(category).on(category.id.eq(information.category.id).and(categoryCondition)) .leftJoin(greatInformation).on(greatInformation.information.id.eq(information.id)) .where(whereClause) @@ -139,7 +140,8 @@ public List getInformationLikeCountFromCreatedIn3(Long } @Override - public List getInformationRecommend(Long informationId, Long childCategoryId, Long userId) { + public List getInformationRecommend(Long informationId, Long childCategoryId, + Long userId) { return from(information) .join(zoneCategoryChild).on(zoneCategoryChild.id.eq(information.zoneCategory.id)) .leftJoin(zoneCategoryParent).on(zoneCategoryParent.id.eq(zoneCategoryChild.parentZoneCategory.id)) diff --git a/src/main/java/solitour_backend/solitour/information/service/InformationService.java b/src/main/java/solitour_backend/solitour/information/service/InformationService.java index 25ce42aa..8d91cdf5 100644 --- a/src/main/java/solitour_backend/solitour/information/service/InformationService.java +++ b/src/main/java/solitour_backend/solitour/information/service/InformationService.java @@ -8,7 +8,6 @@ import java.util.ArrayList; import java.util.List; import java.util.Objects; - import lombok.RequiredArgsConstructor; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; @@ -57,8 +56,8 @@ import solitour_backend.solitour.user.dto.UserPostingResponse; import solitour_backend.solitour.user.dto.mapper.UserMapper; import solitour_backend.solitour.user.entity.User; -import solitour_backend.solitour.user.entity.UserRepository; import solitour_backend.solitour.user.exception.UserNotExistsException; +import solitour_backend.solitour.user.repository.UserRepository; import solitour_backend.solitour.user_image.entity.UserImage; import solitour_backend.solitour.user_image.entity.UserImageRepository; import solitour_backend.solitour.zone_category.dto.mapper.ZoneCategoryMapper; @@ -186,14 +185,14 @@ public InformationDetailResponse getDetailInformation(Long userId, Long informat int likeCount = greatInformationRepository.countByInformationId(information.getId()); - List informationRecommend = informationRepository.getInformationRecommend(information.getId(), information.getCategory().getId(), userId); + List informationRecommend = informationRepository.getInformationRecommend( + information.getId(), information.getCategory().getId(), userId); boolean isLike = greatInformationRepository.existsByInformationIdAndUserId(information.getId(), userId); //TODO UserImage userImage = userImageRepository.findById(userId).orElse(null); - return new InformationDetailResponse( information.getTitle(), information.getAddress(), @@ -213,7 +212,8 @@ public InformationDetailResponse getDetailInformation(Long userId, Long informat } @Transactional - public InformationResponse modifyInformation(Long id, InformationModifyRequest informationModifyRequest, MultipartFile thumbNail, List contentImages) { + public InformationResponse modifyInformation(Long id, InformationModifyRequest informationModifyRequest, + MultipartFile thumbNail, List contentImages) { Information information = informationRepository.findById(id) .orElseThrow( () -> new InformationNotExistsException("해당하는 id의 information 이 존재하지 않습니다.")); diff --git a/src/main/java/solitour_backend/solitour/user/controller/UserController.java b/src/main/java/solitour_backend/solitour/user/controller/UserController.java index 9a7b8d8e..cad40666 100644 --- a/src/main/java/solitour_backend/solitour/user/controller/UserController.java +++ b/src/main/java/solitour_backend/solitour/user/controller/UserController.java @@ -1,7 +1,11 @@ package solitour_backend.solitour.user.controller; + import jakarta.servlet.http.HttpServletResponse; import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.DeleteMapping; @@ -10,13 +14,17 @@ import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RequestPart; import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.multipart.MultipartFile; import solitour_backend.solitour.auth.config.Authenticated; import solitour_backend.solitour.auth.config.AuthenticationPrincipal; import solitour_backend.solitour.auth.service.OauthService; -import solitour_backend.solitour.auth.service.TokenService; import solitour_backend.solitour.auth.support.google.GoogleConnector; import solitour_backend.solitour.auth.support.kakao.KakaoConnector; +import solitour_backend.solitour.gathering.dto.response.GatheringApplicantResponse; +import solitour_backend.solitour.gathering.dto.response.GatheringBriefResponse; +import solitour_backend.solitour.information.dto.response.InformationBriefResponse; import solitour_backend.solitour.user.dto.UpdateAgeAndSex; import solitour_backend.solitour.user.dto.UpdateNicknameRequest; import solitour_backend.solitour.user.exception.NicknameAlreadyExistsException; @@ -33,7 +41,8 @@ public class UserController { private final OauthService oauthservice; private final KakaoConnector kakaoConnector; private final GoogleConnector googleConnector; - private final TokenService tokenService; + + public static final int PAGE_SIZE = 6; @Authenticated @GetMapping("/info") @@ -73,18 +82,12 @@ public ResponseEntity updateAgeAndSex(@AuthenticationPrincipal Long user } } - @Authenticated - @PutMapping("/image") - public ResponseEntity updateUserImage(@AuthenticationPrincipal Long userId, - @RequestParam String userImage) { - try { - userService.updateUserImage(userId, userImage); - return ResponseEntity.ok("UserImage updated successfully"); - } catch (UserNotExistsException e) { - return ResponseEntity.status(HttpStatus.NOT_FOUND).body("User not found"); - } catch (Exception e) { - return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("An internal error occurred"); - } + @PutMapping("/profile") + public ResponseEntity updateUserProfile(@AuthenticationPrincipal Long userId, + @RequestPart(value = "userProfile", required = false) MultipartFile userProfile) { + userService.updateUserProfile(userId, userProfile); + + return ResponseEntity.ok().build(); } @Authenticated @@ -106,6 +109,65 @@ public ResponseEntity deleteUser(HttpServletResponse response, @Authenti } } + @Authenticated + @GetMapping("/mypage/information/owner") + public ResponseEntity> retrieveInformationOwner( + @RequestParam(defaultValue = "0") int page, + @AuthenticationPrincipal Long userId) { + Pageable pageable = PageRequest.of(page, PAGE_SIZE); + Page response = userService.retrieveInformationOwner(pageable, userId); + + return ResponseEntity.ok(response); + } + + @GetMapping("/mypage/information/bookmark") + public ResponseEntity> retrieveInformationBookmark( + @RequestParam(defaultValue = "0") int page, + @AuthenticationPrincipal Long userId) { + + Pageable pageable = PageRequest.of(page, PAGE_SIZE); + Page response = userService.retrieveInformationBookmark(pageable, + userId); + + return ResponseEntity.ok(response); + } + + @Authenticated + @GetMapping("/mypage/gathering/host") + public ResponseEntity> retrieveGatheringHost( + @RequestParam(defaultValue = "0") int page, + @AuthenticationPrincipal Long userId) { + Pageable pageable = PageRequest.of(page, PAGE_SIZE); + Page response = userService.retrieveGatheringHost(pageable, userId); + + return ResponseEntity.ok(response); + } + + @GetMapping("/mypage/gathering/bookmark") + public ResponseEntity> retrieveGatheringBookmark( + @RequestParam(defaultValue = "0") int page, + @AuthenticationPrincipal Long userId) { + + Pageable pageable = PageRequest.of(page, PAGE_SIZE); + Page response = userService.retrieveGatheringBookmark(pageable, + userId); + + return ResponseEntity.ok(response); + } + + @GetMapping("/mypage/gathering/applicant") + public ResponseEntity> retrieveGatheringApplicant( + @RequestParam(defaultValue = "0") int page, + @AuthenticationPrincipal Long userId) { + + Pageable pageable = PageRequest.of(page, PAGE_SIZE); + Page response = userService.retrieveGatheringApplicant(pageable, + userId); + + return ResponseEntity.ok(response); + } + + private String getOauthAccessToken(String type, String code, String redirectUrl) { String token = ""; switch (type) { @@ -119,4 +181,5 @@ private String getOauthAccessToken(String type, String code, String redirectUrl) } return token; } + } diff --git a/src/main/java/solitour_backend/solitour/user/entity/User.java b/src/main/java/solitour_backend/solitour/user/entity/User.java index ac16c20d..a4b28417 100644 --- a/src/main/java/solitour_backend/solitour/user/entity/User.java +++ b/src/main/java/solitour_backend/solitour/user/entity/User.java @@ -89,4 +89,8 @@ public void deleteUser(Long userId) { this.userStatus = UserStatus.DELETE; this.deletedAt = LocalDateTime.now(); } + + public void updateUserImage(String imageUrl) { + this.userImage.updateUserImage(imageUrl); + } } diff --git a/src/main/java/solitour_backend/solitour/user/entity/UserRepository.java b/src/main/java/solitour_backend/solitour/user/repository/UserRepository.java similarity index 85% rename from src/main/java/solitour_backend/solitour/user/entity/UserRepository.java rename to src/main/java/solitour_backend/solitour/user/repository/UserRepository.java index d60646e6..804da6f9 100644 --- a/src/main/java/solitour_backend/solitour/user/entity/UserRepository.java +++ b/src/main/java/solitour_backend/solitour/user/repository/UserRepository.java @@ -1,10 +1,11 @@ -package solitour_backend.solitour.user.entity; +package solitour_backend.solitour.user.repository; import java.util.Optional; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; +import solitour_backend.solitour.user.entity.User; -public interface UserRepository extends JpaRepository { +public interface UserRepository extends JpaRepository, UserRepositoryCustom { @Query("SELECT u FROM User u JOIN FETCH u.userImage WHERE u.nickname = :nickname AND u.userStatus = '활성화'") Optional findByNickname(String nickname); diff --git a/src/main/java/solitour_backend/solitour/user/repository/UserRepositoryCustom.java b/src/main/java/solitour_backend/solitour/user/repository/UserRepositoryCustom.java new file mode 100644 index 00000000..34b50425 --- /dev/null +++ b/src/main/java/solitour_backend/solitour/user/repository/UserRepositoryCustom.java @@ -0,0 +1,23 @@ +package solitour_backend.solitour.user.repository; + +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.repository.NoRepositoryBean; +import solitour_backend.solitour.gathering.dto.response.GatheringApplicantResponse; +import solitour_backend.solitour.gathering.dto.response.GatheringBriefResponse; +import solitour_backend.solitour.information.dto.response.InformationBriefResponse; + + +@NoRepositoryBean +public interface UserRepositoryCustom { + + Page retrieveInformationOwner(Pageable pageable, Long userId); + + Page retrieveInformationBookmark(Pageable pageable, Long userId); + + Page retrieveGatheringHost(Pageable pageable, Long userId); + + Page retrieveGatheringBookmark(Pageable pageable, Long userId); + + Page retrieveGatheringApplicant(Pageable pageable, Long userId); +} diff --git a/src/main/java/solitour_backend/solitour/user/repository/UserRepositoryImpl.java b/src/main/java/solitour_backend/solitour/user/repository/UserRepositoryImpl.java new file mode 100644 index 00000000..571bf473 --- /dev/null +++ b/src/main/java/solitour_backend/solitour/user/repository/UserRepositoryImpl.java @@ -0,0 +1,328 @@ +package solitour_backend.solitour.user.repository; + +import com.querydsl.core.types.Projections; +import com.querydsl.core.types.dsl.BooleanExpression; +import com.querydsl.core.types.dsl.CaseBuilder; +import com.querydsl.core.types.dsl.Expressions; +import com.querydsl.core.types.dsl.NumberExpression; +import com.querydsl.core.types.dsl.StringExpression; +import com.querydsl.jpa.JPAExpressions; +import com.querydsl.jpa.JPQLQuery; +import java.util.List; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageImpl; +import org.springframework.data.domain.Pageable; +import org.springframework.data.jpa.repository.support.QuerydslRepositorySupport; +import solitour_backend.solitour.book_mark_gathering.entity.QBookMarkGathering; +import solitour_backend.solitour.book_mark_information.entity.QBookMarkInformation; +import solitour_backend.solitour.gathering.dto.response.GatheringApplicantResponse; +import solitour_backend.solitour.gathering.dto.response.GatheringBriefResponse; +import solitour_backend.solitour.gathering.entity.Gathering; +import solitour_backend.solitour.gathering.entity.QGathering; +import solitour_backend.solitour.gathering_applicants.entity.GatheringStatus; +import solitour_backend.solitour.gathering_applicants.entity.QGatheringApplicants; +import solitour_backend.solitour.gathering_category.entity.QGatheringCategory; +import solitour_backend.solitour.great_gathering.entity.QGreatGathering; +import solitour_backend.solitour.great_information.entity.QGreatInformation; +import solitour_backend.solitour.image.entity.QImage; +import solitour_backend.solitour.image.image_status.ImageStatus; +import solitour_backend.solitour.information.dto.response.InformationBriefResponse; +import solitour_backend.solitour.information.entity.Information; +import solitour_backend.solitour.information.entity.QInformation; +import solitour_backend.solitour.place.entity.QPlace; +import solitour_backend.solitour.user.entity.User; +import solitour_backend.solitour.zone_category.entity.QZoneCategory; + +public class UserRepositoryImpl extends QuerydslRepositorySupport implements UserRepositoryCustom { + + public UserRepositoryImpl() { + super(User.class); + } + + QInformation information = QInformation.information; + QZoneCategory zoneCategoryChild = QZoneCategory.zoneCategory; + QZoneCategory zoneCategoryParent = new QZoneCategory("zoneCategoryParent"); + QBookMarkInformation bookMarkInformation = QBookMarkInformation.bookMarkInformation; + QImage image = QImage.image; + QGreatInformation greatInformation = QGreatInformation.greatInformation; + QGathering gathering = QGathering.gathering; + QGatheringCategory gatheringCategory = QGatheringCategory.gatheringCategory; + QPlace place = QPlace.place; + QBookMarkGathering bookMarkGathering = QBookMarkGathering.bookMarkGathering; + QGatheringApplicants gatheringApplicants = QGatheringApplicants.gatheringApplicants; + QGreatGathering greatGathering = QGreatGathering.greatGathering; + + @Override + public Page retrieveInformationOwner(Pageable pageable, Long userId) { + JPQLQuery query = from(information) + .leftJoin(bookMarkInformation) + .on(bookMarkInformation.information.id.eq(information.id)) + .leftJoin(zoneCategoryParent) + .on(zoneCategoryParent.id.eq(information.zoneCategory.parentZoneCategory.id)) + .leftJoin(image).on(image.information.id.eq(information.id) + .and(image.imageStatus.eq(ImageStatus.THUMBNAIL))) + .leftJoin(greatInformation).on(greatInformation.information.id.eq(information.id)) + .where(information.user.id.eq(userId)); + + List list = query + .groupBy(information.id, information.title, zoneCategoryParent.name, zoneCategoryChild.name, + information.viewCount, bookMarkInformation.user.id, image.address) + .orderBy(information.createdDate.desc()) + .select(Projections.constructor( + InformationBriefResponse.class, + information.id, + information.title, + zoneCategoryParent.name, + zoneCategoryChild.name, + information.viewCount, + bookMarkInformation.user.id.isNotNull(), + image.address, + greatInformation.information.count().coalesce(0L).intValue() + )) + .offset(pageable.getOffset()) + .limit(pageable.getPageSize()) + .fetch(); + + long total = query.fetchCount(); + + return new PageImpl<>(list, pageable, total); + } + + @Override + public Page retrieveInformationBookmark(Pageable pageable, Long userId) { + JPQLQuery query = from(information) + .leftJoin(bookMarkInformation) + .on(bookMarkInformation.information.id.eq(information.id)) + .leftJoin(zoneCategoryParent) + .on(zoneCategoryParent.id.eq(information.zoneCategory.parentZoneCategory.id)) + .leftJoin(image).on(image.information.id.eq(information.id) + .and(image.imageStatus.eq(ImageStatus.THUMBNAIL))) + .leftJoin(greatInformation).on(greatInformation.information.id.eq(information.id)) + .where(information.user.id.eq(userId).and(bookMarkInformation.user.id.eq(userId))); + + List list = query + .groupBy(information.id, information.title, zoneCategoryParent.name, zoneCategoryChild.name, + information.viewCount, bookMarkInformation.user.id, image.address) + .orderBy(information.createdDate.desc()) + .select(Projections.constructor( + InformationBriefResponse.class, + information.id, + information.title, + zoneCategoryParent.name, + zoneCategoryChild.name, + information.viewCount, + bookMarkInformation.user.id.isNotNull(), + image.address, + greatInformation.information.count().coalesce(0L).intValue() + )) + .offset(pageable.getOffset()) + .limit(pageable.getPageSize()) + .fetch(); + + long total = query.fetchCount(); + + return new PageImpl<>(list, pageable, total); + } + + @Override + public Page retrieveGatheringHost(Pageable pageable, Long userId) { + NumberExpression likeCount = countGreatGatheringByGatheringById(); + BooleanExpression isBookMark = isGatheringBookmark(userId); + + JPQLQuery query = from(gathering) + .leftJoin(zoneCategoryParent) + .on(zoneCategoryParent.id.eq(gathering.zoneCategory.parentZoneCategory.id)) + .leftJoin(gatheringCategory) + .on(gatheringCategory.id.eq(gathering.gatheringCategory.id)) + .leftJoin(gatheringApplicants) + .on(gatheringApplicants.gathering.id.eq(gathering.id)) + .orderBy(gathering.createdAt.desc()) + .where(gathering.user.id.eq(userId)); + + List list = query + .groupBy(gathering.id, gathering.title, zoneCategoryParent.name, zoneCategoryChild.name, + gathering.viewCount, + gatheringCategory.name, gathering.user.nickname, gathering.scheduleStartDate, + gathering.scheduleEndDate, gathering.deadline, gathering.allowedSex, gathering.startAge, + gathering.endAge, gathering.personCount) + .select(Projections.constructor( + GatheringBriefResponse.class, + gathering.id, + gathering.title, + zoneCategoryParent.name, + zoneCategoryChild.name, + gathering.viewCount, + isBookMark, + likeCount, + gatheringCategory.name, + gathering.user.nickname, + gathering.scheduleStartDate, + gathering.scheduleEndDate, + gathering.deadline, + gathering.allowedSex, + gathering.startAge, + gathering.endAge, + gathering.personCount, + gatheringApplicants.count().coalesce(0L).intValue(), + isUserGreatGathering(userId) + )) + .offset(pageable.getOffset()) + .limit(pageable.getPageSize()) + .fetch(); + long total = query.fetchCount(); + + return new PageImpl<>(list, pageable, total); + } + + @Override + public Page retrieveGatheringBookmark(Pageable pageable, Long userId) { + NumberExpression likeCount = countGreatGatheringByGatheringById(); + BooleanExpression isBookMark = isGatheringBookmark(userId); + + JPQLQuery query = from(gathering) + .leftJoin(zoneCategoryParent) + .on(zoneCategoryParent.id.eq(gathering.zoneCategory.parentZoneCategory.id)) + .leftJoin(gatheringCategory) + .on(gatheringCategory.id.eq(gathering.gatheringCategory.id)) + .leftJoin(gatheringApplicants) + .on(gatheringApplicants.gathering.id.eq(gathering.id)) + .leftJoin(bookMarkGathering) + .on(bookMarkGathering.gathering.id.eq(gathering.id)) + .orderBy(gathering.createdAt.desc()) + .where(bookMarkGathering.user.id.eq(userId)); + + List list = query + .groupBy(gathering.id, gathering.title, zoneCategoryParent.name, zoneCategoryChild.name, + gathering.viewCount, + gatheringCategory.name, gathering.user.nickname, gathering.scheduleStartDate, + gathering.scheduleEndDate, gathering.deadline, gathering.allowedSex, gathering.startAge, + gathering.endAge, gathering.personCount) + .select(Projections.constructor( + GatheringBriefResponse.class, + gathering.id, + gathering.title, + zoneCategoryParent.name, + zoneCategoryChild.name, + gathering.viewCount, + isBookMark, + likeCount, + gatheringCategory.name, + gathering.user.nickname, + gathering.scheduleStartDate, + gathering.scheduleEndDate, + gathering.deadline, + gathering.allowedSex, + gathering.startAge, + gathering.endAge, + gathering.personCount, + gatheringApplicants.count().coalesce(0L).intValue(), + isUserGreatGathering(userId) + )) + .offset(pageable.getOffset()) + .limit(pageable.getPageSize()) + .fetch(); + long total = query.fetchCount(); + + return new PageImpl<>(list, pageable, total); + } + + @Override + public Page retrieveGatheringApplicant(Pageable pageable, Long userId) { + NumberExpression likeCount = countGreatGatheringByGatheringById(); + BooleanExpression isBookMark = isGatheringBookmark(userId); + StringExpression gatheringStatus = getGatheringStatus(); + + JPQLQuery query = from(gathering) + .leftJoin(zoneCategoryParent) + .on(zoneCategoryParent.id.eq(gathering.zoneCategory.parentZoneCategory.id)) + .leftJoin(gatheringCategory) + .on(gatheringCategory.id.eq(gathering.gatheringCategory.id)) + .leftJoin(gatheringApplicants) + .on(gatheringApplicants.gathering.id.eq(gathering.id)) + .leftJoin(gatheringApplicants) + .on(gatheringApplicants.gathering.id.eq(gathering.id)) + .orderBy(gathering.createdAt.desc()) + .where(gatheringApplicants.user.id.eq(userId)); + + List list = query + .groupBy(gathering.id, gathering.title, zoneCategoryParent.name, zoneCategoryChild.name, + gathering.viewCount, + gatheringCategory.name, gathering.user.nickname, gathering.scheduleStartDate, + gathering.scheduleEndDate, gathering.deadline, gathering.allowedSex, gathering.startAge, + gathering.endAge, gathering.personCount, gatheringApplicants.gatheringStatus) + .select(Projections.constructor( + GatheringApplicantResponse.class, + gathering.id, + gathering.title, + zoneCategoryParent.name, + zoneCategoryChild.name, + gathering.viewCount, + isBookMark, + likeCount, + gatheringCategory.name, + gathering.user.nickname, + gathering.scheduleStartDate, + gathering.scheduleEndDate, + gathering.deadline, + gathering.allowedSex, + gathering.startAge, + gathering.endAge, + gathering.personCount, + gatheringApplicants.count().coalesce(0L).intValue(), + isUserGreatGathering(userId), + gatheringStatus + )) + .offset(pageable.getOffset()) + .limit(pageable.getPageSize()) + .fetch(); + long total = query.fetchCount(); + + return new PageImpl<>(list, pageable, total); + } + + private StringExpression getGatheringStatus() { + QGatheringApplicants gatheringApplicants = QGatheringApplicants.gatheringApplicants; + return new CaseBuilder() + .when(gatheringApplicants.gatheringStatus.eq(GatheringStatus.WAIT)) + .then("대기중") + .when(gatheringApplicants.gatheringStatus.eq(GatheringStatus.CONSENT)) + .then("승인됨") + .otherwise("거절됨"); + } + + private NumberExpression countGreatGatheringByGatheringById() { + QGreatGathering greatGatheringSub = QGreatGathering.greatGathering; + JPQLQuery likeCountSubQuery = JPAExpressions + .select(greatGatheringSub.count()) + .from(greatGatheringSub) + .where(greatGatheringSub.gathering.id.eq(gathering.id)); + + return Expressions.numberTemplate(Long.class, "{0}", likeCountSubQuery) + .coalesce(0L) + .intValue(); + } + + private BooleanExpression isUserGreatGathering(Long userId) { + return new CaseBuilder() + .when(JPAExpressions.selectOne() + .from(greatGathering) + .where(greatGathering.gathering.id.eq(gathering.id) + .and(greatGathering.user.id.eq(userId))) + .exists()) + .then(true) + .otherwise(false); + } + + private BooleanExpression isGatheringBookmark(Long userId) { + return new CaseBuilder() + .when(JPAExpressions.selectOne() + .from(bookMarkGathering) + .where(bookMarkGathering.gathering.id.eq(gathering.id) + .and(bookMarkGathering.user.id.eq(userId))) + .exists()) + .then(true) + .otherwise(false); + } + + +} diff --git a/src/main/java/solitour_backend/solitour/user/service/UserService.java b/src/main/java/solitour_backend/solitour/user/service/UserService.java index c6d88367..d69f34ef 100644 --- a/src/main/java/solitour_backend/solitour/user/service/UserService.java +++ b/src/main/java/solitour_backend/solitour/user/service/UserService.java @@ -1,13 +1,21 @@ package solitour_backend.solitour.user.service; import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.multipart.MultipartFile; +import solitour_backend.solitour.gathering.dto.response.GatheringApplicantResponse; +import solitour_backend.solitour.gathering.dto.response.GatheringBriefResponse; +import solitour_backend.solitour.information.dto.response.InformationBriefResponse; import solitour_backend.solitour.user.entity.User; -import solitour_backend.solitour.user.entity.UserRepository; import solitour_backend.solitour.user.exception.NicknameAlreadyExistsException; +import solitour_backend.solitour.user.repository.UserRepository; import solitour_backend.solitour.user.service.dto.response.UserInfoResponse; -import solitour_backend.solitour.user_image.entity.UserImage; +import solitour_backend.solitour.user_image.dto.UserImageResponse; +import solitour_backend.solitour.user_image.entity.UserImageRepository; +import solitour_backend.solitour.user_image.service.UserImageService; @Service @RequiredArgsConstructor @@ -15,6 +23,8 @@ public class UserService { private final UserRepository userRepository; + private final UserImageService userImageService; + private final UserImageRepository userImageRepository; public UserInfoResponse retrieveUserInfo(Long userId) { User user = userRepository.findByUserId(userId); @@ -44,10 +54,30 @@ public void deleteUser(Long userId) { user.deleteUser(userId); } + public Page retrieveInformationOwner(Pageable pageable, Long userId) { + return userRepository.retrieveInformationOwner(pageable, userId); + } + + public Page retrieveInformationBookmark(Pageable pageable, Long userId) { + return userRepository.retrieveInformationBookmark(pageable, userId); + } + @Transactional - public void updateUserImage(Long userId, String updateImage) { + public void updateUserProfile(Long userId, MultipartFile userProfile) { + UserImageResponse response = userImageService.registerInformation(userId, userProfile); User user = userRepository.findByUserId(userId); - UserImage userImage = user.getUserImage(); - userImage.updateUserImage(updateImage); + user.updateUserImage(response.getImageUrl()); + } + + public Page retrieveGatheringHost(Pageable pageable, Long userId) { + return userRepository.retrieveGatheringHost(pageable, userId); + } + + public Page retrieveGatheringBookmark(Pageable pageable, Long userId) { + return userRepository.retrieveGatheringBookmark(pageable, userId); + } + + public Page retrieveGatheringApplicant(Pageable pageable, Long userId) { + return userRepository.retrieveGatheringApplicant(pageable, userId); } } diff --git a/src/main/java/solitour_backend/solitour/user_image/entity/UserImage.java b/src/main/java/solitour_backend/solitour/user_image/entity/UserImage.java index c9c0ac49..7f0d4cce 100644 --- a/src/main/java/solitour_backend/solitour/user_image/entity/UserImage.java +++ b/src/main/java/solitour_backend/solitour/user_image/entity/UserImage.java @@ -32,7 +32,7 @@ public UserImage(String address, LocalDate createdDate) { this.createdDate = createdDate; } - public void updateUserImage(String userImage) { - this.address = userImage; + public void updateUserImage(String imageUrl) { + this.address = imageUrl; } } diff --git a/src/main/java/solitour_backend/solitour/user_image/entity/UserImageRepository.java b/src/main/java/solitour_backend/solitour/user_image/entity/UserImageRepository.java index a15bee77..faf56853 100644 --- a/src/main/java/solitour_backend/solitour/user_image/entity/UserImageRepository.java +++ b/src/main/java/solitour_backend/solitour/user_image/entity/UserImageRepository.java @@ -5,5 +5,4 @@ public interface UserImageRepository extends JpaRepository { UserImage save(UserImage userImage); - } diff --git a/src/main/java/solitour_backend/solitour/user_image/service/UserImageService.java b/src/main/java/solitour_backend/solitour/user_image/service/UserImageService.java index a8de5fc2..2a9496bd 100644 --- a/src/main/java/solitour_backend/solitour/user_image/service/UserImageService.java +++ b/src/main/java/solitour_backend/solitour/user_image/service/UserImageService.java @@ -35,5 +35,4 @@ public UserImageResponse registerInformation(Long userId, MultipartFile userImag return new UserImageResponse(userImageUrl); } - } From 9a3fce9aa8aef2431bda7fd49c91734fa2fc0cee Mon Sep 17 00:00:00 2001 From: Donghun Won Date: Wed, 28 Aug 2024 19:40:03 +0900 Subject: [PATCH 175/371] =?UTF-8?q?Refactor(#110)=20:=20group=20by=20?= =?UTF-8?q?=EC=BF=BC=EB=A6=AC=20=EA=B0=84=EC=86=8C=ED=99=94=20(#112)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Refactor : group by 쿼리 간소화 --- .../user/repository/UserRepositoryImpl.java | 29 +++++++------------ 1 file changed, 10 insertions(+), 19 deletions(-) diff --git a/src/main/java/solitour_backend/solitour/user/repository/UserRepositoryImpl.java b/src/main/java/solitour_backend/solitour/user/repository/UserRepositoryImpl.java index 571bf473..07901250 100644 --- a/src/main/java/solitour_backend/solitour/user/repository/UserRepositoryImpl.java +++ b/src/main/java/solitour_backend/solitour/user/repository/UserRepositoryImpl.java @@ -65,8 +65,8 @@ public Page retrieveInformationOwner(Pageable pageable .where(information.user.id.eq(userId)); List list = query - .groupBy(information.id, information.title, zoneCategoryParent.name, zoneCategoryChild.name, - information.viewCount, bookMarkInformation.user.id, image.address) + .groupBy(information.id, zoneCategoryParent.id, zoneCategoryChild.id, + information.id, bookMarkInformation.id, image.id) .orderBy(information.createdDate.desc()) .select(Projections.constructor( InformationBriefResponse.class, @@ -101,8 +101,8 @@ public Page retrieveInformationBookmark(Pageable pagea .where(information.user.id.eq(userId).and(bookMarkInformation.user.id.eq(userId))); List list = query - .groupBy(information.id, information.title, zoneCategoryParent.name, zoneCategoryChild.name, - information.viewCount, bookMarkInformation.user.id, image.address) + .groupBy(information.id, zoneCategoryParent.id, zoneCategoryChild.id, + information.id, bookMarkInformation.id, image.id) .orderBy(information.createdDate.desc()) .select(Projections.constructor( InformationBriefResponse.class, @@ -140,11 +140,8 @@ public Page retrieveGatheringHost(Pageable pageable, Lon .where(gathering.user.id.eq(userId)); List list = query - .groupBy(gathering.id, gathering.title, zoneCategoryParent.name, zoneCategoryChild.name, - gathering.viewCount, - gatheringCategory.name, gathering.user.nickname, gathering.scheduleStartDate, - gathering.scheduleEndDate, gathering.deadline, gathering.allowedSex, gathering.startAge, - gathering.endAge, gathering.personCount) + .groupBy(gathering.id, zoneCategoryParent.id, zoneCategoryChild.id, + gatheringCategory.id) .select(Projections.constructor( GatheringBriefResponse.class, gathering.id, @@ -192,11 +189,8 @@ public Page retrieveGatheringBookmark(Pageable pageable, .where(bookMarkGathering.user.id.eq(userId)); List list = query - .groupBy(gathering.id, gathering.title, zoneCategoryParent.name, zoneCategoryChild.name, - gathering.viewCount, - gatheringCategory.name, gathering.user.nickname, gathering.scheduleStartDate, - gathering.scheduleEndDate, gathering.deadline, gathering.allowedSex, gathering.startAge, - gathering.endAge, gathering.personCount) + .groupBy(gathering.id, zoneCategoryParent.id, zoneCategoryChild.id, + gatheringCategory.id) .select(Projections.constructor( GatheringBriefResponse.class, gathering.id, @@ -245,11 +239,8 @@ public Page retrieveGatheringApplicant(Pageable page .where(gatheringApplicants.user.id.eq(userId)); List list = query - .groupBy(gathering.id, gathering.title, zoneCategoryParent.name, zoneCategoryChild.name, - gathering.viewCount, - gatheringCategory.name, gathering.user.nickname, gathering.scheduleStartDate, - gathering.scheduleEndDate, gathering.deadline, gathering.allowedSex, gathering.startAge, - gathering.endAge, gathering.personCount, gatheringApplicants.gatheringStatus) + .groupBy(gathering.id, zoneCategoryParent.id, zoneCategoryChild.id, + gatheringCategory.id, gatheringApplicants.id) .select(Projections.constructor( GatheringApplicantResponse.class, gathering.id, From 8192ffa7bc0e2084b7cda6e6e9984fa030f6133c Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Thu, 29 Aug 2024 14:21:32 +0900 Subject: [PATCH 176/371] =?UTF-8?q?refactor:=20=EB=AA=A8=EC=9E=84=20?= =?UTF-8?q?=EC=83=81=ED=83=9C=20return?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../gathering/dto/response/GatheringDetailResponse.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/solitour_backend/solitour/gathering/dto/response/GatheringDetailResponse.java b/src/main/java/solitour_backend/solitour/gathering/dto/response/GatheringDetailResponse.java index fb5243d1..68a3106a 100644 --- a/src/main/java/solitour_backend/solitour/gathering/dto/response/GatheringDetailResponse.java +++ b/src/main/java/solitour_backend/solitour/gathering/dto/response/GatheringDetailResponse.java @@ -2,10 +2,12 @@ import java.time.LocalDateTime; import java.util.List; + import lombok.AllArgsConstructor; import lombok.Getter; import solitour_backend.solitour.gathering.entity.AllowedSex; import solitour_backend.solitour.gathering_applicants.dto.response.GatheringApplicantsResponse; +import solitour_backend.solitour.gathering_applicants.entity.GatheringStatus; import solitour_backend.solitour.gathering_category.dto.response.GatheringCategoryResponse; import solitour_backend.solitour.place.dto.response.PlaceResponse; import solitour_backend.solitour.tag.dto.response.TagResponse; @@ -46,5 +48,5 @@ public class GatheringDetailResponse { private List gatheringRecommend; - private Boolean isApplicants; + private GatheringStatus gatheringStatus; } From 1bc0b6e52637b0bcf0f54d562e37d047f85e08d2 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Thu, 29 Aug 2024 14:22:20 +0900 Subject: [PATCH 177/371] =?UTF-8?q?refactor:=20user=20id=20=ED=95=84?= =?UTF-8?q?=EB=93=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../solitour/user/dto/response/UserGatheringResponse.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/solitour_backend/solitour/user/dto/response/UserGatheringResponse.java b/src/main/java/solitour_backend/solitour/user/dto/response/UserGatheringResponse.java index 7a6aaf9e..b8573ead 100644 --- a/src/main/java/solitour_backend/solitour/user/dto/response/UserGatheringResponse.java +++ b/src/main/java/solitour_backend/solitour/user/dto/response/UserGatheringResponse.java @@ -6,6 +6,7 @@ @Getter @AllArgsConstructor public class UserGatheringResponse { + private Long id; private String profileUrl; private String nickname; private Integer age; From ce8aab072da13d70a8ebc92511a2285f6280944d Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Thu, 29 Aug 2024 14:22:29 +0900 Subject: [PATCH 178/371] refactor: --- .../gathering/service/GatheringService.java | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/src/main/java/solitour_backend/solitour/gathering/service/GatheringService.java b/src/main/java/solitour_backend/solitour/gathering/service/GatheringService.java index 81635f59..88a802c4 100644 --- a/src/main/java/solitour_backend/solitour/gathering/service/GatheringService.java +++ b/src/main/java/solitour_backend/solitour/gathering/service/GatheringService.java @@ -6,6 +6,7 @@ import java.util.ArrayList; import java.util.List; import java.util.Objects; + import lombok.RequiredArgsConstructor; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; @@ -117,16 +118,22 @@ public GatheringDetailResponse getGatheringDetail(Long userId, Long gatheringId) List gatheringApplicantsResponses = null; - boolean isApplicants = gatheringApplicantsRepository.existsByGatheringIdAndUserId(gathering.getId(), userId); +// boolean isApplicants = gatheringApplicantsRepository.existsByGatheringIdAndUserId(gathering.getId(), userId); + + GatheringStatus gatheringStatus = null; + GatheringApplicants gatheringApplicants = gatheringApplicantsRepository.findByGatheringIdAndUserId(gathering.getId(), userId).orElse(null); + + if (Objects.nonNull(gatheringApplicants)) { + gatheringStatus = gatheringApplicants.getGatheringStatus(); + } + if (gathering.getUser().getId().equals(userId)) { gatheringApplicantsResponses = gatheringApplicantsMapper.mapToGatheringApplicantsResponses( - gatheringApplicantsRepository.findAllByGathering_IdAndUserIdNot(gathering.getId(), - gathering.getUser().getId())); + gatheringApplicantsRepository.findAllByGathering_IdAndUserIdNot(gathering.getId(), gathering.getUser().getId())); } - int nowPersonCount = gatheringApplicantsRepository.countAllByGathering_IdAndGatheringStatus(gathering.getId(), - GatheringStatus.CONSENT); + int nowPersonCount = gatheringApplicantsRepository.countAllByGathering_IdAndGatheringStatus(gathering.getId(), GatheringStatus.CONSENT); boolean isLike = greatGatheringRepository.existsByGatheringIdAndUserId(gathering.getId(), userId); @@ -156,7 +163,7 @@ public GatheringDetailResponse getGatheringDetail(Long userId, Long gatheringId) isLike, gatheringApplicantsResponses, gatheringRecommend, - isApplicants + gatheringStatus ); } From bbebe6dfbf59f95489e6418a92a7252b2f6e94f4 Mon Sep 17 00:00:00 2001 From: Donghun Won Date: Thu, 29 Aug 2024 19:17:42 +0900 Subject: [PATCH 179/371] =?UTF-8?q?Feature(#114):=20=EC=A0=95=EB=B3=B4,=20?= =?UTF-8?q?=EB=AA=A8=EC=9E=84=20=ED=95=B4=EC=8B=9C=ED=83=9C=EA=B7=B8=20?= =?UTF-8?q?=EA=B2=80=EC=83=89=20(#115)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Feat : 태그 검색 * Refactor : 마감여부 필드 추가, 가입상태 서술 변경 * Feat : 정보 태그 검색 * Feat: 모임 태그 검색 * Style : 코드 포맷팅 --- .../controller/GatheringController.java | 21 ++++++ .../response/GatheringApplicantResponse.java | 1 + .../repository/GatheringRepositoryCustom.java | 3 + .../repository/GatheringRepositoryImpl.java | 63 ++++++++++++++++- .../gathering/service/GatheringService.java | 9 ++- .../controller/InformationController.java | 21 ++++++ .../request/InformationRegisterRequest.java | 2 + .../InformationRepositoryCustom.java | 4 ++ .../repository/InformationRepositoryImpl.java | 69 +++++++++++++++++++ .../service/InformationService.java | 7 ++ .../user/repository/UserRepositoryImpl.java | 9 +-- 11 files changed, 202 insertions(+), 7 deletions(-) diff --git a/src/main/java/solitour_backend/solitour/gathering/controller/GatheringController.java b/src/main/java/solitour_backend/solitour/gathering/controller/GatheringController.java index 42b8be84..98f920f4 100644 --- a/src/main/java/solitour_backend/solitour/gathering/controller/GatheringController.java +++ b/src/main/java/solitour_backend/solitour/gathering/controller/GatheringController.java @@ -5,6 +5,7 @@ import jakarta.servlet.http.HttpServletRequest; import jakarta.validation.Valid; import java.time.LocalDateTime; +import java.util.Base64; import java.util.List; import java.util.Objects; import lombok.RequiredArgsConstructor; @@ -135,6 +136,26 @@ public ResponseEntity> pageGatheringSortAndFilter( .body(pageGathering); } + @GetMapping("/tag/search") + public ResponseEntity> getPageGatheringByTag( + @RequestParam(defaultValue = "0") int page, + @Valid @ModelAttribute GatheringPageRequest gatheringPageRequest, + @RequestParam(required = false, name = "tagName") String tag, + BindingResult bindingResult, + HttpServletRequest request) { + byte[] decodedBytes = Base64.getUrlDecoder().decode(tag); + String decodedTag = new String(decodedBytes); + + Utils.validationRequest(bindingResult); + Long userId = findUser(request); + Pageable pageable = PageRequest.of(page, PAGE_SIZE); + Page briefGatheringPage = gatheringService.getPageGatheringByTag( + pageable, userId, gatheringPageRequest, decodedTag); + return ResponseEntity + .status(HttpStatus.OK) + .body(briefGatheringPage); + } + @GetMapping("/ranks") public ResponseEntity> getGatheringRankOrderByLikes() { List gatheringRankOrderByLikes = gatheringService.getGatheringRankOrderByLikes(); diff --git a/src/main/java/solitour_backend/solitour/gathering/dto/response/GatheringApplicantResponse.java b/src/main/java/solitour_backend/solitour/gathering/dto/response/GatheringApplicantResponse.java index 33b4a5e4..2dc23990 100644 --- a/src/main/java/solitour_backend/solitour/gathering/dto/response/GatheringApplicantResponse.java +++ b/src/main/java/solitour_backend/solitour/gathering/dto/response/GatheringApplicantResponse.java @@ -32,4 +32,5 @@ public class GatheringApplicantResponse { private Integer nowPersonCount; private Boolean isLike; private String gatheringStatus; + private Boolean isFinish; } diff --git a/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryCustom.java b/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryCustom.java index bee8bc18..ee76daa0 100644 --- a/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryCustom.java +++ b/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryCustom.java @@ -21,4 +21,7 @@ Page getGatheringPageFilterAndOrder(Pageable pageable, List getGatheringRankList(); List getGatheringLikeCountFromCreatedIn3(Long userId); + + Page getPageGatheringByTag(Pageable pageable, GatheringPageRequest gatheringPageRequest, + Long userId, String decodedTag); } diff --git a/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryImpl.java b/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryImpl.java index 298a6309..e85052b7 100644 --- a/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryImpl.java +++ b/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryImpl.java @@ -28,6 +28,7 @@ import solitour_backend.solitour.gathering_applicants.entity.GatheringStatus; import solitour_backend.solitour.gathering_applicants.entity.QGatheringApplicants; import solitour_backend.solitour.gathering_category.entity.QGatheringCategory; +import solitour_backend.solitour.gathering_tag.entity.QGatheringTag; import solitour_backend.solitour.great_gathering.entity.QGreatGathering; import solitour_backend.solitour.zone_category.entity.QZoneCategory; @@ -44,7 +45,7 @@ public GatheringRepositoryImpl() { QGreatGathering greatGathering = QGreatGathering.greatGathering; QGatheringCategory category = QGatheringCategory.gatheringCategory; QGatheringApplicants gatheringApplicants = QGatheringApplicants.gatheringApplicants; - + QGatheringTag gatheringTag = QGatheringTag.gatheringTag; @Override public List getGatheringRecommend(Long gatheringId, Long gatheringCategoryId, Long userId) { @@ -152,6 +153,65 @@ public Page getGatheringPageFilterAndOrder(Pageable page return new PageImpl<>(content, pageable, total); } + @Override + public Page getPageGatheringByTag(Pageable pageable, + GatheringPageRequest gatheringPageRequest, Long userId, + String decodedTag) { + BooleanBuilder booleanBuilder = makeWhereSQL(gatheringPageRequest); + + OrderSpecifier orderSpecifier = getOrderSpecifier(gatheringPageRequest.getSort()); + + NumberExpression countGreatGathering = countGreatGatheringByGatheringById(); + + long total = from(gathering) + .join(zoneCategoryChild).on(zoneCategoryChild.id.eq(gathering.zoneCategory.id)) + .leftJoin(zoneCategoryParent).on(zoneCategoryParent.id.eq(zoneCategoryChild.parentZoneCategory.id)) + .leftJoin(bookMarkGathering) + .on(bookMarkGathering.gathering.id.eq(gathering.id).and(bookMarkGathering.user.id.eq(userId))) + .leftJoin(gatheringApplicants).on(gatheringApplicants.gathering.id.eq(gathering.id)) + .leftJoin(gatheringTag) + .on(gatheringTag.gathering.id.eq(gathering.id).and(gatheringTag.tag.name.eq(decodedTag))) + .where(booleanBuilder.and(gatheringTag.tag.name.eq(decodedTag))) + .select(gathering.id.count()).fetchCount(); + + List content = from(gathering) + .join(zoneCategoryChild).on(zoneCategoryChild.id.eq(gathering.zoneCategory.id)) + .leftJoin(zoneCategoryParent).on(zoneCategoryParent.id.eq(zoneCategoryChild.parentZoneCategory.id)) + .leftJoin(bookMarkGathering) + .on(bookMarkGathering.gathering.id.eq(gathering.id).and(bookMarkGathering.user.id.eq(userId))) + .leftJoin(gatheringApplicants).on(gatheringApplicants.gathering.id.eq(gathering.id)) + .leftJoin(gatheringTag) + .on(gatheringTag.gathering.id.eq(gathering.id).and(gatheringTag.tag.name.eq(decodedTag))) + .where(booleanBuilder.and(gatheringTag.tag.name.eq(decodedTag))) + .groupBy(gathering.id, zoneCategoryChild.id, zoneCategoryParent.id, category.id) + .orderBy(orderSpecifier) + .select(Projections.constructor( + GatheringBriefResponse.class, + gathering.id, + gathering.title, + zoneCategoryParent.name, + zoneCategoryChild.name, + gathering.viewCount, + bookMarkGathering.user.id.isNotNull(), + countGreatGathering, + gathering.gatheringCategory.name, + gathering.user.name, + gathering.scheduleStartDate, + gathering.scheduleEndDate, + gathering.deadline, + gathering.allowedSex, + gathering.startAge, + gathering.endAge, + gathering.personCount, + gatheringApplicants.count().coalesce(0L).intValue(), + isUserGreatGathering(userId) + )) + .offset(pageable.getOffset()) + .limit(pageable.getPageSize()) + .fetch(); + + return new PageImpl<>(content, pageable, total); + } @Override public List getGatheringRankList() { @@ -211,7 +271,6 @@ public List getGatheringLikeCountFromCreatedIn3(Long use )).limit(6).fetch(); } - //where 절 private BooleanBuilder makeWhereSQL(GatheringPageRequest gatheringPageRequest) { BooleanBuilder whereClause = new BooleanBuilder(); diff --git a/src/main/java/solitour_backend/solitour/gathering/service/GatheringService.java b/src/main/java/solitour_backend/solitour/gathering/service/GatheringService.java index 88a802c4..206f91c4 100644 --- a/src/main/java/solitour_backend/solitour/gathering/service/GatheringService.java +++ b/src/main/java/solitour_backend/solitour/gathering/service/GatheringService.java @@ -333,6 +333,14 @@ public Page getPageGathering(Pageable pageable, Gatherin return gatheringRepository.getGatheringPageFilterAndOrder(pageable, gatheringPageRequest, userId); } + public Page getPageGatheringByTag(Pageable pageable, Long userId, + GatheringPageRequest gatheringPageRequest, + String decodedTag) { + validateGatheringPageRequest(gatheringPageRequest); + + return gatheringRepository.getPageGatheringByTag(pageable, gatheringPageRequest, userId, decodedTag); + } + public List getGatheringRankOrderByLikes() { return gatheringRepository.getGatheringRankList(); } @@ -388,5 +396,4 @@ private void validateGatheringPageRequest(GatheringPageRequest gatheringPageRequ } } - } \ No newline at end of file diff --git a/src/main/java/solitour_backend/solitour/information/controller/InformationController.java b/src/main/java/solitour_backend/solitour/information/controller/InformationController.java index 50b69069..9f09aa29 100644 --- a/src/main/java/solitour_backend/solitour/information/controller/InformationController.java +++ b/src/main/java/solitour_backend/solitour/information/controller/InformationController.java @@ -3,6 +3,7 @@ import jakarta.servlet.http.HttpServletRequest; import jakarta.validation.Valid; +import java.util.Base64; import java.util.List; import java.util.Objects; import lombok.RequiredArgsConstructor; @@ -121,6 +122,26 @@ public ResponseEntity> pageInformationSortAndFilt .body(pageInformation); } + @GetMapping("/tag/search") + public ResponseEntity> getPageInformationByTag( + @RequestParam(defaultValue = "0") int page, + @RequestParam(defaultValue = "1") Long parentCategoryId, + @Valid @ModelAttribute InformationPageRequest informationPageRequest, + @RequestParam(required = false, name = "tagName") String tag, + BindingResult bindingResult, + HttpServletRequest request) { + byte[] decodedBytes = Base64.getUrlDecoder().decode(tag); + String decodedTag = new String(decodedBytes); + + Utils.validationRequest(bindingResult); + Long userId = findUser(request); + Pageable pageable = PageRequest.of(page, PAGE_SIZE); + Page briefInformationPage = informationService.getPageInformationByTag( + pageable, userId, parentCategoryId, informationPageRequest, decodedTag); + return ResponseEntity + .status(HttpStatus.OK) + .body(briefInformationPage); + } @GetMapping("/ranks") public ResponseEntity> rankInformation() { diff --git a/src/main/java/solitour_backend/solitour/information/dto/request/InformationRegisterRequest.java b/src/main/java/solitour_backend/solitour/information/dto/request/InformationRegisterRequest.java index 64c4d73e..75fe1ad2 100644 --- a/src/main/java/solitour_backend/solitour/information/dto/request/InformationRegisterRequest.java +++ b/src/main/java/solitour_backend/solitour/information/dto/request/InformationRegisterRequest.java @@ -5,12 +5,14 @@ import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.Size; import java.util.List; +import lombok.AllArgsConstructor; import lombok.Getter; import lombok.NoArgsConstructor; import solitour_backend.solitour.place.dto.request.PlaceRegisterRequest; import solitour_backend.solitour.tag.dto.request.TagRegisterRequest; @Getter +@AllArgsConstructor @NoArgsConstructor public class InformationRegisterRequest { diff --git a/src/main/java/solitour_backend/solitour/information/repository/InformationRepositoryCustom.java b/src/main/java/solitour_backend/solitour/information/repository/InformationRepositoryCustom.java index 84d6bde0..4100ea69 100644 --- a/src/main/java/solitour_backend/solitour/information/repository/InformationRepositoryCustom.java +++ b/src/main/java/solitour_backend/solitour/information/repository/InformationRepositoryCustom.java @@ -24,4 +24,8 @@ Page getInformationPageFilterAndOrder(Pageable pageabl List getInformationLikeCountFromCreatedIn3(Long userId); List getInformationRecommend(Long informationId, Long childCategoryId, Long userId); + + Page getInformationPageByTag(Pageable pageable, Long userId, Long parentCategoryId, + InformationPageRequest informationPageRequest, + String decodedTag); } diff --git a/src/main/java/solitour_backend/solitour/information/repository/InformationRepositoryImpl.java b/src/main/java/solitour_backend/solitour/information/repository/InformationRepositoryImpl.java index e95fc2f1..b8dc83f1 100644 --- a/src/main/java/solitour_backend/solitour/information/repository/InformationRepositoryImpl.java +++ b/src/main/java/solitour_backend/solitour/information/repository/InformationRepositoryImpl.java @@ -21,6 +21,7 @@ import solitour_backend.solitour.great_information.entity.QGreatInformation; import solitour_backend.solitour.image.entity.QImage; import solitour_backend.solitour.image.image_status.ImageStatus; +import solitour_backend.solitour.info_tag.entity.QInfoTag; import solitour_backend.solitour.information.dto.request.InformationPageRequest; import solitour_backend.solitour.information.dto.response.InformationBriefResponse; import solitour_backend.solitour.information.dto.response.InformationMainResponse; @@ -42,6 +43,7 @@ public InformationRepositoryImpl() { QImage image = QImage.image; QGreatInformation greatInformation = QGreatInformation.greatInformation; QCategory category = QCategory.category; + QInfoTag infoTag = QInfoTag.infoTag; @Override @@ -169,6 +171,73 @@ public List getInformationRecommend(Long informationId .fetch(); } + @Override + public Page getInformationPageByTag(Pageable pageable, Long userId, Long parentCategoryId, + InformationPageRequest informationPageRequest, + String decodedTag) { + BooleanBuilder whereClause = new BooleanBuilder(); + + if (Objects.nonNull(informationPageRequest.getZoneCategoryId())) { + whereClause.and( + information.zoneCategory.parentZoneCategory.id.eq(informationPageRequest.getZoneCategoryId())); + } + + BooleanBuilder categoryCondition = new BooleanBuilder(); + + if (Objects.nonNull(informationPageRequest.getChildCategoryId())) { + whereClause.and(information.category.id.eq(informationPageRequest.getChildCategoryId())); + } else { + categoryCondition.and(category.parentCategory.id.eq(parentCategoryId)); + } + + OrderSpecifier orderSpecifier = getOrderSpecifier(informationPageRequest.getSort()); + NumberExpression countGreatInformation = countGreatInformationByInformationById(); + + long total = from(information) + .join(zoneCategoryChild).on(zoneCategoryChild.id.eq(information.zoneCategory.id)) + .leftJoin(zoneCategoryParent).on(zoneCategoryParent.id.eq(zoneCategoryChild.parentZoneCategory.id)) + .leftJoin(bookMarkInformation) + .on(bookMarkInformation.information.id.eq(information.id).and(bookMarkInformation.user.id.eq(userId))) + .leftJoin(image) + .on(image.information.id.eq(information.id).and(image.imageStatus.eq(ImageStatus.THUMBNAIL))) + .join(category).on(category.id.eq(information.category.id).and(categoryCondition)) + .leftJoin(infoTag) + .on(infoTag.information.id.eq(information.id)) + .where(whereClause.and(infoTag.information.id.eq(information.id).and(infoTag.tag.name.eq(decodedTag)))) + .select(information.count()).fetchCount(); + + List list = from(information) + .join(zoneCategoryChild).on(zoneCategoryChild.id.eq(information.zoneCategory.id)) + .leftJoin(zoneCategoryParent).on(zoneCategoryParent.id.eq(zoneCategoryChild.parentZoneCategory.id)) + .leftJoin(bookMarkInformation) + .on(bookMarkInformation.information.id.eq(information.id).and(bookMarkInformation.user.id.eq(userId))) + .leftJoin(image) + .on(image.information.id.eq(information.id).and(image.imageStatus.eq(ImageStatus.THUMBNAIL))) + .join(category).on(category.id.eq(information.category.id).and(categoryCondition)) + .leftJoin(greatInformation).on(greatInformation.information.id.eq(information.id)) + .leftJoin(infoTag) + .on(infoTag.information.id.eq(information.id)) + .where(whereClause) + .groupBy(information.id, zoneCategoryChild.id, zoneCategoryParent.id, image.id, infoTag.id) + .orderBy(orderSpecifier) + .select(Projections.constructor( + InformationBriefResponse.class, + information.id, + information.title, + zoneCategoryParent.name, + zoneCategoryChild.name, + information.viewCount, + bookMarkInformation.user.id.isNotNull(), + image.address, + countGreatInformation, + isUserGreatInformation(userId) + )).offset(pageable.getOffset()) + .limit(pageable.getPageSize()) + .fetch(); + + return new PageImpl<>(list, pageable, total); + } + @Override public List getInformationRank() { return from(information) diff --git a/src/main/java/solitour_backend/solitour/information/service/InformationService.java b/src/main/java/solitour_backend/solitour/information/service/InformationService.java index 8d91cdf5..98f499dc 100644 --- a/src/main/java/solitour_backend/solitour/information/service/InformationService.java +++ b/src/main/java/solitour_backend/solitour/information/service/InformationService.java @@ -389,4 +389,11 @@ public List getRankInformation() { public List getMainPageInformation(Long userId) { return informationRepository.getInformationLikeCountFromCreatedIn3(userId); } + + public Page getPageInformationByTag(Pageable pageable, Long userId, Long parentCategoryId, + InformationPageRequest informationPageRequest, + String decodedTag) { + return informationRepository.getInformationPageByTag(pageable, userId, parentCategoryId, informationPageRequest, + decodedTag); + } } diff --git a/src/main/java/solitour_backend/solitour/user/repository/UserRepositoryImpl.java b/src/main/java/solitour_backend/solitour/user/repository/UserRepositoryImpl.java index 07901250..44d8ad84 100644 --- a/src/main/java/solitour_backend/solitour/user/repository/UserRepositoryImpl.java +++ b/src/main/java/solitour_backend/solitour/user/repository/UserRepositoryImpl.java @@ -261,7 +261,8 @@ public Page retrieveGatheringApplicant(Pageable page gathering.personCount, gatheringApplicants.count().coalesce(0L).intValue(), isUserGreatGathering(userId), - gatheringStatus + gatheringStatus, + gathering.isFinish )) .offset(pageable.getOffset()) .limit(pageable.getPageSize()) @@ -275,10 +276,10 @@ private StringExpression getGatheringStatus() { QGatheringApplicants gatheringApplicants = QGatheringApplicants.gatheringApplicants; return new CaseBuilder() .when(gatheringApplicants.gatheringStatus.eq(GatheringStatus.WAIT)) - .then("대기중") + .then("WAIT") .when(gatheringApplicants.gatheringStatus.eq(GatheringStatus.CONSENT)) - .then("승인됨") - .otherwise("거절됨"); + .then("CONSENT") + .otherwise("REFUSE"); } private NumberExpression countGreatGatheringByGatheringById() { From 2654559394b39f94bf8c1c8a1951e49c9d48fbac Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Fri, 30 Aug 2024 01:13:51 +0900 Subject: [PATCH 180/371] =?UTF-8?q?feat:=20=EB=AA=A8=EC=9E=84=20=EC=83=81?= =?UTF-8?q?=ED=83=9C=EB=A5=BC=20=EC=99=84=EB=A3=8C=EB=A1=9C=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD=20=ED=95=98=EA=B1=B0=EB=82=98=20=EC=99=84=EB=A3=8C?= =?UTF-8?q?=ED=95=98=EC=A7=80=20=EC=95=8A=EC=95=98=EB=8B=A4=EB=A1=9C=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD=20=ED=95=A0=EB=95=8C=20=EC=9D=B4=EB=AF=B8=20?= =?UTF-8?q?=EA=B7=B8=20=EC=83=81=ED=83=9C=EC=9D=BC=EB=95=8C=20=EB=B0=9C?= =?UTF-8?q?=EC=83=9D=ED=95=98=EB=8A=94=20exception?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../exception/GatheringFinishConflictException.java | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 src/main/java/solitour_backend/solitour/gathering/exception/GatheringFinishConflictException.java diff --git a/src/main/java/solitour_backend/solitour/gathering/exception/GatheringFinishConflictException.java b/src/main/java/solitour_backend/solitour/gathering/exception/GatheringFinishConflictException.java new file mode 100644 index 00000000..17aed37d --- /dev/null +++ b/src/main/java/solitour_backend/solitour/gathering/exception/GatheringFinishConflictException.java @@ -0,0 +1,7 @@ +package solitour_backend.solitour.gathering.exception; + +public class GatheringFinishConflictException extends RuntimeException { + public GatheringFinishConflictException(String message) { + super(message); + } +} From 6892cc6ddb7f026ebb4840d1119d5edf22ab6c93 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Fri, 30 Aug 2024 01:15:18 +0900 Subject: [PATCH 181/371] =?UTF-8?q?feat:=20=EB=AA=A8=EC=9E=84=20=EC=83=81?= =?UTF-8?q?=ED=83=9C=EB=A5=BC=20=EC=99=84=EB=A3=8C=EB=A1=9C=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD=20=ED=95=98=EA=B1=B0=EB=82=98=20=EC=99=84=EB=A3=8C?= =?UTF-8?q?=ED=95=98=EC=A7=80=20=EC=95=8A=EC=95=98=EB=8B=A4=EB=A1=9C=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD=20service?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../gathering/service/GatheringService.java | 52 ++++++++++++++++++- 1 file changed, 50 insertions(+), 2 deletions(-) diff --git a/src/main/java/solitour_backend/solitour/gathering/service/GatheringService.java b/src/main/java/solitour_backend/solitour/gathering/service/GatheringService.java index 206f91c4..3836b440 100644 --- a/src/main/java/solitour_backend/solitour/gathering/service/GatheringService.java +++ b/src/main/java/solitour_backend/solitour/gathering/service/GatheringService.java @@ -24,6 +24,7 @@ import solitour_backend.solitour.gathering.entity.Gathering; import solitour_backend.solitour.gathering.exception.GatheringCategoryNotExistsException; import solitour_backend.solitour.gathering.exception.GatheringDeleteException; +import solitour_backend.solitour.gathering.exception.GatheringFinishConflictException; import solitour_backend.solitour.gathering.exception.GatheringNotExistsException; import solitour_backend.solitour.gathering.repository.GatheringRepository; import solitour_backend.solitour.gathering_applicants.dto.mapper.GatheringApplicantsMapper; @@ -349,6 +350,54 @@ public List getGatheringOrderByLikesFilterByCreate3After return gatheringRepository.getGatheringLikeCountFromCreatedIn3(userId); } + public void setGatheringFinish(Long userId, Long gatheringId) { + Gathering gathering = gatheringRepository.findById(gatheringId) + .orElseThrow( + () -> new GatheringNotExistsException("해당하는 id의 gathering 이 존재 하지 않습니다")); + + User user = userRepository.findById(userId) + .orElseThrow( + () -> new UserNotExistsException("해당하는 id의 User 가 없습니다")); + + if (!Objects.equals(user, gathering.getUser())) { + throw new GatheringNotManagerException("해당 유저는 권한이 없습니다"); + } + + if (Boolean.TRUE.equals(gathering.getIsDeleted())) { + throw new GatheringDeleteException("해당 하는 모임은 삭제된 모임입니다"); + } + + if (Boolean.TRUE.equals(gathering.getIsFinish())) { + throw new GatheringFinishConflictException("이미 모임이 finish 상태입니다"); + } + + gathering.setIsFinish(true); + } + + public void setGatheringNotFinish(Long userId, Long gatheringId) { + Gathering gathering = gatheringRepository.findById(gatheringId) + .orElseThrow( + () -> new GatheringNotExistsException("해당하는 id의 gathering 이 존재 하지 않습니다")); + + User user = userRepository.findById(userId) + .orElseThrow( + () -> new UserNotExistsException("해당하는 id의 User 가 없습니다")); + + if (!Objects.equals(user, gathering.getUser())) { + throw new GatheringNotManagerException("해당 유저는 권한이 없습니다"); + } + + if (Boolean.TRUE.equals(gathering.getIsDeleted())) { + throw new GatheringDeleteException("해당 하는 모임은 삭제된 모임입니다"); + } + + if (Boolean.FALSE.equals(gathering.getIsFinish())) { + throw new GatheringFinishConflictException("이미 모임이 not finish 상태입니다"); + } + + gathering.setIsFinish(false); + } + private void validateGatheringPageRequest(GatheringPageRequest gatheringPageRequest) { // Category 검증 @@ -377,8 +426,7 @@ private void validateGatheringPageRequest(GatheringPageRequest gatheringPageRequ // 정렬 방식 검증 if (Objects.nonNull(gatheringPageRequest.getSort())) { - if (!LIKE_COUNT_SORT.equals(gatheringPageRequest.getSort()) && !VIEW_COUNT_SORT.equals( - gatheringPageRequest.getSort())) { + if (!LIKE_COUNT_SORT.equals(gatheringPageRequest.getSort()) && !VIEW_COUNT_SORT.equals(gatheringPageRequest.getSort())) { throw new RequestValidationFailedException("잘못된 정렬 코드입니다."); } } From 4e1c4226371596e4fe18deb104386d9d98ab6cf8 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Fri, 30 Aug 2024 01:15:44 +0900 Subject: [PATCH 182/371] =?UTF-8?q?feat:=20=EB=AA=A8=EC=9E=84=20=EC=83=81?= =?UTF-8?q?=ED=83=9C=EB=A5=BC=20=EC=99=84=EB=A3=8C=EB=A1=9C=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD=20=ED=95=98=EA=B1=B0=EB=82=98=20=EC=99=84=EB=A3=8C?= =?UTF-8?q?=ED=95=98=EC=A7=80=20=EC=95=8A=EC=95=98=EB=8B=A4=EB=A1=9C=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD=20controller?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/GatheringController.java | 46 +++++++++++++------ 1 file changed, 32 insertions(+), 14 deletions(-) diff --git a/src/main/java/solitour_backend/solitour/gathering/controller/GatheringController.java b/src/main/java/solitour_backend/solitour/gathering/controller/GatheringController.java index 98f920f4..d0b8dc58 100644 --- a/src/main/java/solitour_backend/solitour/gathering/controller/GatheringController.java +++ b/src/main/java/solitour_backend/solitour/gathering/controller/GatheringController.java @@ -4,10 +4,12 @@ import jakarta.servlet.http.HttpServletRequest; import jakarta.validation.Valid; + import java.time.LocalDateTime; import java.util.Base64; import java.util.List; import java.util.Objects; + import lombok.RequiredArgsConstructor; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; @@ -119,11 +121,10 @@ public ResponseEntity deleteGathering(@PathVariable Long gatheringId, Http @GetMapping - public ResponseEntity> pageGatheringSortAndFilter( - @RequestParam(defaultValue = "0") int page, - @Valid @ModelAttribute GatheringPageRequest gatheringPageRequest, - BindingResult bindingResult, - HttpServletRequest request) { + public ResponseEntity> pageGatheringSortAndFilter(@RequestParam(defaultValue = "0") int page, + @Valid @ModelAttribute GatheringPageRequest gatheringPageRequest, + BindingResult bindingResult, + HttpServletRequest request) { Utils.validationRequest(bindingResult); Long userId = findUser(request); @@ -137,20 +138,18 @@ public ResponseEntity> pageGatheringSortAndFilter( } @GetMapping("/tag/search") - public ResponseEntity> getPageGatheringByTag( - @RequestParam(defaultValue = "0") int page, - @Valid @ModelAttribute GatheringPageRequest gatheringPageRequest, - @RequestParam(required = false, name = "tagName") String tag, - BindingResult bindingResult, - HttpServletRequest request) { + public ResponseEntity> getPageGatheringByTag(@RequestParam(defaultValue = "0") int page, + @Valid @ModelAttribute GatheringPageRequest gatheringPageRequest, + @RequestParam(required = false, name = "tagName") String tag, + BindingResult bindingResult, + HttpServletRequest request) { byte[] decodedBytes = Base64.getUrlDecoder().decode(tag); String decodedTag = new String(decodedBytes); Utils.validationRequest(bindingResult); Long userId = findUser(request); Pageable pageable = PageRequest.of(page, PAGE_SIZE); - Page briefGatheringPage = gatheringService.getPageGatheringByTag( - pageable, userId, gatheringPageRequest, decodedTag); + Page briefGatheringPage = gatheringService.getPageGatheringByTag(pageable, userId, gatheringPageRequest, decodedTag); return ResponseEntity .status(HttpStatus.OK) .body(briefGatheringPage); @@ -165,6 +164,26 @@ public ResponseEntity> getGatheringRankOrderByLikes( .body(gatheringRankOrderByLikes); } + @PutMapping("/finish/{gatheringId}") + public ResponseEntity gatheringFinish(@AuthenticationPrincipal Long userId, + @PathVariable Long gatheringId) { + gatheringService.setGatheringFinish(userId, gatheringId); + return ResponseEntity + .status(HttpStatus.NO_CONTENT) + .build(); + } + + @PutMapping("/not-finish/{gatheringId}") + public ResponseEntity gatheringNotFinish(@AuthenticationPrincipal Long userId, + @PathVariable Long gatheringId) { + gatheringService.setGatheringNotFinish(userId, gatheringId); + + return ResponseEntity + .status(HttpStatus.NO_CONTENT) + .build(); + } + + @GetMapping("/home") public ResponseEntity> getHomeGathering(HttpServletRequest request) { Long userId = findUser(request); @@ -177,7 +196,6 @@ public ResponseEntity> getHomeGathering(HttpServlet .body(gatheringOrderByLikesFilterByCreate3After); } - private Long findUser(HttpServletRequest request) { String token = CookieExtractor.findToken("access_token", request.getCookies()); From 5e20b0992b5bc23292812e6bd24f17b037883820 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Fri, 30 Aug 2024 01:16:03 +0900 Subject: [PATCH 183/371] =?UTF-8?q?fix:=20validation=20if=20=EB=AC=B8=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 --- .../solitour/information/service/InformationService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/solitour_backend/solitour/information/service/InformationService.java b/src/main/java/solitour_backend/solitour/information/service/InformationService.java index 98f499dc..821c6089 100644 --- a/src/main/java/solitour_backend/solitour/information/service/InformationService.java +++ b/src/main/java/solitour_backend/solitour/information/service/InformationService.java @@ -372,7 +372,7 @@ public Page getPageInformation(Pageable pageable, Long } if (Objects.nonNull(informationPageRequest.getSort())) { - if (!Objects.equals(LIKE_COUNT_SORT, informationPageRequest.getSort()) || !Objects.equals(VIEW_COUNT_SORT, + if (!Objects.equals(LIKE_COUNT_SORT, informationPageRequest.getSort()) && !Objects.equals(VIEW_COUNT_SORT, informationPageRequest.getSort())) { throw new RequestValidationFailedException("잘못된 정렬 코드입니다."); } From 4554af3ca705b96a85e905fd4bf0d9e6763a62d9 Mon Sep 17 00:00:00 2001 From: Donghun Won Date: Fri, 30 Aug 2024 13:00:14 +0900 Subject: [PATCH 184/371] =?UTF-8?q?Feat(#114)=20:=20=ED=83=9C=EA=B7=B8=20?= =?UTF-8?q?=EA=B2=80=EC=83=89=20=ED=95=84=ED=84=B0=20=20(#118)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Refactor : 태그 필터 추가 공백, 특수문자 제거 한글, 영어, 숫자만 허용 --- .../solitour/gathering/controller/GatheringController.java | 3 ++- .../solitour/information/controller/InformationController.java | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/main/java/solitour_backend/solitour/gathering/controller/GatheringController.java b/src/main/java/solitour_backend/solitour/gathering/controller/GatheringController.java index d0b8dc58..73918250 100644 --- a/src/main/java/solitour_backend/solitour/gathering/controller/GatheringController.java +++ b/src/main/java/solitour_backend/solitour/gathering/controller/GatheringController.java @@ -145,11 +145,12 @@ public ResponseEntity> getPageGatheringByTag(@Reque HttpServletRequest request) { byte[] decodedBytes = Base64.getUrlDecoder().decode(tag); String decodedTag = new String(decodedBytes); + String filteredTag = decodedTag.replaceAll("[^a-zA-Z0-9가-힣]", ""); Utils.validationRequest(bindingResult); Long userId = findUser(request); Pageable pageable = PageRequest.of(page, PAGE_SIZE); - Page briefGatheringPage = gatheringService.getPageGatheringByTag(pageable, userId, gatheringPageRequest, decodedTag); + Page briefGatheringPage = gatheringService.getPageGatheringByTag(pageable, userId, gatheringPageRequest, filteredTag); return ResponseEntity .status(HttpStatus.OK) .body(briefGatheringPage); diff --git a/src/main/java/solitour_backend/solitour/information/controller/InformationController.java b/src/main/java/solitour_backend/solitour/information/controller/InformationController.java index 9f09aa29..2702baaa 100644 --- a/src/main/java/solitour_backend/solitour/information/controller/InformationController.java +++ b/src/main/java/solitour_backend/solitour/information/controller/InformationController.java @@ -132,12 +132,13 @@ public ResponseEntity> getPageInformationByTag( HttpServletRequest request) { byte[] decodedBytes = Base64.getUrlDecoder().decode(tag); String decodedTag = new String(decodedBytes); + String filteredTag = decodedTag.replaceAll("[^a-zA-Z0-9가-힣]", ""); Utils.validationRequest(bindingResult); Long userId = findUser(request); Pageable pageable = PageRequest.of(page, PAGE_SIZE); Page briefInformationPage = informationService.getPageInformationByTag( - pageable, userId, parentCategoryId, informationPageRequest, decodedTag); + pageable, userId, parentCategoryId, informationPageRequest, filteredTag); return ResponseEntity .status(HttpStatus.OK) .body(briefInformationPage); From 78b45bd3d895ea1258658d185edd49a7d1eb86a4 Mon Sep 17 00:00:00 2001 From: Donghun Won Date: Fri, 30 Aug 2024 23:02:26 +0900 Subject: [PATCH 185/371] =?UTF-8?q?Feature(#119):=20=ED=9A=8C=EC=9B=90?= =?UTF-8?q?=EA=B0=80=EC=9E=85=20=EC=A4=91=EB=B3=B5=20=EA=B2=80=EC=A6=9D=20?= =?UTF-8?q?(#120)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Refactor : 유저 아이디 중복 검증 --- .../solitour/auth/service/OauthService.java | 8 ++++---- .../solitour/user/repository/UserRepository.java | 3 +++ 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/main/java/solitour_backend/solitour/auth/service/OauthService.java b/src/main/java/solitour_backend/solitour/auth/service/OauthService.java index 298dcdf9..8c806920 100644 --- a/src/main/java/solitour_backend/solitour/auth/service/OauthService.java +++ b/src/main/java/solitour_backend/solitour/auth/service/OauthService.java @@ -79,15 +79,15 @@ private User checkAndSaveUser(String type, String code, String redirectUrl) { if (Objects.equals(type, "kakao")) { KakaoUserResponse response = kakaoConnector.requestKakaoUserInfo(code, redirectUrl) .getBody(); - String nickname = response.getKakaoAccount().getProfile().getNickName(); - return userRepository.findByNickname(nickname) + String id = response.getId().toString(); + return userRepository.findByOauthId(id) .orElseGet(() -> saveKakaoUser(response)); } if (Objects.equals(type, "google")) { GoogleUserResponse response = googleConnector.requestGoogleUserInfo(code, redirectUrl) .getBody(); - String email = response.getEmailAddresses().get(0).getValue(); - return userRepository.findByEmail(email) + String id = response.getResourceName(); + return userRepository.findByOauthId(id) .orElseGet(() -> saveGoogleUser(response)); } else { throw new RuntimeException("지원하지 않는 oauth 타입입니다."); diff --git a/src/main/java/solitour_backend/solitour/user/repository/UserRepository.java b/src/main/java/solitour_backend/solitour/user/repository/UserRepository.java index 804da6f9..12b784ae 100644 --- a/src/main/java/solitour_backend/solitour/user/repository/UserRepository.java +++ b/src/main/java/solitour_backend/solitour/user/repository/UserRepository.java @@ -16,5 +16,8 @@ public interface UserRepository extends JpaRepository, UserRepositor @Query("SELECT u FROM User u JOIN FETCH u.userImage WHERE u.id = :userId AND u.userStatus = '활성화'") User findByUserId(Long userId); + @Query("SELECT u FROM User u JOIN FETCH u.userImage WHERE u.oauthId = :oauthId AND u.userStatus = '활성화'") + Optional findByOauthId(String oauthId); + boolean existsByNickname(String nickname); } From d48319c4c09c95bc576480e0bea4ac1d1b69b183 Mon Sep 17 00:00:00 2001 From: Donghun Won Date: Fri, 30 Aug 2024 23:15:08 +0900 Subject: [PATCH 186/371] =?UTF-8?q?Feature(#121)=20:=20=EC=9D=B4=EB=AF=B8?= =?UTF-8?q?=EC=A7=80=20=EC=97=85=EB=A1=9C=EB=93=9C=20=EB=A1=9C=EC=A7=81=20?= =?UTF-8?q?=EC=88=98=EC=A0=95=20(#122)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Refactor : 이미지 업로드 로직 수정 --- .../image/controller/ImageController.java | 6 ++--- .../image/dto/response/ImageResponse.java | 2 -- .../solitour/image/service/ImageService.java | 24 +++---------------- 3 files changed, 5 insertions(+), 27 deletions(-) diff --git a/src/main/java/solitour_backend/solitour/image/controller/ImageController.java b/src/main/java/solitour_backend/solitour/image/controller/ImageController.java index 0952cf7d..aac42873 100644 --- a/src/main/java/solitour_backend/solitour/image/controller/ImageController.java +++ b/src/main/java/solitour_backend/solitour/image/controller/ImageController.java @@ -26,10 +26,8 @@ public class ImageController { @PostMapping public ResponseEntity uploadImage(@AuthenticationPrincipal Long userId, @RequestPart("image") MultipartFile userImage, - @RequestParam String type, - @RequestParam String imageStatus) { - ImageResponse imageResponse = imageService.uploadImage(userId, userImage, type, - imageStatus); + @RequestParam String type) { + ImageResponse imageResponse = imageService.uploadImage(userId, userImage, type); return ResponseEntity .status(HttpStatus.CREATED) diff --git a/src/main/java/solitour_backend/solitour/image/dto/response/ImageResponse.java b/src/main/java/solitour_backend/solitour/image/dto/response/ImageResponse.java index 3a6f81db..c383b546 100644 --- a/src/main/java/solitour_backend/solitour/image/dto/response/ImageResponse.java +++ b/src/main/java/solitour_backend/solitour/image/dto/response/ImageResponse.java @@ -6,7 +6,5 @@ @Getter @AllArgsConstructor public class ImageResponse { - - private String imageStatus; private String address; } \ No newline at end of file diff --git a/src/main/java/solitour_backend/solitour/image/service/ImageService.java b/src/main/java/solitour_backend/solitour/image/service/ImageService.java index 7f1b6764..b41ff61c 100644 --- a/src/main/java/solitour_backend/solitour/image/service/ImageService.java +++ b/src/main/java/solitour_backend/solitour/image/service/ImageService.java @@ -17,31 +17,13 @@ @Service public class ImageService { - private final UserImageRepository userImageRepository; - private final ImageRepository imageRepository; private final S3Uploader s3Uploader; @Transactional - public ImageResponse uploadImage(Long id, MultipartFile image, String type, String imageStatus) { + public ImageResponse uploadImage(Long id, MultipartFile image, String type) { String imageUrl = s3Uploader.upload(image, type, id); - ImageStatus status = checkImageStatus(imageStatus); - Image contentImage = new Image(status, imageUrl, LocalDate.now()); - imageRepository.save(contentImage); - return new ImageResponse(contentImage.getImageStatus().getName(), contentImage.getAddress()); - } - private ImageStatus checkImageStatus(String imageStatus) { - switch (imageStatus) { - case "CONTENT" -> { - return ImageStatus.CONTENT; - } - case "USER" -> { - return ImageStatus.USER; - } - case "THUMNAIl" -> { - return ImageStatus.THUMBNAIL; - } - } - return ImageStatus.NONE; + return new ImageResponse( imageUrl); } + } From 624b0ae4e6ee3e86abb61433deaa31e0040ea560 Mon Sep 17 00:00:00 2001 From: Donghun Won Date: Fri, 30 Aug 2024 23:33:39 +0900 Subject: [PATCH 187/371] =?UTF-8?q?Refactor=20:=20imageStatus=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../solitour/image/dto/mapper/ImageMapper.java | 1 - .../solitour/image/dto/response/ImageResponse.java | 2 ++ .../solitour_backend/solitour/image/service/ImageService.java | 3 +-- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/solitour_backend/solitour/image/dto/mapper/ImageMapper.java b/src/main/java/solitour_backend/solitour/image/dto/mapper/ImageMapper.java index b961d950..eca9e9c1 100644 --- a/src/main/java/solitour_backend/solitour/image/dto/mapper/ImageMapper.java +++ b/src/main/java/solitour_backend/solitour/image/dto/mapper/ImageMapper.java @@ -20,6 +20,5 @@ default String mapImageStatus(ImageStatus imageStatus) { return imageStatus.getName(); } - List toImageResponseList(List images); } diff --git a/src/main/java/solitour_backend/solitour/image/dto/response/ImageResponse.java b/src/main/java/solitour_backend/solitour/image/dto/response/ImageResponse.java index c383b546..3a6f81db 100644 --- a/src/main/java/solitour_backend/solitour/image/dto/response/ImageResponse.java +++ b/src/main/java/solitour_backend/solitour/image/dto/response/ImageResponse.java @@ -6,5 +6,7 @@ @Getter @AllArgsConstructor public class ImageResponse { + + private String imageStatus; private String address; } \ No newline at end of file diff --git a/src/main/java/solitour_backend/solitour/image/service/ImageService.java b/src/main/java/solitour_backend/solitour/image/service/ImageService.java index b41ff61c..96d898df 100644 --- a/src/main/java/solitour_backend/solitour/image/service/ImageService.java +++ b/src/main/java/solitour_backend/solitour/image/service/ImageService.java @@ -23,7 +23,6 @@ public class ImageService { public ImageResponse uploadImage(Long id, MultipartFile image, String type) { String imageUrl = s3Uploader.upload(image, type, id); - return new ImageResponse( imageUrl); + return new ImageResponse(ImageStatus.CONTENT.getName(), imageUrl); } - } From 4dcf548d147b21462be164147c8876f9afdb51a1 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Sat, 31 Aug 2024 02:03:47 +0900 Subject: [PATCH 188/371] =?UTF-8?q?feat:=20=EC=A0=95=EB=B3=B4=20create=20r?= =?UTF-8?q?equest=20dto?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dto/request/InformationCreateRequest.java | 52 +++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 src/main/java/solitour_backend/solitour/information/dto/request/InformationCreateRequest.java diff --git a/src/main/java/solitour_backend/solitour/information/dto/request/InformationCreateRequest.java b/src/main/java/solitour_backend/solitour/information/dto/request/InformationCreateRequest.java new file mode 100644 index 00000000..d581e0b4 --- /dev/null +++ b/src/main/java/solitour_backend/solitour/information/dto/request/InformationCreateRequest.java @@ -0,0 +1,52 @@ +package solitour_backend.solitour.information.dto.request; + +import jakarta.validation.constraints.Min; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import solitour_backend.solitour.place.dto.request.PlaceRegisterRequest; +import solitour_backend.solitour.tag.dto.request.TagRegisterRequest; + +import java.util.List; + +@Getter +@AllArgsConstructor +@NoArgsConstructor +public class InformationCreateRequest { + @NotBlank + @Size(min = 1, max = 50) + private String informationTitle; + + @NotBlank + @Size(min = 1, max = 20) + private String informationAddress; + + private String informationContent; + + private String informationTips; + + @NotNull + private PlaceRegisterRequest placeRegisterRequest; + + @NotNull + @Min(1) + private Long categoryId; + + @NotBlank + @Size(min = 1, max = 20) + private String zoneCategoryNameParent; + + @NotBlank + @Size(min = 1, max = 20) + private String zoneCategoryNameChild; + + @NotBlank + private String thumbNailImageUrl; + + private List contentImagesUrl; + + private List tagRegisterRequests; +} From a4f9b14d3f3d23701206ef869f5cf8e962793b2c Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Sat, 31 Aug 2024 02:32:47 +0900 Subject: [PATCH 189/371] =?UTF-8?q?fix:=20gathering=20=EC=83=9D=EC=84=B1?= =?UTF-8?q?=EC=9E=90=EC=97=90=20isDeleted=20false=EB=A1=9C=20=EC=A7=80?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../solitour_backend/solitour/gathering/entity/Gathering.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main/java/solitour_backend/solitour/gathering/entity/Gathering.java b/src/main/java/solitour_backend/solitour/gathering/entity/Gathering.java index 39df37f1..d0ee7598 100644 --- a/src/main/java/solitour_backend/solitour/gathering/entity/Gathering.java +++ b/src/main/java/solitour_backend/solitour/gathering/entity/Gathering.java @@ -11,7 +11,9 @@ import jakarta.persistence.JoinColumn; import jakarta.persistence.ManyToOne; import jakarta.persistence.Table; + import java.time.LocalDateTime; + import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; @@ -116,5 +118,6 @@ public Gathering(User user, ZoneCategory zoneCategory, GatheringCategory gatheri this.allowedSex = allowedSex; this.startAge = startAge; this.endAge = endAge; + this.isDeleted = false; } } From 1fbb6f40b6d51780fc3c555d0b4f6ec8e14fad8d Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Sat, 31 Aug 2024 02:33:20 +0900 Subject: [PATCH 190/371] =?UTF-8?q?fix:=20gatheringApplicants=20=EC=83=81?= =?UTF-8?q?=ED=83=9C=EA=B0=92=20consent=EC=9D=B8=20=EC=9C=A0=EC=A0=80?= =?UTF-8?q?=EB=93=A4=EB=A7=8C=20count?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../gathering/repository/GatheringRepositoryImpl.java | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryImpl.java b/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryImpl.java index e85052b7..a0a7f2f5 100644 --- a/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryImpl.java +++ b/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryImpl.java @@ -10,11 +10,13 @@ import com.querydsl.core.types.dsl.PathBuilder; import com.querydsl.jpa.JPAExpressions; import com.querydsl.jpa.JPQLQuery; + import java.time.LocalDate; import java.time.LocalDateTime; import java.time.LocalTime; import java.util.List; import java.util.Objects; + import org.springframework.data.domain.Page; import org.springframework.data.domain.PageImpl; import org.springframework.data.domain.Pageable; @@ -56,8 +58,7 @@ public List getGatheringRecommend(Long gatheringId, Long .leftJoin(bookMarkGathering) .on(bookMarkGathering.gathering.id.eq(gathering.id).and(bookMarkGathering.user.id.eq(userId))) .leftJoin(category).on(category.id.eq(gathering.gatheringCategory.id)) - .leftJoin(gatheringApplicants).on(gatheringApplicants.gathering.id.eq(gathering.id) - .and(gatheringApplicants.gatheringStatus.eq(GatheringStatus.CONSENT))) + .leftJoin(gatheringApplicants).on(gatheringApplicants.gathering.id.eq(gathering.id).and(gatheringApplicants.gatheringStatus.eq(GatheringStatus.CONSENT))) .where(gathering.isFinish.eq(Boolean.FALSE) .and(gathering.gatheringCategory.id.eq(gatheringCategoryId)) .and(gathering.id.ne(gatheringId)) @@ -117,7 +118,7 @@ public Page getGatheringPageFilterAndOrder(Pageable page .leftJoin(zoneCategoryParent).on(zoneCategoryParent.id.eq(zoneCategoryChild.parentZoneCategory.id)) .leftJoin(bookMarkGathering) .on(bookMarkGathering.gathering.id.eq(gathering.id).and(bookMarkGathering.user.id.eq(userId))) - .leftJoin(gatheringApplicants).on(gatheringApplicants.gathering.id.eq(gathering.id)) + .leftJoin(gatheringApplicants).on(gatheringApplicants.gathering.id.eq(gathering.id).and(gatheringApplicants.gatheringStatus.eq(GatheringStatus.CONSENT))) .where(booleanBuilder) .groupBy(gathering.id, zoneCategoryChild.id, zoneCategoryParent.id, category.id, gathering.title, gathering.viewCount, gathering.user.name, @@ -179,7 +180,7 @@ public Page getPageGatheringByTag(Pageable pageable, .leftJoin(zoneCategoryParent).on(zoneCategoryParent.id.eq(zoneCategoryChild.parentZoneCategory.id)) .leftJoin(bookMarkGathering) .on(bookMarkGathering.gathering.id.eq(gathering.id).and(bookMarkGathering.user.id.eq(userId))) - .leftJoin(gatheringApplicants).on(gatheringApplicants.gathering.id.eq(gathering.id)) + .leftJoin(gatheringApplicants).on(gatheringApplicants.gathering.id.eq(gathering.id).and(gatheringApplicants.gatheringStatus.eq(GatheringStatus.CONSENT))) .leftJoin(gatheringTag) .on(gatheringTag.gathering.id.eq(gathering.id).and(gatheringTag.tag.name.eq(decodedTag))) .where(booleanBuilder.and(gatheringTag.tag.name.eq(decodedTag))) From f4d0e3a400f2f29fe90925d70069e41010a4f04d Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Sat, 31 Aug 2024 02:54:21 +0900 Subject: [PATCH 191/371] =?UTF-8?q?feat:=20=EC=82=AC=EC=9A=A9=ED=95=98?= =?UTF-8?q?=EC=A7=80=20=EC=95=8A=EB=8A=94=20=EC=BD=94=EB=93=9C=20=EC=A0=9C?= =?UTF-8?q?=EA=B1=B0=20=EB=B0=8F=20createdDate=20=EC=B9=BC=EB=9F=BC=20?= =?UTF-8?q?=EC=96=B4=EB=85=B8=ED=85=8C=EC=9D=B4=EC=85=98=20=EC=A0=81?= =?UTF-8?q?=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../solitour/image/entity/Image.java | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/src/main/java/solitour_backend/solitour/image/entity/Image.java b/src/main/java/solitour_backend/solitour/image/entity/Image.java index e6773f57..b6add7c7 100644 --- a/src/main/java/solitour_backend/solitour/image/entity/Image.java +++ b/src/main/java/solitour_backend/solitour/image/entity/Image.java @@ -10,9 +10,12 @@ import jakarta.persistence.JoinColumn; import jakarta.persistence.ManyToOne; import jakarta.persistence.Table; + import java.time.LocalDate; + import lombok.Getter; import lombok.NoArgsConstructor; +import org.springframework.data.annotation.CreatedDate; import solitour_backend.solitour.image.image_status.ImageStatus; import solitour_backend.solitour.image.image_status.ImageStatusConverter; import solitour_backend.solitour.information.entity.Information; @@ -39,19 +42,13 @@ public class Image { @Column(name = "image_address") private String address; + @CreatedDate @Column(name = "image_created_date") private LocalDate createdDate; - public Image(ImageStatus imageStatus, Information information, String address, LocalDate createdDate) { + public Image(ImageStatus imageStatus, Information information, String address) { this.imageStatus = imageStatus; this.information = information; this.address = address; - this.createdDate = createdDate; - } - - public Image(ImageStatus status, String imageUrl, LocalDate now) { - this.imageStatus = status; - this.address = imageUrl; - this.createdDate = now; } } From e03b9a0c29c08d7dfc6a2518398d6a29cf78c3e1 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Sat, 31 Aug 2024 02:54:54 +0900 Subject: [PATCH 192/371] feat: S3 upload response dto --- .../solitour/image/dto/response/S3FileResponse.java | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 src/main/java/solitour_backend/solitour/image/dto/response/S3FileResponse.java diff --git a/src/main/java/solitour_backend/solitour/image/dto/response/S3FileResponse.java b/src/main/java/solitour_backend/solitour/image/dto/response/S3FileResponse.java new file mode 100644 index 00000000..683e80ab --- /dev/null +++ b/src/main/java/solitour_backend/solitour/image/dto/response/S3FileResponse.java @@ -0,0 +1,10 @@ +package solitour_backend.solitour.image.dto.response; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor +public class S3FileResponse { + private String fileUrl; +} From 29d2ee5085fde00fdf6845cb8a3025c69131eb63 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Sat, 31 Aug 2024 02:55:35 +0900 Subject: [PATCH 193/371] =?UTF-8?q?refactor:=20createdDate=20=EC=B9=BC?= =?UTF-8?q?=EB=9F=BC=20=EC=96=B4=EB=85=B8=ED=85=8C=EC=9D=B4=EC=85=98=20?= =?UTF-8?q?=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../solitour/information/entity/Information.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/java/solitour_backend/solitour/information/entity/Information.java b/src/main/java/solitour_backend/solitour/information/entity/Information.java index bb60e6bc..dc746bd1 100644 --- a/src/main/java/solitour_backend/solitour/information/entity/Information.java +++ b/src/main/java/solitour_backend/solitour/information/entity/Information.java @@ -15,6 +15,7 @@ import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; +import org.springframework.data.annotation.CreatedDate; import solitour_backend.solitour.category.entity.Category; import solitour_backend.solitour.place.entity.Place; import solitour_backend.solitour.user.entity.User; @@ -55,6 +56,7 @@ public class Information { @Column(name = "information_address") private String address; + @CreatedDate @Column(name = "information_created_date") private LocalDateTime createdDate; @@ -68,7 +70,7 @@ public class Information { private String tip; public Information(Category category, ZoneCategory zoneCategory, User user, Place place, - String title, String address, LocalDateTime createdDate, Integer viewCount, String content, + String title, String address, Integer viewCount, String content, String tip) { this.category = category; this.zoneCategory = zoneCategory; @@ -76,7 +78,6 @@ public Information(Category category, ZoneCategory zoneCategory, User user, Plac this.place = place; this.title = title; this.address = address; - this.createdDate = createdDate; this.viewCount = viewCount; this.content = content; this.tip = tip; From a49444940dc9a943ea666356e99452c05cf04d51 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Sat, 31 Aug 2024 02:56:20 +0900 Subject: [PATCH 194/371] =?UTF-8?q?feat:=20create=20information=20api=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 --- .../controller/InformationController.java | 52 ++++++++----------- 1 file changed, 21 insertions(+), 31 deletions(-) diff --git a/src/main/java/solitour_backend/solitour/information/controller/InformationController.java b/src/main/java/solitour_backend/solitour/information/controller/InformationController.java index 2702baaa..7cae67f6 100644 --- a/src/main/java/solitour_backend/solitour/information/controller/InformationController.java +++ b/src/main/java/solitour_backend/solitour/information/controller/InformationController.java @@ -3,9 +3,11 @@ import jakarta.servlet.http.HttpServletRequest; import jakarta.validation.Valid; + import java.util.Base64; import java.util.List; import java.util.Objects; + import lombok.RequiredArgsConstructor; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; @@ -13,24 +15,16 @@ import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.validation.BindingResult; -import org.springframework.web.bind.annotation.DeleteMapping; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.ModelAttribute; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.PutMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RequestPart; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; import solitour_backend.solitour.auth.config.Authenticated; +import solitour_backend.solitour.auth.config.AuthenticationPrincipal; import solitour_backend.solitour.auth.support.CookieExtractor; import solitour_backend.solitour.auth.support.JwtTokenProvider; import solitour_backend.solitour.error.Utils; +import solitour_backend.solitour.information.dto.request.InformationCreateRequest; import solitour_backend.solitour.information.dto.request.InformationModifyRequest; import solitour_backend.solitour.information.dto.request.InformationPageRequest; -import solitour_backend.solitour.information.dto.request.InformationRegisterRequest; import solitour_backend.solitour.information.dto.response.InformationBriefResponse; import solitour_backend.solitour.information.dto.response.InformationDetailResponse; import solitour_backend.solitour.information.dto.response.InformationMainResponse; @@ -50,14 +44,12 @@ public class InformationController { @PostMapping @Authenticated - public ResponseEntity createInformation( - @Valid @RequestPart("request") InformationRegisterRequest informationRegisterRequest, - @RequestPart("thumbNailImage") MultipartFile thumbnail, - @RequestPart("contentImages") List contentImages, - BindingResult bindingResult) { + public ResponseEntity createInformation(@AuthenticationPrincipal Long userId, + @Valid @RequestBody InformationCreateRequest informationCreateRequest, + BindingResult bindingResult) { Utils.validationRequest(bindingResult); - InformationResponse informationResponse = informationService.registerInformation( - informationRegisterRequest, thumbnail, contentImages); + + InformationResponse informationResponse = informationService.registerInformation(userId, informationCreateRequest); return ResponseEntity .status(HttpStatus.CREATED) @@ -104,12 +96,11 @@ public ResponseEntity deleteInformation(@PathVariable Long informationId) } @GetMapping - public ResponseEntity> pageInformationSortAndFilter( - @RequestParam(defaultValue = "0") int page, - @RequestParam(defaultValue = "1") Long parentCategoryId, - @Valid @ModelAttribute InformationPageRequest informationPageRequest, - BindingResult bindingResult, - HttpServletRequest request) { + public ResponseEntity> pageInformationSortAndFilter(@RequestParam(defaultValue = "0") int page, + @RequestParam(defaultValue = "1") Long parentCategoryId, + @Valid @ModelAttribute InformationPageRequest informationPageRequest, + BindingResult bindingResult, + HttpServletRequest request) { Utils.validationRequest(bindingResult); Long userId = findUser(request); @@ -123,13 +114,12 @@ public ResponseEntity> pageInformationSortAndFilt } @GetMapping("/tag/search") - public ResponseEntity> getPageInformationByTag( - @RequestParam(defaultValue = "0") int page, - @RequestParam(defaultValue = "1") Long parentCategoryId, - @Valid @ModelAttribute InformationPageRequest informationPageRequest, - @RequestParam(required = false, name = "tagName") String tag, - BindingResult bindingResult, - HttpServletRequest request) { + public ResponseEntity> getPageInformationByTag(@RequestParam(defaultValue = "0") int page, + @RequestParam(defaultValue = "1") Long parentCategoryId, + @Valid @ModelAttribute InformationPageRequest informationPageRequest, + @RequestParam(required = false, name = "tagName") String tag, + BindingResult bindingResult, + HttpServletRequest request) { byte[] decodedBytes = Base64.getUrlDecoder().decode(tag); String decodedTag = new String(decodedBytes); String filteredTag = decodedTag.replaceAll("[^a-zA-Z0-9가-힣]", ""); From 9ed26e94c777d61aed25a2375194f0b28f688336 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Sat, 31 Aug 2024 02:56:57 +0900 Subject: [PATCH 195/371] =?UTF-8?q?refactor:=20s3=20upload=20api=20?= =?UTF-8?q?=EB=B0=98=ED=99=98=ED=83=80=EC=9E=85=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../solitour/image/controller/ImageController.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/main/java/solitour_backend/solitour/image/controller/ImageController.java b/src/main/java/solitour_backend/solitour/image/controller/ImageController.java index aac42873..156052b6 100644 --- a/src/main/java/solitour_backend/solitour/image/controller/ImageController.java +++ b/src/main/java/solitour_backend/solitour/image/controller/ImageController.java @@ -11,7 +11,7 @@ import org.springframework.web.multipart.MultipartFile; import solitour_backend.solitour.auth.config.Authenticated; import solitour_backend.solitour.auth.config.AuthenticationPrincipal; -import solitour_backend.solitour.image.dto.response.ImageResponse; +import solitour_backend.solitour.image.dto.response.S3FileResponse; import solitour_backend.solitour.image.service.ImageService; @RestController @@ -24,14 +24,14 @@ public class ImageController { @Authenticated @PostMapping - public ResponseEntity uploadImage(@AuthenticationPrincipal Long userId, - @RequestPart("image") MultipartFile userImage, - @RequestParam String type) { - ImageResponse imageResponse = imageService.uploadImage(userId, userImage, type); + public ResponseEntity uploadImage(@AuthenticationPrincipal Long userId, + @RequestPart("image") MultipartFile userImage, + @RequestParam String type) { + S3FileResponse s3FileResponse = imageService.uploadImage(userId, userImage, type); return ResponseEntity .status(HttpStatus.CREATED) - .body(imageResponse); + .body(s3FileResponse); } } From 5e56eee55188b6a32865204bd74139790637c146 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Sat, 31 Aug 2024 02:57:35 +0900 Subject: [PATCH 196/371] =?UTF-8?q?refactor:=20S3FileResponse=20dto=20?= =?UTF-8?q?=EB=B0=98=ED=99=98=20=ED=83=80=EC=9E=85=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../solitour/image/service/ImageService.java | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/src/main/java/solitour_backend/solitour/image/service/ImageService.java b/src/main/java/solitour_backend/solitour/image/service/ImageService.java index 96d898df..41c88e77 100644 --- a/src/main/java/solitour_backend/solitour/image/service/ImageService.java +++ b/src/main/java/solitour_backend/solitour/image/service/ImageService.java @@ -1,28 +1,23 @@ package solitour_backend.solitour.image.service; -import java.time.LocalDate; + import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.multipart.MultipartFile; -import solitour_backend.solitour.image.dto.response.ImageResponse; -import solitour_backend.solitour.image.entity.Image; -import solitour_backend.solitour.image.image_status.ImageStatus; -import solitour_backend.solitour.image.repository.ImageRepository; +import solitour_backend.solitour.image.dto.response.S3FileResponse; import solitour_backend.solitour.image.s3.S3Uploader; -import solitour_backend.solitour.user_image.entity.UserImageRepository; -@RequiredArgsConstructor -@Transactional(readOnly = true) @Service +@Transactional +@RequiredArgsConstructor public class ImageService { private final S3Uploader s3Uploader; - @Transactional - public ImageResponse uploadImage(Long id, MultipartFile image, String type) { + public S3FileResponse uploadImage(Long id, MultipartFile image, String type) { String imageUrl = s3Uploader.upload(image, type, id); - return new ImageResponse(ImageStatus.CONTENT.getName(), imageUrl); + return new S3FileResponse(imageUrl); } } From 91db7361943d73c000d5ce4bf94f0720b5e00a05 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Sat, 31 Aug 2024 02:58:00 +0900 Subject: [PATCH 197/371] =?UTF-8?q?refactor:=20=EC=A0=95=EB=B3=B4=20?= =?UTF-8?q?=EB=93=B1=EB=A1=9D=20api=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/InformationService.java | 67 +++++++++---------- 1 file changed, 31 insertions(+), 36 deletions(-) diff --git a/src/main/java/solitour_backend/solitour/information/service/InformationService.java b/src/main/java/solitour_backend/solitour/information/service/InformationService.java index 821c6089..2783f002 100644 --- a/src/main/java/solitour_backend/solitour/information/service/InformationService.java +++ b/src/main/java/solitour_backend/solitour/information/service/InformationService.java @@ -3,11 +3,10 @@ import static solitour_backend.solitour.information.repository.InformationRepositoryCustom.LIKE_COUNT_SORT; import static solitour_backend.solitour.information.repository.InformationRepositoryCustom.VIEW_COUNT_SORT; -import java.time.LocalDate; -import java.time.LocalDateTime; import java.util.ArrayList; import java.util.List; import java.util.Objects; + import lombok.RequiredArgsConstructor; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; @@ -33,9 +32,9 @@ import solitour_backend.solitour.info_tag.entity.InfoTag; import solitour_backend.solitour.info_tag.repository.InfoTagRepository; import solitour_backend.solitour.information.dto.mapper.InformationMapper; +import solitour_backend.solitour.information.dto.request.InformationCreateRequest; import solitour_backend.solitour.information.dto.request.InformationModifyRequest; import solitour_backend.solitour.information.dto.request.InformationPageRequest; -import solitour_backend.solitour.information.dto.request.InformationRegisterRequest; import solitour_backend.solitour.information.dto.response.InformationBriefResponse; import solitour_backend.solitour.information.dto.response.InformationDetailResponse; import solitour_backend.solitour.information.dto.response.InformationMainResponse; @@ -92,32 +91,30 @@ public class InformationService { public static final String IMAGE_PATH = "information"; private final ImageRepository imageRepository; - @Transactional - public InformationResponse registerInformation(InformationRegisterRequest informationRegisterRequest, - MultipartFile thumbnail, List contentImages) { - Category category = categoryRepository.findById(informationRegisterRequest.getCategoryId()) + public InformationResponse registerInformation(Long userId, InformationCreateRequest informationCreateRequest) { + Category category = categoryRepository.findById(informationCreateRequest.getCategoryId()) .orElseThrow( () -> new CategoryNotExistsException("해당하는 id의 category 가 없습니다")); ZoneCategory parentZoneCategory = zoneCategoryRepository.findByName( - informationRegisterRequest.getZoneCategoryNameParent()) + informationCreateRequest.getZoneCategoryNameParent()) .orElseThrow(() -> new ZoneCategoryNotExistsException("해당하는 name의 ZoneCategory 없습니다")); ZoneCategory childZoneCategory = zoneCategoryRepository.findByParentZoneCategoryIdAndName( - parentZoneCategory.getId(), informationRegisterRequest.getZoneCategoryNameChild()) + parentZoneCategory.getId(), informationCreateRequest.getZoneCategoryNameChild()) .orElseThrow(() -> new ZoneCategoryNotExistsException( "해당하는 ParentZoneCategoryId 와 name의 ZoneCategory 없습니다")); Place savePlace = placeRepository.save( new Place( - informationRegisterRequest.getPlaceRegisterRequest().getSearchId(), - informationRegisterRequest.getPlaceRegisterRequest().getName(), - informationRegisterRequest.getPlaceRegisterRequest().getXAxis(), - informationRegisterRequest.getPlaceRegisterRequest().getYAxis(), - informationRegisterRequest.getPlaceRegisterRequest().getAddress()) + informationCreateRequest.getPlaceRegisterRequest().getSearchId(), + informationCreateRequest.getPlaceRegisterRequest().getName(), + informationCreateRequest.getPlaceRegisterRequest().getXAxis(), + informationCreateRequest.getPlaceRegisterRequest().getYAxis(), + informationCreateRequest.getPlaceRegisterRequest().getAddress()) ); - User user = userRepository.findById(informationRegisterRequest.getUserId()) + User user = userRepository.findById(userId) .orElseThrow( () -> new UserNotExistsException("해당하는 id의 User 가 없습니다")); @@ -127,35 +124,35 @@ public InformationResponse registerInformation(InformationRegisterRequest inform childZoneCategory, user, savePlace, - informationRegisterRequest.getInformationTitle(), - informationRegisterRequest.getInformationAddress(), - LocalDateTime.now(), + informationCreateRequest.getInformationTitle(), + informationCreateRequest.getInformationAddress(), 0, - informationRegisterRequest.getInformationContent(), - informationRegisterRequest.getInformationTips() + informationCreateRequest.getInformationContent(), + informationCreateRequest.getInformationTips() ); Information saveInformation = informationRepository.save(information); - LocalDate localDate = LocalDate.now(); + Image thumbImage = new Image(ImageStatus.THUMBNAIL, saveInformation, informationCreateRequest.getThumbNailImageUrl()); + List contentImagesUrl = informationCreateRequest.getContentImagesUrl(); - String thumbNailImageUrl = s3Uploader.upload(thumbnail, IMAGE_PATH, saveInformation.getId()); - Image thumbImage = new Image(ImageStatus.THUMBNAIL, saveInformation, thumbNailImageUrl, localDate); - imageRepository.save(thumbImage); - - for (MultipartFile multipartFile : contentImages) { - String upload = s3Uploader.upload(multipartFile, IMAGE_PATH, saveInformation.getId()); - Image contentImage = new Image(ImageStatus.CONTENT, saveInformation, upload, localDate); - imageRepository.save(contentImage); + if (Objects.nonNull(contentImagesUrl) && !contentImagesUrl.isEmpty()) { + List contentImageList = new ArrayList<>(); + for (String contentImage : contentImagesUrl) { + contentImageList.add(new Image(ImageStatus.CONTENT, saveInformation, contentImage)); + } + imageRepository.saveAll(contentImageList); } - List tags = tagMapper.mapToTags(informationRegisterRequest.getTagRegisterRequests()); + imageRepository.save(thumbImage); + + List tags = tagMapper.mapToTags(informationCreateRequest.getTagRegisterRequests()); List saveTags = tagRepository.saveAll(tags); for (Tag tag : saveTags) { infoTagRepository.save(new InfoTag(tag, saveInformation)); } - return informationMapper.mapToInformationResponse(information); + return informationMapper.mapToInformationResponse(saveInformation); } @@ -280,8 +277,7 @@ public InformationResponse modifyInformation(Long id, InformationModifyRequest i } else { String thumbNailImageUrl = s3Uploader.upload(thumbNail, IMAGE_PATH, information.getId()); - Image thumbImage = new Image(ImageStatus.THUMBNAIL, information, thumbNailImageUrl, - LocalDate.now()); + Image thumbImage = new Image(ImageStatus.THUMBNAIL, information, thumbNailImageUrl); imageRepository.save(thumbImage); } } else { @@ -293,7 +289,7 @@ public InformationResponse modifyInformation(Long id, InformationModifyRequest i if (Objects.nonNull(contentImages)) { for (MultipartFile multipartFile : contentImages) { String upload = s3Uploader.upload(multipartFile, IMAGE_PATH, information.getId()); - Image contentImage = new Image(ImageStatus.CONTENT, information, upload, LocalDate.now()); + Image contentImage = new Image(ImageStatus.CONTENT, information, upload); imageRepository.save(contentImage); } @@ -336,8 +332,7 @@ public void deleteInformation(Long id) { bookMarkInformationRepository.deleteAllByInformationId(information.getId()); - List allByInformationId = imageRepository.findAllByInformationId( - information.getId()); + List allByInformationId = imageRepository.findAllByInformationId(information.getId()); for (Image image : allByInformationId) { s3Uploader.deleteImage(image.getAddress()); From b4b4af80d43e8dd57ba6f9ab08842d1ac8f04219 Mon Sep 17 00:00:00 2001 From: Donghun Won Date: Sun, 1 Sep 2024 14:05:06 +0900 Subject: [PATCH 198/371] =?UTF-8?q?Feat(#121):=20=EC=9D=B4=EB=AF=B8?= =?UTF-8?q?=EC=A7=80=20=EC=97=85=EB=A1=9C=EB=93=9C=20=EC=8B=9C=20dev,=20pr?= =?UTF-8?q?od=20=ED=99=98=EA=B2=BD=20=EA=B5=AC=EB=B6=84+=20=EC=97=94?= =?UTF-8?q?=ED=8B=B0=ED=8B=B0=EB=B3=84=EB=A1=9C=20=EA=B5=AC=EB=B6=84?= =?UTF-8?q?=ED=95=B4=EC=84=9C=20=EA=B2=BD=EB=A1=9C=20=EC=84=A4=EC=A0=95=20?= =?UTF-8?q?(#125)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Feat : 엔티티, 환경에 따라 저장 경로 변경 * Refactor : 유저 프로필 이미지 url 위치 yml 파일로 변경 --- .../solitour/auth/service/OauthService.java | 7 ++++-- .../image/controller/ImageController.java | 22 ++++++++++++++++++- .../image/dto/response/ImageResponse.java | 2 -- .../solitour/image/service/ImageService.java | 4 ++-- 4 files changed, 28 insertions(+), 7 deletions(-) diff --git a/src/main/java/solitour_backend/solitour/auth/service/OauthService.java b/src/main/java/solitour_backend/solitour/auth/service/OauthService.java index 8c806920..eac6c057 100644 --- a/src/main/java/solitour_backend/solitour/auth/service/OauthService.java +++ b/src/main/java/solitour_backend/solitour/auth/service/OauthService.java @@ -8,6 +8,7 @@ import java.util.Objects; import java.util.concurrent.TimeUnit; import lombok.RequiredArgsConstructor; +import org.springframework.beans.factory.annotation.Value; import org.springframework.http.HttpStatusCode; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -40,8 +41,10 @@ public class OauthService { private final GoogleConnector googleConnector; private final GoogleProvider googleProvider; private final UserImageService userImageService; - private final String USER_PROFILE_MALE = "https://s3.ap-northeast-2.amazonaws.com/solitour-bucket/user/2/3e6f9c1b-5f3d-4744-9c8b-dfd2c0e2455f.svg"; - private final String USER_PROFILE_FEMALE = "https://s3.ap-northeast-2.amazonaws.com/solitour-bucket/user/3/96cb196b-35db-4b51-86fa-f661ae731db9.svg"; + @Value("${user.profile.url.male}") + private String USER_PROFILE_MALE; + @Value("${user.profile.url.female}") + private String USER_PROFILE_FEMALE; public OauthLinkResponse generateAuthUrl(String type, String redirectUrl) { diff --git a/src/main/java/solitour_backend/solitour/image/controller/ImageController.java b/src/main/java/solitour_backend/solitour/image/controller/ImageController.java index 156052b6..3ecc727b 100644 --- a/src/main/java/solitour_backend/solitour/image/controller/ImageController.java +++ b/src/main/java/solitour_backend/solitour/image/controller/ImageController.java @@ -1,6 +1,7 @@ package solitour_backend.solitour.image.controller; import lombok.RequiredArgsConstructor; +import org.springframework.beans.factory.annotation.Value; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.PostMapping; @@ -20,6 +21,8 @@ public class ImageController { private final ImageService imageService; + @Value("${image.env}") + private String env; @Authenticated @@ -27,11 +30,28 @@ public class ImageController { public ResponseEntity uploadImage(@AuthenticationPrincipal Long userId, @RequestPart("image") MultipartFile userImage, @RequestParam String type) { - S3FileResponse s3FileResponse = imageService.uploadImage(userId, userImage, type); + checkType(type); + String path = env.concat("/").concat(type); + S3FileResponse s3FileResponse = imageService.uploadImage(userId, userImage, path); return ResponseEntity .status(HttpStatus.CREATED) .body(s3FileResponse); } + private void checkType(String type) { + switch (type) { + case "user": + break; + case "diary": + break; + case "gathering": + break; + case "information": + break; + default: + throw new IllegalArgumentException("잘못된 타입입니다."); + } + } + } diff --git a/src/main/java/solitour_backend/solitour/image/dto/response/ImageResponse.java b/src/main/java/solitour_backend/solitour/image/dto/response/ImageResponse.java index 3a6f81db..c383b546 100644 --- a/src/main/java/solitour_backend/solitour/image/dto/response/ImageResponse.java +++ b/src/main/java/solitour_backend/solitour/image/dto/response/ImageResponse.java @@ -6,7 +6,5 @@ @Getter @AllArgsConstructor public class ImageResponse { - - private String imageStatus; private String address; } \ No newline at end of file diff --git a/src/main/java/solitour_backend/solitour/image/service/ImageService.java b/src/main/java/solitour_backend/solitour/image/service/ImageService.java index 41c88e77..49fd08b3 100644 --- a/src/main/java/solitour_backend/solitour/image/service/ImageService.java +++ b/src/main/java/solitour_backend/solitour/image/service/ImageService.java @@ -15,8 +15,8 @@ public class ImageService { private final S3Uploader s3Uploader; - public S3FileResponse uploadImage(Long id, MultipartFile image, String type) { - String imageUrl = s3Uploader.upload(image, type, id); + public S3FileResponse uploadImage(Long id, MultipartFile image, String path) { + String imageUrl = s3Uploader.upload(image, path, id); return new S3FileResponse(imageUrl); } From 70d72eebe70ab801c2924fd5176aa99292945ca5 Mon Sep 17 00:00:00 2001 From: Donghun Won Date: Sun, 1 Sep 2024 14:30:42 +0900 Subject: [PATCH 199/371] =?UTF-8?q?Feat(#95)=20:=20=EB=AA=A8=EC=9E=84=20?= =?UTF-8?q?=EB=B6=81=EB=A7=88=ED=81=AC=20(#126)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Feat : 모임 북마크 * Refactor : 모임 북마크 생성자 추가 --- .../BookMarkGatheringController.java | 50 +++++++++++++++++++ .../response/BookMarkGatheringResponse.java | 29 +++++++++++ .../dto/response/BookMarkInfo.java | 10 ++++ .../entity/BookMarkGathering.java | 6 +++ .../BookMarkGatheringRepository.java | 16 ++++++ .../service/BookMarkGatheringService.java | 48 ++++++++++++++++++ .../repository/GatheringRepository.java | 2 + 7 files changed, 161 insertions(+) create mode 100644 src/main/java/solitour_backend/solitour/book_mark_gathering/controller/BookMarkGatheringController.java create mode 100644 src/main/java/solitour_backend/solitour/book_mark_gathering/dto/response/BookMarkGatheringResponse.java create mode 100644 src/main/java/solitour_backend/solitour/book_mark_gathering/dto/response/BookMarkInfo.java create mode 100644 src/main/java/solitour_backend/solitour/book_mark_gathering/repository/BookMarkGatheringRepository.java create mode 100644 src/main/java/solitour_backend/solitour/book_mark_gathering/service/BookMarkGatheringService.java diff --git a/src/main/java/solitour_backend/solitour/book_mark_gathering/controller/BookMarkGatheringController.java b/src/main/java/solitour_backend/solitour/book_mark_gathering/controller/BookMarkGatheringController.java new file mode 100644 index 00000000..100c90c0 --- /dev/null +++ b/src/main/java/solitour_backend/solitour/book_mark_gathering/controller/BookMarkGatheringController.java @@ -0,0 +1,50 @@ +package solitour_backend.solitour.book_mark_gathering.controller; + +import lombok.RequiredArgsConstructor; +import org.springframework.http.ResponseEntity; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; +import solitour_backend.solitour.auth.config.AuthenticationPrincipal; +import solitour_backend.solitour.book_mark_gathering.dto.response.BookMarkGatheringResponse; +import solitour_backend.solitour.book_mark_gathering.service.BookMarkGatheringService; +import solitour_backend.solitour.book_mark_information.service.BookMarkInformationService; +import solitour_backend.solitour.book_mark_information.service.dto.response.BookMarkInformationResponse; + +@RestController +@RequiredArgsConstructor +@RequestMapping("/api/bookmark/gathering") +public class BookMarkGatheringController { + + private final BookMarkGatheringService service; + + @GetMapping() + public ResponseEntity getUserBookmark( + @AuthenticationPrincipal Long userId) { + BookMarkGatheringResponse response = service.getUserBookmark(userId); + + return ResponseEntity.ok(response); + } + + @Transactional + @PostMapping() + public ResponseEntity createUserBookmark( + @AuthenticationPrincipal Long userId, @RequestParam Long gatheringId) { + service.createUserBookmark(userId, gatheringId); + + return ResponseEntity.ok().build(); + } + + @Transactional + @DeleteMapping() + public ResponseEntity deleteUserBookmark(@AuthenticationPrincipal Long userId, + @RequestParam Long gatheringId) { + service.deleteUserBookmark(userId, gatheringId); + + return ResponseEntity.ok().build(); + } +} diff --git a/src/main/java/solitour_backend/solitour/book_mark_gathering/dto/response/BookMarkGatheringResponse.java b/src/main/java/solitour_backend/solitour/book_mark_gathering/dto/response/BookMarkGatheringResponse.java new file mode 100644 index 00000000..2548c6e0 --- /dev/null +++ b/src/main/java/solitour_backend/solitour/book_mark_gathering/dto/response/BookMarkGatheringResponse.java @@ -0,0 +1,29 @@ +package solitour_backend.solitour.book_mark_gathering.dto.response; + +import java.util.List; +import lombok.Getter; +import solitour_backend.solitour.book_mark_gathering.entity.BookMarkGathering; + +@Getter +public class BookMarkGatheringResponse { + + private final BookMarkDto bookMarkGathering; + + public BookMarkGatheringResponse(List bookMarkGathering) { + this.bookMarkGathering = new BookMarkDto(bookMarkGathering); + } + + @Getter + private static class BookMarkDto { + + private final List bookMarkInfoList; + + private BookMarkDto(List bookMarkGathering) { + this.bookMarkInfoList = bookMarkGathering.stream().map(bookMark -> { + Long bookMarkId = bookMark.getGathering().getId(); + return new BookMarkInfo(bookMarkId); + }).toList(); + } + + } +} diff --git a/src/main/java/solitour_backend/solitour/book_mark_gathering/dto/response/BookMarkInfo.java b/src/main/java/solitour_backend/solitour/book_mark_gathering/dto/response/BookMarkInfo.java new file mode 100644 index 00000000..8357c89f --- /dev/null +++ b/src/main/java/solitour_backend/solitour/book_mark_gathering/dto/response/BookMarkInfo.java @@ -0,0 +1,10 @@ +package solitour_backend.solitour.book_mark_gathering.dto.response; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +@AllArgsConstructor +@Getter +public class BookMarkInfo { + private Long bookMarkId; +} diff --git a/src/main/java/solitour_backend/solitour/book_mark_gathering/entity/BookMarkGathering.java b/src/main/java/solitour_backend/solitour/book_mark_gathering/entity/BookMarkGathering.java index 549b32d4..a167e44c 100644 --- a/src/main/java/solitour_backend/solitour/book_mark_gathering/entity/BookMarkGathering.java +++ b/src/main/java/solitour_backend/solitour/book_mark_gathering/entity/BookMarkGathering.java @@ -9,6 +9,7 @@ import jakarta.persistence.JoinColumn; import jakarta.persistence.ManyToOne; import jakarta.persistence.Table; +import lombok.AllArgsConstructor; import lombok.Getter; import lombok.NoArgsConstructor; import solitour_backend.solitour.gathering.entity.Gathering; @@ -34,4 +35,9 @@ public class BookMarkGathering { @JoinColumn(name = "gathering_id") private Gathering gathering; + public BookMarkGathering(User user, Gathering gathering) { + this.user = user; + this.gathering = gathering; + } + } diff --git a/src/main/java/solitour_backend/solitour/book_mark_gathering/repository/BookMarkGatheringRepository.java b/src/main/java/solitour_backend/solitour/book_mark_gathering/repository/BookMarkGatheringRepository.java new file mode 100644 index 00000000..20fb7837 --- /dev/null +++ b/src/main/java/solitour_backend/solitour/book_mark_gathering/repository/BookMarkGatheringRepository.java @@ -0,0 +1,16 @@ +package solitour_backend.solitour.book_mark_gathering.repository; + +import java.util.List; +import java.util.Optional; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import solitour_backend.solitour.book_mark_gathering.entity.BookMarkGathering; +import solitour_backend.solitour.book_mark_information.entity.BookMarkInformation; + +public interface BookMarkGatheringRepository extends JpaRepository { + + @Query("SELECT b FROM BookMarkGathering b JOIN FETCH b.user u JOIN FETCH b.gathering i WHERE u.id = :userId") + List findByUserId(Long userId); + + Optional findByGatheringIdAndUserId(Long gatheringId, Long userId); +} diff --git a/src/main/java/solitour_backend/solitour/book_mark_gathering/service/BookMarkGatheringService.java b/src/main/java/solitour_backend/solitour/book_mark_gathering/service/BookMarkGatheringService.java new file mode 100644 index 00000000..9c5f60dc --- /dev/null +++ b/src/main/java/solitour_backend/solitour/book_mark_gathering/service/BookMarkGatheringService.java @@ -0,0 +1,48 @@ +package solitour_backend.solitour.book_mark_gathering.service; + +import jakarta.persistence.EntityNotFoundException; +import java.util.List; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import solitour_backend.solitour.book_mark_gathering.dto.response.BookMarkGatheringResponse; +import solitour_backend.solitour.book_mark_gathering.entity.BookMarkGathering; +import solitour_backend.solitour.book_mark_gathering.repository.BookMarkGatheringRepository; +import solitour_backend.solitour.gathering.entity.Gathering; +import solitour_backend.solitour.gathering.repository.GatheringRepository; +import solitour_backend.solitour.user.entity.User; +import solitour_backend.solitour.user.repository.UserRepository; + +@Service +@RequiredArgsConstructor +@Transactional(readOnly = true) +public class BookMarkGatheringService { + + private final BookMarkGatheringRepository bookMarkGatheringRepository; + private final UserRepository userRepository; + private final GatheringRepository gatheringRepository; + + public BookMarkGatheringResponse getUserBookmark(Long userId) { + List bookMarkInformation = bookMarkGatheringRepository.findByUserId(userId); + + return new BookMarkGatheringResponse(bookMarkInformation); + } + + public void createUserBookmark(Long userId, Long gatheringId) { + User user = userRepository.findByUserId(userId); + Gathering gathering = gatheringRepository.findById(gatheringId) + .orElseThrow(() -> new EntityNotFoundException("해당하는 정보가 없습니다")); + BookMarkGathering bookMarkGathering = new BookMarkGathering(user, gathering); + + bookMarkGatheringRepository.save(bookMarkGathering); + } + + public void deleteUserBookmark(Long userId, Long gatheringId) { + BookMarkGathering bookmark = bookMarkGatheringRepository.findByGatheringIdAndUserId(gatheringId, + userId) + .orElseThrow(() -> new EntityNotFoundException("해당하는 북마크가 없습니다")); + + bookMarkGatheringRepository.delete(bookmark); + } + +} diff --git a/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepository.java b/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepository.java index 8efacbe3..93c7c22e 100644 --- a/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepository.java +++ b/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepository.java @@ -1,7 +1,9 @@ package solitour_backend.solitour.gathering.repository; +import java.util.Optional; import org.springframework.data.jpa.repository.JpaRepository; import solitour_backend.solitour.gathering.entity.Gathering; public interface GatheringRepository extends JpaRepository, GatheringRepositoryCustom { + } From 94ca3814682d121c9519a560728a3fef1b00f85e Mon Sep 17 00:00:00 2001 From: Donghun Won Date: Sun, 1 Sep 2024 14:34:08 +0900 Subject: [PATCH 200/371] =?UTF-8?q?Fix=20:=20imageStatus=20=ED=95=84?= =?UTF-8?q?=EB=93=9C=20=EB=B3=B5=EA=B5=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../solitour/image/dto/response/ImageResponse.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/solitour_backend/solitour/image/dto/response/ImageResponse.java b/src/main/java/solitour_backend/solitour/image/dto/response/ImageResponse.java index c383b546..5bb8c46c 100644 --- a/src/main/java/solitour_backend/solitour/image/dto/response/ImageResponse.java +++ b/src/main/java/solitour_backend/solitour/image/dto/response/ImageResponse.java @@ -6,5 +6,6 @@ @Getter @AllArgsConstructor public class ImageResponse { + private String imageStatus; private String address; } \ No newline at end of file From d3468e05d43f0ae4c50db8853261f0aa664a3c33 Mon Sep 17 00:00:00 2001 From: Donghun Won Date: Sun, 1 Sep 2024 15:22:09 +0900 Subject: [PATCH 201/371] =?UTF-8?q?Feature(#121)=20:=20=EC=9D=B4=EB=AF=B8?= =?UTF-8?q?=EC=A7=80=20=EC=97=94=ED=8B=B0=ED=8B=B0=20=EA=B2=BD=EB=A1=9C=20?= =?UTF-8?q?=EB=B6=84=EB=A5=98=20=EC=8B=9C=EC=97=90=20enum=EC=82=AC?= =?UTF-8?q?=EC=9A=A9=ED=95=98=EB=8F=84=EB=A1=9D=20=EB=B3=80=EA=B2=BD=20(#1?= =?UTF-8?q?27)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Refactor : 이미지 엔티티 경로 분류 시에 enum사용하도록 변경 --- .../image/controller/ImageController.java | 18 ++++++------- .../image/image_status/ImageType.java | 25 +++++++++++++++++++ 2 files changed, 33 insertions(+), 10 deletions(-) create mode 100644 src/main/java/solitour_backend/solitour/image/image_status/ImageType.java diff --git a/src/main/java/solitour_backend/solitour/image/controller/ImageController.java b/src/main/java/solitour_backend/solitour/image/controller/ImageController.java index 3ecc727b..7f1e3ba3 100644 --- a/src/main/java/solitour_backend/solitour/image/controller/ImageController.java +++ b/src/main/java/solitour_backend/solitour/image/controller/ImageController.java @@ -13,6 +13,7 @@ import solitour_backend.solitour.auth.config.Authenticated; import solitour_backend.solitour.auth.config.AuthenticationPrincipal; import solitour_backend.solitour.image.dto.response.S3FileResponse; +import solitour_backend.solitour.image.image_status.ImageType; import solitour_backend.solitour.image.service.ImageService; @RestController @@ -29,9 +30,9 @@ public class ImageController { @PostMapping public ResponseEntity uploadImage(@AuthenticationPrincipal Long userId, @RequestPart("image") MultipartFile userImage, - @RequestParam String type) { + @RequestParam ImageType type) { checkType(type); - String path = env.concat("/").concat(type); + String path = env.concat("/").concat(type.getName()); S3FileResponse s3FileResponse = imageService.uploadImage(userId, userImage, path); return ResponseEntity @@ -39,15 +40,12 @@ public ResponseEntity uploadImage(@AuthenticationPrincipal Long .body(s3FileResponse); } - private void checkType(String type) { + private void checkType(ImageType type) { switch (type) { - case "user": - break; - case "diary": - break; - case "gathering": - break; - case "information": + case USER: + case DIARY: + case GATHERING: + case INFORMATION: break; default: throw new IllegalArgumentException("잘못된 타입입니다."); diff --git a/src/main/java/solitour_backend/solitour/image/image_status/ImageType.java b/src/main/java/solitour_backend/solitour/image/image_status/ImageType.java new file mode 100644 index 00000000..16b474a6 --- /dev/null +++ b/src/main/java/solitour_backend/solitour/image/image_status/ImageType.java @@ -0,0 +1,25 @@ +package solitour_backend.solitour.image.image_status; + +import java.util.Arrays; +import lombok.Getter; + +@Getter +public enum ImageType { + USER("user"), + DIARY("diary"), + GATHERING("gathering"), + INFORMATION("information"); + + private final String name; + + ImageType(String name) { + this.name = name; + } + + public static ImageType fromName(String name) { + return Arrays.stream(ImageType.values()) + .filter(e -> e.name.equals(name)) + .findAny() + .orElse(null); + } +} \ No newline at end of file From 2d620581109390aadf0020e22ab2a1c0a111a7f8 Mon Sep 17 00:00:00 2001 From: Donghun Won Date: Sun, 1 Sep 2024 15:25:17 +0900 Subject: [PATCH 202/371] =?UTF-8?q?Feat(#128)=20:=20=EC=97=91=EC=84=B8?= =?UTF-8?q?=EC=8A=A4=20=ED=86=A0=ED=81=B0=20=EB=A7=8C=EB=A3=8C=EC=8B=9C=20?= =?UTF-8?q?401=20=EC=BD=94=EB=93=9C=20=EB=B0=98=ED=99=98=20(#129)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Feat : 엑세스 토큰 기간 연장, 로그아웃 시 쿠키 삭제 * Style : 코드 포맷팅 * Refactor : 유저 아이디 중복 검증 * Refactor : 엑세스 토큰 만료시 401 코드 반환 --- .../solitour/auth/config/AuthInterceptor.java | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/main/java/solitour_backend/solitour/auth/config/AuthInterceptor.java b/src/main/java/solitour_backend/solitour/auth/config/AuthInterceptor.java index eea6b2c8..91d93074 100644 --- a/src/main/java/solitour_backend/solitour/auth/config/AuthInterceptor.java +++ b/src/main/java/solitour_backend/solitour/auth/config/AuthInterceptor.java @@ -3,6 +3,7 @@ import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; +import java.io.IOException; import java.lang.annotation.Annotation; import java.util.Optional; import lombok.RequiredArgsConstructor; @@ -18,7 +19,8 @@ public class AuthInterceptor implements HandlerInterceptor { private final JwtTokenProvider jwtTokenProvider; @Override - public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) { + public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) + throws IOException { if (CorsUtils.isPreFlightRequest(request)) { return true; } @@ -26,7 +28,12 @@ public boolean preHandle(HttpServletRequest request, HttpServletResponse respons Optional authenticated = parseAnnotation((HandlerMethod) handler, Authenticated.class); if (authenticated.isPresent()) { - validateToken(request); + try { + validateToken(request); + }catch (Exception e) { + response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "토큰이 유효하지 않습니다."); + return false; + } } return true; } From f9e4f2e8d6558bb10240a5763f94fd8f4c2446d6 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Sun, 1 Sep 2024 17:52:43 +0900 Subject: [PATCH 203/371] =?UTF-8?q?feat:=20=EC=A0=95=EB=B3=B4=EC=97=90=20?= =?UTF-8?q?=EB=8C=80=ED=95=9C=20=EA=B6=8C=ED=95=9C=20=EC=9D=B4=20=EC=97=86?= =?UTF-8?q?=EB=8A=94=EA=B2=BD=EC=9A=B0=20exception?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../exception/InformationNotManageException.java | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 src/main/java/solitour_backend/solitour/information/exception/InformationNotManageException.java diff --git a/src/main/java/solitour_backend/solitour/information/exception/InformationNotManageException.java b/src/main/java/solitour_backend/solitour/information/exception/InformationNotManageException.java new file mode 100644 index 00000000..c96a48e2 --- /dev/null +++ b/src/main/java/solitour_backend/solitour/information/exception/InformationNotManageException.java @@ -0,0 +1,8 @@ +package solitour_backend.solitour.information.exception; + +public class InformationNotManageException extends RuntimeException { + + public InformationNotManageException(String message) { + super(message); + } +} From ca344561967bb29be81cbe594d79022a29cae0b6 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Sun, 1 Sep 2024 17:52:56 +0900 Subject: [PATCH 204/371] =?UTF-8?q?feat:=20=EC=A0=95=EB=B3=B4=20update=20r?= =?UTF-8?q?equest=20dto?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dto/request/InformationUpdateRequest.java | 54 +++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 src/main/java/solitour_backend/solitour/information/dto/request/InformationUpdateRequest.java diff --git a/src/main/java/solitour_backend/solitour/information/dto/request/InformationUpdateRequest.java b/src/main/java/solitour_backend/solitour/information/dto/request/InformationUpdateRequest.java new file mode 100644 index 00000000..55ad0173 --- /dev/null +++ b/src/main/java/solitour_backend/solitour/information/dto/request/InformationUpdateRequest.java @@ -0,0 +1,54 @@ +package solitour_backend.solitour.information.dto.request; + +import jakarta.validation.constraints.Min; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; +import lombok.Getter; +import lombok.NoArgsConstructor; +import solitour_backend.solitour.image.dto.request.ImageDeleteRequest; +import solitour_backend.solitour.place.dto.request.PlaceModifyRequest; +import solitour_backend.solitour.tag.dto.request.TagRegisterRequest; + +import java.util.List; + +@Getter +@NoArgsConstructor +public class InformationUpdateRequest { + + @NotBlank + @Size(min = 1, max = 50) + private String title; + + @NotBlank + @Size(min = 1, max = 20) + private String address; + + private String content; + + private String tips; + + @NotNull + private PlaceModifyRequest placeModifyRequest; + + @NotNull + @Min(1) + private Long categoryId; + + @NotBlank + @Size(min = 1, max = 20) + private String zoneCategoryNameParent; + + @NotBlank + @Size(min = 1, max = 20) + private String zoneCategoryNameChild; + + private List deleteImages; + + @Size(min = 0, max = 200) + private String thumbNailUrl; + + private List contentImagesUrl; + + private List tagRegisterRequests; +} From 11a1d05ae197db1b88c37c6de118006e40b72a06 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Sun, 1 Sep 2024 17:53:09 +0900 Subject: [PATCH 205/371] =?UTF-8?q?feat:=20=EC=A0=95=EB=B3=B4=EC=97=90=20?= =?UTF-8?q?=EB=8C=80=ED=95=9C=20=EA=B6=8C=ED=95=9C=20=EC=9D=B4=20=EC=97=86?= =?UTF-8?q?=EB=8A=94=EA=B2=BD=EC=9A=B0=20exception=20handler?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../solitour/error/GlobalControllerAdvice.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/solitour_backend/solitour/error/GlobalControllerAdvice.java b/src/main/java/solitour_backend/solitour/error/GlobalControllerAdvice.java index ebf7071e..73fbbc3c 100644 --- a/src/main/java/solitour_backend/solitour/error/GlobalControllerAdvice.java +++ b/src/main/java/solitour_backend/solitour/error/GlobalControllerAdvice.java @@ -18,6 +18,7 @@ import solitour_backend.solitour.image.exception.ImageNotExistsException; import solitour_backend.solitour.image.exception.ImageRequestValidationFailedException; import solitour_backend.solitour.information.exception.InformationNotExistsException; +import solitour_backend.solitour.information.exception.InformationNotManageException; import solitour_backend.solitour.user.exception.UserNotExistsException; import solitour_backend.solitour.zone_category.exception.ZoneCategoryAlreadyExistsException; import solitour_backend.solitour.zone_category.exception.ZoneCategoryNotExistsException; @@ -28,7 +29,8 @@ public class GlobalControllerAdvice { @ExceptionHandler({ RequestValidationFailedException.class, ImageRequestValidationFailedException.class, - GatheringApplicantsManagerException.class + GatheringApplicantsManagerException.class, + InformationNotManageException.class }) public ResponseEntity validationException(Exception exception) { return ResponseEntity From 612654eb453581ed2d03f432a49407af3abfa977 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Sun, 1 Sep 2024 17:54:47 +0900 Subject: [PATCH 206/371] =?UTF-8?q?feat:=20=EC=9E=90=EC=8B=9D=20=EC=B9=B4?= =?UTF-8?q?=ED=85=8C=EA=B3=A0=EB=A6=AC=20=EC=B0=BE=EB=8A=94=20=EB=A9=94?= =?UTF-8?q?=EC=84=9C=EB=93=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../solitour/category/repository/CategoryRepository.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main/java/solitour_backend/solitour/category/repository/CategoryRepository.java b/src/main/java/solitour_backend/solitour/category/repository/CategoryRepository.java index 479fdb09..823e68e7 100644 --- a/src/main/java/solitour_backend/solitour/category/repository/CategoryRepository.java +++ b/src/main/java/solitour_backend/solitour/category/repository/CategoryRepository.java @@ -1,6 +1,8 @@ package solitour_backend.solitour.category.repository; import java.util.List; +import java.util.Optional; + import org.springframework.data.jpa.repository.JpaRepository; import solitour_backend.solitour.category.entity.Category; @@ -9,4 +11,6 @@ public interface CategoryRepository extends JpaRepository { List findAllByParentCategoryId(Long parentCategoryId); boolean existsByIdAndParentCategoryId(Long id, Long parentCategoryId); + + Optional findByIdAndParentCategoryId(Long id, Long parentCategoryId); } From 444be53cd6e2eabff0a57b03a3358ca75e753259 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Sun, 1 Sep 2024 17:55:07 +0900 Subject: [PATCH 207/371] =?UTF-8?q?feat:=20=EC=A0=95=EB=B3=B4=EC=97=90?= =?UTF-8?q?=EC=84=9C=20=EC=8D=B8=EB=84=A4=EC=9D=BC=20=EC=9D=B4=EB=AF=B8?= =?UTF-8?q?=EC=A7=80=EA=B0=80=20=EC=A1=B4=EC=9E=AC=ED=95=98=EB=8A=94?= =?UTF-8?q?=EC=A7=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../solitour/image/repository/ImageRepository.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main/java/solitour_backend/solitour/image/repository/ImageRepository.java b/src/main/java/solitour_backend/solitour/image/repository/ImageRepository.java index 7e04a88c..770ce59d 100644 --- a/src/main/java/solitour_backend/solitour/image/repository/ImageRepository.java +++ b/src/main/java/solitour_backend/solitour/image/repository/ImageRepository.java @@ -1,6 +1,7 @@ package solitour_backend.solitour.image.repository; import java.util.List; + import org.springframework.data.jpa.repository.JpaRepository; import solitour_backend.solitour.image.entity.Image; import solitour_backend.solitour.image.image_status.ImageStatus; @@ -16,4 +17,6 @@ public interface ImageRepository extends JpaRepository { void deleteByAddress(String address); void deleteAllByInformationId(Long informationId); + + boolean existsImageByImageStatusAndInformationId(ImageStatus imageStatus, Long informationId); } From 1069ccc00bf0f34fb3741e7379946215ad844032 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Sun, 1 Sep 2024 17:56:00 +0900 Subject: [PATCH 208/371] =?UTF-8?q?feat:=20=EC=A0=95=EB=B3=B4=20=EC=88=98?= =?UTF-8?q?=EC=A0=95=20api=20version2,=20=EC=A0=95=EB=B3=B4=20=EC=82=AD?= =?UTF-8?q?=EC=A0=9C=ED=95=A0=EB=95=8C=20userId=20=EA=B0=80=EC=A0=B8?= =?UTF-8?q?=EC=98=A4=EB=8A=94=EA=B1=B0=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/InformationController.java | 35 ++++++++++++++----- 1 file changed, 26 insertions(+), 9 deletions(-) diff --git a/src/main/java/solitour_backend/solitour/information/controller/InformationController.java b/src/main/java/solitour_backend/solitour/information/controller/InformationController.java index 7cae67f6..a8f51f51 100644 --- a/src/main/java/solitour_backend/solitour/information/controller/InformationController.java +++ b/src/main/java/solitour_backend/solitour/information/controller/InformationController.java @@ -25,6 +25,7 @@ import solitour_backend.solitour.information.dto.request.InformationCreateRequest; import solitour_backend.solitour.information.dto.request.InformationModifyRequest; import solitour_backend.solitour.information.dto.request.InformationPageRequest; +import solitour_backend.solitour.information.dto.request.InformationUpdateRequest; import solitour_backend.solitour.information.dto.response.InformationBriefResponse; import solitour_backend.solitour.information.dto.response.InformationDetailResponse; import solitour_backend.solitour.information.dto.response.InformationMainResponse; @@ -68,17 +69,32 @@ public ResponseEntity getDetailInformation(@PathVaria .body(informationDetailResponse); } +// @Authenticated +// @PutMapping("/{informationId}") +// public ResponseEntity modifyInformation(@PathVariable Long informationId, +// @RequestPart(value = "thumbNailImage", required = false) MultipartFile thumbnail, +// @RequestPart(value = "contentImages", required = false) List contentImages, +// @Valid @RequestPart("request") InformationModifyRequest informationModifyRequest, +// BindingResult bindingResult) { +// Utils.validationRequest(bindingResult); +// +// InformationResponse informationResponse = informationService.modifyInformation( +// informationId, informationModifyRequest, thumbnail, contentImages); +// +// return ResponseEntity +// .status(HttpStatus.CREATED) +// .body(informationResponse); +// } + @Authenticated - @PutMapping("/{informationId}") - public ResponseEntity modifyInformation(@PathVariable Long informationId, - @RequestPart(value = "thumbNailImage", required = false) MultipartFile thumbnail, - @RequestPart(value = "contentImages", required = false) List contentImages, - @Valid @RequestPart("request") InformationModifyRequest informationModifyRequest, + @PutMapping("{/informationId}") + public ResponseEntity modifyInformation(@AuthenticationPrincipal Long userId, + @PathVariable Long informationId, + @Valid @RequestBody InformationUpdateRequest informationUpdateRequest, BindingResult bindingResult) { Utils.validationRequest(bindingResult); - InformationResponse informationResponse = informationService.modifyInformation( - informationId, informationModifyRequest, thumbnail, contentImages); + InformationResponse informationResponse = informationService.updateInformation(userId, informationId, informationUpdateRequest); return ResponseEntity .status(HttpStatus.CREATED) @@ -87,8 +103,9 @@ public ResponseEntity modifyInformation(@PathVariable Long @Authenticated @DeleteMapping("/{informationId}") - public ResponseEntity deleteInformation(@PathVariable Long informationId) { - informationService.deleteInformation(informationId); + public ResponseEntity deleteInformation(@AuthenticationPrincipal Long userId, + @PathVariable Long informationId) { + informationService.deleteInformation(userId, informationId); return ResponseEntity .status(HttpStatus.NO_CONTENT) From d825196df37e330e9941c9f5ba5e63c8c672768f Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Sun, 1 Sep 2024 17:56:31 +0900 Subject: [PATCH 209/371] =?UTF-8?q?feat:=20=EC=A0=95=EB=B3=B4=20=EC=88=98?= =?UTF-8?q?=EC=A0=95=20version2=20service?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/InformationService.java | 226 +++++++++++++----- 1 file changed, 161 insertions(+), 65 deletions(-) diff --git a/src/main/java/solitour_backend/solitour/information/service/InformationService.java b/src/main/java/solitour_backend/solitour/information/service/InformationService.java index 2783f002..14911e17 100644 --- a/src/main/java/solitour_backend/solitour/information/service/InformationService.java +++ b/src/main/java/solitour_backend/solitour/information/service/InformationService.java @@ -24,6 +24,7 @@ import solitour_backend.solitour.image.dto.request.ImageUseRequest; import solitour_backend.solitour.image.dto.response.ImageResponse; import solitour_backend.solitour.image.entity.Image; +import solitour_backend.solitour.image.exception.ImageAlreadyExistsException; import solitour_backend.solitour.image.exception.ImageNotExistsException; import solitour_backend.solitour.image.exception.ImageRequestValidationFailedException; import solitour_backend.solitour.image.image_status.ImageStatus; @@ -35,6 +36,7 @@ import solitour_backend.solitour.information.dto.request.InformationCreateRequest; import solitour_backend.solitour.information.dto.request.InformationModifyRequest; import solitour_backend.solitour.information.dto.request.InformationPageRequest; +import solitour_backend.solitour.information.dto.request.InformationUpdateRequest; import solitour_backend.solitour.information.dto.response.InformationBriefResponse; import solitour_backend.solitour.information.dto.response.InformationDetailResponse; import solitour_backend.solitour.information.dto.response.InformationMainResponse; @@ -42,6 +44,7 @@ import solitour_backend.solitour.information.dto.response.InformationResponse; import solitour_backend.solitour.information.entity.Information; import solitour_backend.solitour.information.exception.InformationNotExistsException; +import solitour_backend.solitour.information.exception.InformationNotManageException; import solitour_backend.solitour.information.repository.InformationRepository; import solitour_backend.solitour.place.dto.mapper.PlaceMapper; import solitour_backend.solitour.place.dto.response.PlaceResponse; @@ -209,118 +212,211 @@ public InformationDetailResponse getDetailInformation(Long userId, Long informat } @Transactional - public InformationResponse modifyInformation(Long id, InformationModifyRequest informationModifyRequest, - MultipartFile thumbNail, List contentImages) { - Information information = informationRepository.findById(id) + public InformationResponse updateInformation(Long userId, Long informationId, InformationUpdateRequest informationUpdateRequest) { + Information information = informationRepository.findById(informationId) .orElseThrow( () -> new InformationNotExistsException("해당하는 id의 information 이 존재하지 않습니다.")); - information.setTitle(informationModifyRequest.getTitle()); - information.setAddress(informationModifyRequest.getAddress()); - information.setContent(informationModifyRequest.getContent()); - information.setTip(informationModifyRequest.getTips()); + if (!Objects.equals(information.getUser().getId(), userId)) { + throw new InformationNotManageException("권한이 없습니다"); + } + + information.setTitle(informationUpdateRequest.getTitle()); + information.setAddress(informationUpdateRequest.getAddress()); + information.setContent(informationUpdateRequest.getContent()); + information.setTip(informationUpdateRequest.getTips()); Place placeInformation = placeRepository.findById(information.getPlace().getId()) .orElseThrow( () -> new PlaceNotExistsException("해당하는 information의 place에서의 id가 존재하지 않습니다")); - placeInformation.setName(informationModifyRequest.getPlaceModifyRequest().getName()); - placeInformation.setAddress(informationModifyRequest.getPlaceModifyRequest().getAddress()); - placeInformation.setXaxis(informationModifyRequest.getPlaceModifyRequest().getXAxis()); - placeInformation.setYaxis(informationModifyRequest.getPlaceModifyRequest().getYAxis()); - placeInformation.setSearchId(informationModifyRequest.getPlaceModifyRequest().getSearchId()); + placeInformation.setName(informationUpdateRequest.getPlaceModifyRequest().getName()); + placeInformation.setAddress(informationUpdateRequest.getPlaceModifyRequest().getAddress()); + placeInformation.setXaxis(informationUpdateRequest.getPlaceModifyRequest().getXAxis()); + placeInformation.setYaxis(informationUpdateRequest.getPlaceModifyRequest().getYAxis()); + placeInformation.setSearchId(informationUpdateRequest.getPlaceModifyRequest().getSearchId()); - Category categoryInformation = categoryRepository.findById(informationModifyRequest.getCategoryId()) + Category categoryInformation = categoryRepository.findByIdAndParentCategoryId(informationUpdateRequest.getCategoryId(), null) .orElseThrow( () -> new CategoryNotExistsException("해당하는 cateogry Id 가 존재하지 않습니다.")); information.setCategory(categoryInformation); ZoneCategory parentZoneCategory = zoneCategoryRepository.findByParentZoneCategoryIdAndName(null, - informationModifyRequest.getZoneCategoryNameParent()) + informationUpdateRequest.getZoneCategoryNameParent()) .orElseThrow( () -> new ZoneCategoryNotExistsException("해당하는 name에 대한 zoneCategory가 존재하지 않습니다")); ZoneCategory childZoneCategory = zoneCategoryRepository.findByParentZoneCategoryIdAndName( - parentZoneCategory.getId(), informationModifyRequest.getZoneCategoryNameChild()) + parentZoneCategory.getId(), informationUpdateRequest.getZoneCategoryNameChild()) .orElseThrow( () -> new ZoneCategoryNotExistsException("해당하는 name에 대한 zoneCategory가 존재하지 않습니다")); information.setZoneCategory(childZoneCategory); - List useImages = informationModifyRequest.getUseImages(); + List infoTags = infoTagRepository.findAllByInformationId(information.getId()); + + infoTagRepository.deleteAllByInformationId(information.getId()); - for (ImageUseRequest imageUseRequest : useImages) { - if (!imageRepository.existsImageByAddress(imageUseRequest.getAddress())) { - throw new ImageNotExistsException("계속 사용하려는 주소의 이미지는 없습니다."); - } + for (InfoTag infoTag : infoTags) { + tagRepository.deleteById(infoTag.getTag().getTagId()); } - List deleteImages = informationModifyRequest.getDeleteImages(); + List saveTags = tagRepository.saveAll( + tagMapper.mapToTags( + informationUpdateRequest.getTagRegisterRequests())); - for (ImageDeleteRequest imageDeleteRequest : deleteImages) { - if (!imageRepository.existsImageByAddress(imageDeleteRequest.getAddress())) { - throw new ImageNotExistsException("삭제하려는 주소의 이미지가 없습니다."); - } - s3Uploader.deleteImage(imageDeleteRequest.getAddress()); - imageRepository.deleteByAddress(imageDeleteRequest.getAddress()); + for (Tag tag : saveTags) { + infoTagRepository.save(new InfoTag(tag, information)); } - List allByInformationId = imageRepository.findAllByInformationId( - information.getId()); + if (Objects.nonNull(informationUpdateRequest.getPlaceModifyRequest())) { + List deleteImages = informationUpdateRequest.getDeleteImages(); - for (Image image : allByInformationId) { - s3Uploader.deleteImage(image.getAddress()); + for (ImageDeleteRequest imageDeleteRequest : deleteImages) { + s3Uploader.deleteImage(imageDeleteRequest.getAddress()); + imageRepository.deleteByAddress(imageDeleteRequest.getAddress()); + } } - if (!Objects.isNull(thumbNail)) { - if (imageRepository.existsByInformationIdAndImageStatus(information.getId(), - ImageStatus.THUMBNAIL)) { - throw new ImageRequestValidationFailedException("이미 썸네일 이미지가 있습니다"); - } else { - String thumbNailImageUrl = s3Uploader.upload(thumbNail, IMAGE_PATH, - information.getId()); - Image thumbImage = new Image(ImageStatus.THUMBNAIL, information, thumbNailImageUrl); - imageRepository.save(thumbImage); + if (!imageRepository.existsImageByImageStatusAndInformationId(ImageStatus.THUMBNAIL, informationId)) { + if (Objects.isNull(informationUpdateRequest.getThumbNailUrl())) { + throw new ImageRequestValidationFailedException("썸네일 이미지는 있어야 합니다"); } + + imageRepository.save(new Image(ImageStatus.THUMBNAIL, information, informationUpdateRequest.getAddress())); } else { - if (!imageRepository.existsByInformationIdAndImageStatus(information.getId(), - ImageStatus.THUMBNAIL)) { - throw new ImageRequestValidationFailedException("썸네일 이미지가 없습니다"); + if (Objects.nonNull(informationUpdateRequest.getThumbNailUrl())) { + if (!imageRepository.existsImageByAddress(informationUpdateRequest.getThumbNailUrl())) { + throw new ImageAlreadyExistsException("썸네일 이미지가 이미 있습니다"); + } } } - if (Objects.nonNull(contentImages)) { - for (MultipartFile multipartFile : contentImages) { - String upload = s3Uploader.upload(multipartFile, IMAGE_PATH, information.getId()); - Image contentImage = new Image(ImageStatus.CONTENT, information, upload); - imageRepository.save(contentImage); + if (Objects.nonNull(informationUpdateRequest.getContentImagesUrl())) { + List contentImagesUrl = informationUpdateRequest.getContentImagesUrl(); + for (String contentImageUrl : contentImagesUrl) { + imageRepository.save(new Image(ImageStatus.CONTENT, information, contentImageUrl)); } } - List infoTags = infoTagRepository.findAllByInformationId(information.getId()); - - infoTagRepository.deleteAllByInformationId(information.getId()); - - for (InfoTag infoTag : infoTags) { - tagRepository.deleteById(infoTag.getTag().getTagId()); - } - - List saveTags = tagRepository.saveAll( - tagMapper.mapToTags( - informationModifyRequest.getTagRegisterRequests())); - - for (Tag tag : saveTags) { - infoTagRepository.save(new InfoTag(tag, information)); - } - return informationMapper.mapToInformationResponse(information); } + +// @Transactional +// public InformationResponse modifyInformation(Long id, InformationModifyRequest informationModifyRequest, +// MultipartFile thumbNail, List contentImages) { +// Information information = informationRepository.findById(id) +// .orElseThrow( +// () -> new InformationNotExistsException("해당하는 id의 information 이 존재하지 않습니다.")); +// information.setTitle(informationModifyRequest.getTitle()); +// information.setAddress(informationModifyRequest.getAddress()); +// information.setContent(informationModifyRequest.getContent()); +// information.setTip(informationModifyRequest.getTips()); +// +// Place placeInformation = placeRepository.findById(information.getPlace().getId()) +// .orElseThrow( +// () -> new PlaceNotExistsException("해당하는 information의 place에서의 id가 존재하지 않습니다")); +// placeInformation.setName(informationModifyRequest.getPlaceModifyRequest().getName()); +// placeInformation.setAddress(informationModifyRequest.getPlaceModifyRequest().getAddress()); +// placeInformation.setXaxis(informationModifyRequest.getPlaceModifyRequest().getXAxis()); +// placeInformation.setYaxis(informationModifyRequest.getPlaceModifyRequest().getYAxis()); +// placeInformation.setSearchId(informationModifyRequest.getPlaceModifyRequest().getSearchId()); +// +// Category categoryInformation = categoryRepository.findById(informationModifyRequest.getCategoryId()) +// .orElseThrow( +// () -> new CategoryNotExistsException("해당하는 cateogry Id 가 존재하지 않습니다.")); +// information.setCategory(categoryInformation); +// +// ZoneCategory parentZoneCategory = zoneCategoryRepository.findByParentZoneCategoryIdAndName(null, +// informationModifyRequest.getZoneCategoryNameParent()) +// .orElseThrow( +// () -> new ZoneCategoryNotExistsException("해당하는 name에 대한 zoneCategory가 존재하지 않습니다")); +// +// ZoneCategory childZoneCategory = zoneCategoryRepository.findByParentZoneCategoryIdAndName( +// parentZoneCategory.getId(), informationModifyRequest.getZoneCategoryNameChild()) +// .orElseThrow( +// () -> new ZoneCategoryNotExistsException("해당하는 name에 대한 zoneCategory가 존재하지 않습니다")); +// +// information.setZoneCategory(childZoneCategory); +// +// List useImages = informationModifyRequest.getUseImages(); +// +// for (ImageUseRequest imageUseRequest : useImages) { +// if (!imageRepository.existsImageByAddress(imageUseRequest.getAddress())) { +// throw new ImageNotExistsException("계속 사용하려는 주소의 이미지는 없습니다."); +// } +// } +// +// List deleteImages = informationModifyRequest.getDeleteImages(); +// +// for (ImageDeleteRequest imageDeleteRequest : deleteImages) { +// if (!imageRepository.existsImageByAddress(imageDeleteRequest.getAddress())) { +// throw new ImageNotExistsException("삭제하려는 주소의 이미지가 없습니다."); +// } +// s3Uploader.deleteImage(imageDeleteRequest.getAddress()); +// imageRepository.deleteByAddress(imageDeleteRequest.getAddress()); +// } +// +// List allByInformationId = imageRepository.findAllByInformationId( +// information.getId()); +// +// for (Image image : allByInformationId) { +// s3Uploader.deleteImage(image.getAddress()); +// } +// +// if (!Objects.isNull(thumbNail)) { +// if (imageRepository.existsByInformationIdAndImageStatus(information.getId(), +// ImageStatus.THUMBNAIL)) { +// throw new ImageRequestValidationFailedException("이미 썸네일 이미지가 있습니다"); +// } else { +// String thumbNailImageUrl = s3Uploader.upload(thumbNail, IMAGE_PATH, +// information.getId()); +// Image thumbImage = new Image(ImageStatus.THUMBNAIL, information, thumbNailImageUrl); +// imageRepository.save(thumbImage); +// } +// } else { +// if (!imageRepository.existsByInformationIdAndImageStatus(information.getId(), +// ImageStatus.THUMBNAIL)) { +// throw new ImageRequestValidationFailedException("썸네일 이미지가 없습니다"); +// } +// } +// if (Objects.nonNull(contentImages)) { +// for (MultipartFile multipartFile : contentImages) { +// String upload = s3Uploader.upload(multipartFile, IMAGE_PATH, information.getId()); +// Image contentImage = new Image(ImageStatus.CONTENT, information, upload); +// +// imageRepository.save(contentImage); +// } +// } +// +// List infoTags = infoTagRepository.findAllByInformationId(information.getId()); +// +// infoTagRepository.deleteAllByInformationId(information.getId()); +// +// for (InfoTag infoTag : infoTags) { +// tagRepository.deleteById(infoTag.getTag().getTagId()); +// } +// +// List saveTags = tagRepository.saveAll( +// tagMapper.mapToTags( +// informationModifyRequest.getTagRegisterRequests())); +// +// for (Tag tag : saveTags) { +// infoTagRepository.save(new InfoTag(tag, information)); +// } +// +// return informationMapper.mapToInformationResponse(information); +// } + @Transactional - public void deleteInformation(Long id) { + public void deleteInformation(Long userId, Long id) { Information information = informationRepository.findById(id) .orElseThrow( () -> new InformationNotExistsException("해당하는 id의 information 이 존재하지 않습니다.")); + if (!Objects.equals(information.getUser().getId(), userId)) { + throw new InformationNotManageException("권한이 없습니다"); + } List infoTags = infoTagRepository.findAllByInformationId(information.getId()); infoTagRepository.deleteAllByInformationId(information.getId()); From 3982d2d89c8236e40e94cc7b87fad43926028328 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Mon, 2 Sep 2024 00:13:16 +0900 Subject: [PATCH 210/371] =?UTF-8?q?refactor:=20=EC=82=AC=EC=9A=A9=ED=95=98?= =?UTF-8?q?=EC=A7=80=20=EC=95=8A=EB=8A=94=20=EC=BD=94=EB=93=9C=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 --- .../solitour/category/repository/CategoryRepository.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/main/java/solitour_backend/solitour/category/repository/CategoryRepository.java b/src/main/java/solitour_backend/solitour/category/repository/CategoryRepository.java index 823e68e7..dd525a7d 100644 --- a/src/main/java/solitour_backend/solitour/category/repository/CategoryRepository.java +++ b/src/main/java/solitour_backend/solitour/category/repository/CategoryRepository.java @@ -11,6 +11,4 @@ public interface CategoryRepository extends JpaRepository { List findAllByParentCategoryId(Long parentCategoryId); boolean existsByIdAndParentCategoryId(Long id, Long parentCategoryId); - - Optional findByIdAndParentCategoryId(Long id, Long parentCategoryId); } From 21f49fc546883acc66060364858ea59b1c996338 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Mon, 2 Sep 2024 00:14:20 +0900 Subject: [PATCH 211/371] =?UTF-8?q?fix:=20url=20mapping=20=EC=98=A4?= =?UTF-8?q?=EB=A5=98=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../solitour/information/controller/InformationController.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/solitour_backend/solitour/information/controller/InformationController.java b/src/main/java/solitour_backend/solitour/information/controller/InformationController.java index a8f51f51..5bb0517d 100644 --- a/src/main/java/solitour_backend/solitour/information/controller/InformationController.java +++ b/src/main/java/solitour_backend/solitour/information/controller/InformationController.java @@ -87,7 +87,7 @@ public ResponseEntity getDetailInformation(@PathVaria // } @Authenticated - @PutMapping("{/informationId}") + @PutMapping("/{informationId}") public ResponseEntity modifyInformation(@AuthenticationPrincipal Long userId, @PathVariable Long informationId, @Valid @RequestBody InformationUpdateRequest informationUpdateRequest, From 25e6082945ff0eb5eb043b0e0dd614dfbead303f Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Mon, 2 Sep 2024 00:14:34 +0900 Subject: [PATCH 212/371] =?UTF-8?q?fix:=20category=20=EB=A1=9C=EC=A7=81=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 --- .../information/service/InformationService.java | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/main/java/solitour_backend/solitour/information/service/InformationService.java b/src/main/java/solitour_backend/solitour/information/service/InformationService.java index 14911e17..23685ef7 100644 --- a/src/main/java/solitour_backend/solitour/information/service/InformationService.java +++ b/src/main/java/solitour_backend/solitour/information/service/InformationService.java @@ -227,22 +227,26 @@ public InformationResponse updateInformation(Long userId, Long informationId, In Place placeInformation = placeRepository.findById(information.getPlace().getId()) .orElseThrow( - () -> new PlaceNotExistsException("해당하는 information의 place에서의 id가 존재하지 않습니다")); + () -> new PlaceNotExistsException("해당하는 information 의 place 에서의 id가 존재하지 않습니다")); placeInformation.setName(informationUpdateRequest.getPlaceModifyRequest().getName()); placeInformation.setAddress(informationUpdateRequest.getPlaceModifyRequest().getAddress()); placeInformation.setXaxis(informationUpdateRequest.getPlaceModifyRequest().getXAxis()); placeInformation.setYaxis(informationUpdateRequest.getPlaceModifyRequest().getYAxis()); placeInformation.setSearchId(informationUpdateRequest.getPlaceModifyRequest().getSearchId()); - Category categoryInformation = categoryRepository.findByIdAndParentCategoryId(informationUpdateRequest.getCategoryId(), null) + Category categoryInformation = categoryRepository.findById(informationUpdateRequest.getCategoryId()) .orElseThrow( - () -> new CategoryNotExistsException("해당하는 cateogry Id 가 존재하지 않습니다.")); + () -> new CategoryNotExistsException("해당하는 category Id 가 존재하지 않습니다.")); + + if (Objects.isNull(categoryInformation.getParentCategory())) { + throw new RequestValidationFailedException("부모 카테고리는 등록이 안됩니다"); + } information.setCategory(categoryInformation); ZoneCategory parentZoneCategory = zoneCategoryRepository.findByParentZoneCategoryIdAndName(null, informationUpdateRequest.getZoneCategoryNameParent()) .orElseThrow( - () -> new ZoneCategoryNotExistsException("해당하는 name에 대한 zoneCategory가 존재하지 않습니다")); + () -> new ZoneCategoryNotExistsException("해당하는 name 에 대한 zoneCategory 가 존재하지 않습니다")); ZoneCategory childZoneCategory = zoneCategoryRepository.findByParentZoneCategoryIdAndName( parentZoneCategory.getId(), informationUpdateRequest.getZoneCategoryNameChild()) From b6a774d8176b6baa6afbbd3a6abefb66ad9a782e Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Mon, 2 Sep 2024 14:44:32 +0900 Subject: [PATCH 213/371] =?UTF-8?q?fix:=20createdDate=20=EC=B9=BC=EB=9F=BC?= =?UTF-8?q?=20auto=20=EC=83=9D=EC=84=B1=20=EC=84=A4=EC=A0=95=20=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../solitour/image/entity/Image.java | 13 +++---------- .../solitour/information/entity/Information.java | 15 ++++----------- 2 files changed, 7 insertions(+), 21 deletions(-) diff --git a/src/main/java/solitour_backend/solitour/image/entity/Image.java b/src/main/java/solitour_backend/solitour/image/entity/Image.java index b6add7c7..289ea75f 100644 --- a/src/main/java/solitour_backend/solitour/image/entity/Image.java +++ b/src/main/java/solitour_backend/solitour/image/entity/Image.java @@ -1,21 +1,13 @@ package solitour_backend.solitour.image.entity; -import jakarta.persistence.Column; -import jakarta.persistence.Convert; -import jakarta.persistence.Entity; -import jakarta.persistence.FetchType; -import jakarta.persistence.GeneratedValue; -import jakarta.persistence.GenerationType; -import jakarta.persistence.Id; -import jakarta.persistence.JoinColumn; -import jakarta.persistence.ManyToOne; -import jakarta.persistence.Table; +import jakarta.persistence.*; import java.time.LocalDate; import lombok.Getter; import lombok.NoArgsConstructor; import org.springframework.data.annotation.CreatedDate; +import org.springframework.data.jpa.domain.support.AuditingEntityListener; import solitour_backend.solitour.image.image_status.ImageStatus; import solitour_backend.solitour.image.image_status.ImageStatusConverter; import solitour_backend.solitour.information.entity.Information; @@ -24,6 +16,7 @@ @Getter @Table(name = "image") @NoArgsConstructor +@EntityListeners(AuditingEntityListener.class) public class Image { @Id diff --git a/src/main/java/solitour_backend/solitour/information/entity/Information.java b/src/main/java/solitour_backend/solitour/information/entity/Information.java index dc746bd1..7ec18556 100644 --- a/src/main/java/solitour_backend/solitour/information/entity/Information.java +++ b/src/main/java/solitour_backend/solitour/information/entity/Information.java @@ -1,21 +1,13 @@ package solitour_backend.solitour.information.entity; -import jakarta.persistence.CascadeType; -import jakarta.persistence.Column; -import jakarta.persistence.Entity; -import jakarta.persistence.FetchType; -import jakarta.persistence.GeneratedValue; -import jakarta.persistence.GenerationType; -import jakarta.persistence.Id; -import jakarta.persistence.JoinColumn; -import jakarta.persistence.ManyToOne; -import jakarta.persistence.OneToOne; -import jakarta.persistence.Table; +import jakarta.persistence.*; + import java.time.LocalDateTime; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; import org.springframework.data.annotation.CreatedDate; +import org.springframework.data.jpa.domain.support.AuditingEntityListener; import solitour_backend.solitour.category.entity.Category; import solitour_backend.solitour.place.entity.Place; import solitour_backend.solitour.user.entity.User; @@ -26,6 +18,7 @@ @Setter @Table(name = "information") @NoArgsConstructor +@EntityListeners(AuditingEntityListener.class) public class Information { @Id From 3e60d8f3e53d63bb72c21092ddde9c036540518f Mon Sep 17 00:00:00 2001 From: "SK\\ssssk" Date: Tue, 3 Sep 2024 00:24:11 +0900 Subject: [PATCH 214/371] =?UTF-8?q?feat:=20=EA=B3=B5=EC=A7=80=EC=82=AC?= =?UTF-8?q?=ED=95=AD=20entity=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../solitour/admin/entity/Notice.java | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 src/main/java/solitour_backend/solitour/admin/entity/Notice.java diff --git a/src/main/java/solitour_backend/solitour/admin/entity/Notice.java b/src/main/java/solitour_backend/solitour/admin/entity/Notice.java new file mode 100644 index 00000000..ef8d2c2e --- /dev/null +++ b/src/main/java/solitour_backend/solitour/admin/entity/Notice.java @@ -0,0 +1,40 @@ +package solitour_backend.solitour.admin.entity; + +import jakarta.persistence.*; +import lombok.*; +import org.springframework.data.annotation.CreatedDate; +import org.springframework.data.jpa.domain.support.AuditingEntityListener; + +import java.time.LocalDateTime; + +@Entity +@Getter +@Setter +@Table(name = "notice") +@NoArgsConstructor +@AllArgsConstructor +@Builder +@EntityListeners(AuditingEntityListener.class) +public class Notice { + @Id + @Column(name = "notice_id") + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @Column(name = "notice_title") + private String title; + + @Column(name = "notice_content") + private String content; + + @CreatedDate + @Column(name = "notice_created_at") + private LocalDateTime createdAt; + + @Column(name = "notice_category_name") + private String categoryName; + + @Builder.Default + @Column(name = "notice_is_deleted") + private Boolean isDeleted = false; +} From 067d7d1d09fc4f8515c7cc966ed7d0892be9a82e Mon Sep 17 00:00:00 2001 From: "SK\\ssssk" Date: Tue, 3 Sep 2024 00:46:57 +0900 Subject: [PATCH 215/371] =?UTF-8?q?feat:=20=EA=B3=B5=EC=A7=80=EC=82=AC?= =?UTF-8?q?=ED=95=AD=20(=EA=B3=B5=EC=A7=80=EC=82=AC=ED=95=AD=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1,=20=EC=88=98=EC=A0=95,=20=EC=A0=9C=EA=B1=B0,=20?= =?UTF-8?q?=EB=AA=A9=EB=A1=9D=EC=A1=B0=ED=9A=8C,=20=EC=83=81=EC=84=B8?= =?UTF-8?q?=EC=A1=B0=ED=9A=8C,=20=EA=B4=80=EB=A6=AC=EC=9E=90=EC=9D=B8?= =?UTF-8?q?=EA=B2=BD=EC=9A=B0=20=EC=A1=B0=ED=9A=8C=EC=8B=9C=20=EC=A0=9C?= =?UTF-8?q?=EA=B1=B0=EB=90=9C=20=EA=B3=B5=EC=A7=80=EC=82=AC=ED=95=AD?= =?UTF-8?q?=EB=8F=84=20=EC=A1=B0=ED=9A=8C=EA=B0=80=EB=8A=A5)=20=EA=B8=B0?= =?UTF-8?q?=EB=8A=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../admin/controller/NoticeController.java | 74 ++++++++++ .../dto/request/NoticeModifyRequest.java | 26 ++++ .../dto/request/NoticeRegisterRequest.java | 23 +++ .../admin/repository/NoticeRepository.java | 17 +++ .../solitour/admin/service/NoticeService.java | 136 ++++++++++++++++++ 5 files changed, 276 insertions(+) create mode 100644 src/main/java/solitour_backend/solitour/admin/controller/NoticeController.java create mode 100644 src/main/java/solitour_backend/solitour/admin/dto/request/NoticeModifyRequest.java create mode 100644 src/main/java/solitour_backend/solitour/admin/dto/request/NoticeRegisterRequest.java create mode 100644 src/main/java/solitour_backend/solitour/admin/repository/NoticeRepository.java create mode 100644 src/main/java/solitour_backend/solitour/admin/service/NoticeService.java diff --git a/src/main/java/solitour_backend/solitour/admin/controller/NoticeController.java b/src/main/java/solitour_backend/solitour/admin/controller/NoticeController.java new file mode 100644 index 00000000..614e7999 --- /dev/null +++ b/src/main/java/solitour_backend/solitour/admin/controller/NoticeController.java @@ -0,0 +1,74 @@ +package solitour_backend.solitour.admin.controller; + +import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Page; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; +import solitour_backend.solitour.admin.dto.request.NoticeModifyRequest; +import solitour_backend.solitour.admin.dto.request.NoticeRegisterRequest; +import solitour_backend.solitour.admin.entity.Notice; +import solitour_backend.solitour.admin.service.NoticeService; +import solitour_backend.solitour.auth.config.Authenticated; +import solitour_backend.solitour.auth.config.AuthenticationPrincipal; + +@RestController +@RequiredArgsConstructor +@RequestMapping("/api/notice") +public class NoticeController { + + private final NoticeService noticeService; + + // Create a new notice + @Authenticated + @PostMapping + public ResponseEntity createNotice(@AuthenticationPrincipal Long userId, @RequestBody NoticeRegisterRequest noticeRegisterRequest) { + Long id = noticeService.createNotice(noticeRegisterRequest, userId); + return ResponseEntity.status(HttpStatus.CREATED).body(id); + } + + // Retrieve a list of notices (excluding deleted ones) + @GetMapping + public ResponseEntity> getNotices(@RequestParam(defaultValue = "0") int page) { + Page notices = noticeService.getNotices(page); + return ResponseEntity.ok(notices); + } + + // Retrieve a list of notices (excluding deleted ones) + @Authenticated + @GetMapping("/admin") + public ResponseEntity> getNoticesForAdmin(@AuthenticationPrincipal Long userId, @RequestParam(defaultValue = "0") int page) { + Page notices = noticeService.getNoticesForAdmin(page, userId); + return ResponseEntity.ok(notices); + } + + @GetMapping("/{id}") + public ResponseEntity getNotice(@PathVariable Long id) { + Notice notice = noticeService.getNotice(id); + return ResponseEntity.ok(notice); + } + + @Authenticated + @GetMapping("/admin/{id}") + public ResponseEntity getNoticeForAdmin(@AuthenticationPrincipal Long userId, @PathVariable Long id) { + Notice notice = noticeService.getNoticeForAdmin(userId, id); + return ResponseEntity.ok(notice); + } + + @Authenticated + @PutMapping + public ResponseEntity updateNotice(@AuthenticationPrincipal Long userId, @RequestBody NoticeModifyRequest noticeModifyRequest) { + boolean result = noticeService.updateNotice(userId, noticeModifyRequest); + if(result) { + return ResponseEntity.ok().build(); + } + return ResponseEntity.badRequest().build(); + } + + @Authenticated + @DeleteMapping("/{id}") + public ResponseEntity deleteNotice(@AuthenticationPrincipal Long userId, @PathVariable Long id) { + noticeService.deleteNotice(userId, id); + return ResponseEntity.noContent().build(); + } +} diff --git a/src/main/java/solitour_backend/solitour/admin/dto/request/NoticeModifyRequest.java b/src/main/java/solitour_backend/solitour/admin/dto/request/NoticeModifyRequest.java new file mode 100644 index 00000000..57c5c610 --- /dev/null +++ b/src/main/java/solitour_backend/solitour/admin/dto/request/NoticeModifyRequest.java @@ -0,0 +1,26 @@ +package solitour_backend.solitour.admin.dto.request; + +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor +public class NoticeModifyRequest { + + @NotNull + private Long id; + + @NotBlank + @Size(min = 1, max = 50) + private String title; + + @NotBlank + @Size(min = 1, max = 1000) + private String content; + + @NotNull + private String category; +} diff --git a/src/main/java/solitour_backend/solitour/admin/dto/request/NoticeRegisterRequest.java b/src/main/java/solitour_backend/solitour/admin/dto/request/NoticeRegisterRequest.java new file mode 100644 index 00000000..0b9a43ea --- /dev/null +++ b/src/main/java/solitour_backend/solitour/admin/dto/request/NoticeRegisterRequest.java @@ -0,0 +1,23 @@ +package solitour_backend.solitour.admin.dto.request; + + +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor +public class NoticeRegisterRequest { + @NotBlank + @Size(min = 1, max = 50) + private String title; + + @NotBlank + @Size(min = 1, max = 1000) + private String content; + + @NotNull + private String category; +} diff --git a/src/main/java/solitour_backend/solitour/admin/repository/NoticeRepository.java b/src/main/java/solitour_backend/solitour/admin/repository/NoticeRepository.java new file mode 100644 index 00000000..04189d92 --- /dev/null +++ b/src/main/java/solitour_backend/solitour/admin/repository/NoticeRepository.java @@ -0,0 +1,17 @@ +package solitour_backend.solitour.admin.repository; + +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; +import solitour_backend.solitour.admin.entity.Notice; + +import java.util.Optional; + +@Repository +public interface NoticeRepository extends JpaRepository { + + Page findAllByIsDeletedFalse(Pageable pageable); + + Optional findByIdAndIsDeletedFalse(Long id); +} diff --git a/src/main/java/solitour_backend/solitour/admin/service/NoticeService.java b/src/main/java/solitour_backend/solitour/admin/service/NoticeService.java new file mode 100644 index 00000000..3c0c4af8 --- /dev/null +++ b/src/main/java/solitour_backend/solitour/admin/service/NoticeService.java @@ -0,0 +1,136 @@ +package solitour_backend.solitour.admin.service; + +import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Sort; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import solitour_backend.solitour.admin.dto.request.NoticeModifyRequest; +import solitour_backend.solitour.admin.dto.request.NoticeRegisterRequest; +import solitour_backend.solitour.admin.entity.Notice; +import solitour_backend.solitour.admin.repository.NoticeRepository; +import solitour_backend.solitour.user.entity.User; +import solitour_backend.solitour.user.repository.UserRepository; + +@Service +@RequiredArgsConstructor +public class NoticeService { + + private final NoticeRepository noticeRepository; + private final UserRepository userRepository; + + // 공지사항 생성 + public Long createNotice(NoticeRegisterRequest noticeRegisterRequest, Long userId) { + User user = userRepository.findByUserId(userId); + + if (user == null) { + throw new RuntimeException("사용자를 찾을 수 없습니다."); + } + + if (!user.getIsAdmin()) { + throw new RuntimeException("관리자 권한이 필요합니다."); + } + + Notice notice = noticeRepository.save(Notice.builder() + .title(noticeRegisterRequest.getTitle()) + .content(noticeRegisterRequest.getContent()) + .categoryName(noticeRegisterRequest.getCategory()) + .build()); + + return notice.getId(); + } + + // 공지사항 목록 조회 + public Page getNotices(int page) { + Pageable pageable = PageRequest.of(page, 10, Sort.by(Sort.Order.desc("id"))); + return noticeRepository.findAllByIsDeletedFalse(pageable); + } + + // 공지사항 목록 조회 + public Page getNoticesForAdmin(int page, Long userId) { + Pageable pageable = PageRequest.of(page, 10, Sort.by(Sort.Order.desc("id"))); + + User user = userRepository.findByUserId(userId); + + if (user == null) { + throw new RuntimeException("사용자를 찾을 수 없습니다."); + } + + if (!user.getIsAdmin()) { + throw new RuntimeException("관리자 권한이 필요합니다."); + } + + return noticeRepository.findAll(pageable); + } + + // 공지사항 싱세 조회 + public Notice getNotice(Long id) { + return noticeRepository.findByIdAndIsDeletedFalse(id) + .orElseThrow(() -> new RuntimeException("공지사항을 찾을 수 없습니다.")); + } + + // 관리자를 위한 공지사항 조회, 관리자는 삭제된 공지사항도 볼 수 있음 + public Notice getNoticeForAdmin(Long userId, Long id) { + + User user = userRepository.findByUserId(userId); + + if (user == null) { + throw new RuntimeException("사용자를 찾을 수 없습니다."); + } + + if (!user.getIsAdmin()) { + throw new RuntimeException("관리자 권한이 필요합니다."); + } + + return noticeRepository.findById(id) + .orElseThrow(() -> new RuntimeException("공지사항을 찾을 수 없습니다.")); + } + + // 공지사항 수정 + @Transactional + public boolean updateNotice(Long userId, NoticeModifyRequest noticeModifyRequest) { + User user = userRepository.findByUserId(userId); + + if (user == null) { + throw new RuntimeException("사용자를 찾을 수 없습니다."); + } + + if (!user.getIsAdmin()) { + throw new RuntimeException("관리자 권한이 필요합니다."); + } + + Notice notice = noticeRepository.findByIdAndIsDeletedFalse(noticeModifyRequest.getId()) + .orElseThrow(() -> new RuntimeException("공지사항을 찾을 수 없습니다.")); + + notice.setTitle(noticeModifyRequest.getTitle()); + notice.setContent(noticeModifyRequest.getContent()); + notice.setCategoryName(noticeModifyRequest.getCategory()); + + noticeRepository.save(notice); + return true; + } + + // 공지사항 삭제 (soft delete) + @Transactional + public boolean deleteNotice(Long userId, Long id) { + User user = userRepository.findByUserId(userId); + + if (user == null) { + throw new RuntimeException("사용자를 찾을 수 없습니다."); + } + + if (!user.getIsAdmin()) { + throw new RuntimeException("관리자 권한이 필요합니다."); + } + + Notice notice = noticeRepository.findByIdAndIsDeletedFalse(id) + .orElseThrow(() -> new RuntimeException("공지사항을 찾을 수 없습니다.")); + + notice.setIsDeleted(true); + noticeRepository.save(notice); + return true; + } +} + From 9e64040227441fdc1b6d360744409e10e0b7b163 Mon Sep 17 00:00:00 2001 From: "SK\\ssssk" Date: Tue, 3 Sep 2024 00:52:50 +0900 Subject: [PATCH 216/371] =?UTF-8?q?feat:=20QnA=20(QnA=ED=8E=98=EC=9D=B4?= =?UTF-8?q?=EC=A7=80,=EC=83=81=ED=83=9C,=EA=B2=80=EC=83=89=EC=9C=BC?= =?UTF-8?q?=EB=A1=9C=20=EA=B4=80=EB=A6=AC=EC=9E=90=EA=B0=80=20=EA=B4=80?= =?UTF-8?q?=EB=A6=AC=ED=95=A0=20QnA=EB=AA=A9=EB=A1=9D=20=EC=A1=B0=ED=9A=8C?= =?UTF-8?q?,=20QnA=20=EC=83=9D=EC=84=B1,=20QnA=20=EC=82=AC=EC=9A=A9?= =?UTF-8?q?=EC=9E=90=20=EB=AA=A9=EB=A1=9D=20=EC=A1=B0=ED=9A=8C,=20QnA=20?= =?UTF-8?q?=EC=83=81=EC=84=B8=20=EC=A1=B0=ED=9A=8C,=20QnA=20=EC=A0=9C?= =?UTF-8?q?=EA=B1=B0,=20QnA=20=EC=A7=88=EB=AC=B8=20=EB=93=B1=EB=A1=9D,=20Q?= =?UTF-8?q?nA=20=EB=8B=B5=EB=B3=80=20=EB=93=B1=EB=A1=9D)=20=EC=9E=91?= =?UTF-8?q?=EC=97=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../admin/controller/QnAController.java | 93 ++++++++++ .../dto/request/AnswerRegisterRequest.java | 18 ++ .../admin/dto/request/QnARegisterRequest.java | 22 +++ .../dto/request/QuestionRegisterRequest.java | 18 ++ .../dto/response/QnaListResponseDto.java | 19 ++ .../solitour/admin/entity/QnA.java | 52 ++++++ .../solitour/admin/entity/QnAMessage.java | 38 ++++ .../admin/repository/AnswerRepository.java | 7 + .../admin/repository/QnARepository.java | 36 ++++ .../solitour/admin/service/QnAService.java | 162 ++++++++++++++++++ 10 files changed, 465 insertions(+) create mode 100644 src/main/java/solitour_backend/solitour/admin/controller/QnAController.java create mode 100644 src/main/java/solitour_backend/solitour/admin/dto/request/AnswerRegisterRequest.java create mode 100644 src/main/java/solitour_backend/solitour/admin/dto/request/QnARegisterRequest.java create mode 100644 src/main/java/solitour_backend/solitour/admin/dto/request/QuestionRegisterRequest.java create mode 100644 src/main/java/solitour_backend/solitour/admin/dto/response/QnaListResponseDto.java create mode 100644 src/main/java/solitour_backend/solitour/admin/entity/QnA.java create mode 100644 src/main/java/solitour_backend/solitour/admin/entity/QnAMessage.java create mode 100644 src/main/java/solitour_backend/solitour/admin/repository/AnswerRepository.java create mode 100644 src/main/java/solitour_backend/solitour/admin/repository/QnARepository.java create mode 100644 src/main/java/solitour_backend/solitour/admin/service/QnAService.java diff --git a/src/main/java/solitour_backend/solitour/admin/controller/QnAController.java b/src/main/java/solitour_backend/solitour/admin/controller/QnAController.java new file mode 100644 index 00000000..2f105317 --- /dev/null +++ b/src/main/java/solitour_backend/solitour/admin/controller/QnAController.java @@ -0,0 +1,93 @@ +package solitour_backend.solitour.admin.controller; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Page; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; +import solitour_backend.solitour.admin.dto.request.AnswerRegisterRequest; +import solitour_backend.solitour.admin.dto.request.QnARegisterRequest; +import solitour_backend.solitour.admin.dto.request.QuestionRegisterRequest; +import solitour_backend.solitour.admin.dto.response.QnaListResponseDto; +import solitour_backend.solitour.admin.entity.QnAMessage; +import solitour_backend.solitour.admin.entity.QnA; +import solitour_backend.solitour.admin.service.QnAService; +import solitour_backend.solitour.auth.config.Authenticated; +import solitour_backend.solitour.auth.config.AuthenticationPrincipal; + +@RestController +@RequestMapping("/api/qna") +public class QnAController { + + @Autowired + private QnAService qnaService; + + @Authenticated + @GetMapping("/manage-list") + public ResponseEntity> getPagedQnAsByUserId( + @AuthenticationPrincipal Long userId, + @RequestParam(defaultValue = "0") int page, + @RequestParam(defaultValue = "ALL") String status, + @RequestParam(required = false) String keyword + ) { + Page qnaPage = qnaService.getQnAsByPageStatusAndKeyword(page, status, keyword, userId); + + return ResponseEntity + .status(HttpStatus.OK) + .body(qnaPage); + } + + @Authenticated + @PostMapping + public ResponseEntity createQnA(@AuthenticationPrincipal Long userId, @RequestBody QnARegisterRequest qnARegisterRequest) { + Long qnaId = qnaService.createQnA(qnARegisterRequest, userId); + return ResponseEntity + .status(HttpStatus.CREATED) + .body(qnaId); + } + + @Authenticated + @GetMapping + public Page getPagedQnAsByUserId( + @AuthenticationPrincipal Long userId, + @RequestParam(defaultValue = "0") int page, + @RequestParam(defaultValue = "10") int size) { + return qnaService.getPagedQnAsByUserId(userId, page, size); + } + + @Authenticated + @GetMapping("/{id}") + public ResponseEntity getQnAById(@AuthenticationPrincipal Long userId, @PathVariable Long id) { + QnA qna = qnaService.getQnAById(id, userId); + return ResponseEntity + .status(HttpStatus.OK) + .body(qna); + } + + @Authenticated + @DeleteMapping("/{id}") + public ResponseEntity closeQnAStatus(@AuthenticationPrincipal Long userId, @PathVariable Long id) { + qnaService.closeQnA(id, userId); + return ResponseEntity + .status(HttpStatus.OK) + .build(); + } + + @Authenticated + @PostMapping("/question") + public ResponseEntity createQuestion(@AuthenticationPrincipal Long userId, @RequestBody QuestionRegisterRequest questionRegisterRequest) { + QnAMessage qnaMessage = qnaService.createQuestion(questionRegisterRequest, userId); + return ResponseEntity + .status(HttpStatus.CREATED) + .body(qnaMessage); + } + + @Authenticated + @PostMapping("/answer") + public ResponseEntity createAnswer(@AuthenticationPrincipal Long userId, @RequestBody AnswerRegisterRequest answerRegisterRequest) { + QnAMessage qnaMessage = qnaService.createAnswer(answerRegisterRequest, userId); + return ResponseEntity + .status(HttpStatus.CREATED) + .body(qnaMessage); + } +} \ No newline at end of file diff --git a/src/main/java/solitour_backend/solitour/admin/dto/request/AnswerRegisterRequest.java b/src/main/java/solitour_backend/solitour/admin/dto/request/AnswerRegisterRequest.java new file mode 100644 index 00000000..ca91aecc --- /dev/null +++ b/src/main/java/solitour_backend/solitour/admin/dto/request/AnswerRegisterRequest.java @@ -0,0 +1,18 @@ +package solitour_backend.solitour.admin.dto.request; + +import jakarta.validation.constraints.Min; +import jakarta.validation.constraints.NotNull; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor +public class AnswerRegisterRequest { + + @NotNull + @Min(1) + private String content; + + @NotNull + private Long qnaId; +} diff --git a/src/main/java/solitour_backend/solitour/admin/dto/request/QnARegisterRequest.java b/src/main/java/solitour_backend/solitour/admin/dto/request/QnARegisterRequest.java new file mode 100644 index 00000000..1e5ff00a --- /dev/null +++ b/src/main/java/solitour_backend/solitour/admin/dto/request/QnARegisterRequest.java @@ -0,0 +1,22 @@ +package solitour_backend.solitour.admin.dto.request; + +import jakarta.validation.constraints.Min; +import jakarta.validation.constraints.NotNull; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor +public class QnARegisterRequest { + + @NotNull + @Min(1) + private String title; + + @NotNull + @Min(1) + private String content; + + @NotNull + private String categoryName; +} diff --git a/src/main/java/solitour_backend/solitour/admin/dto/request/QuestionRegisterRequest.java b/src/main/java/solitour_backend/solitour/admin/dto/request/QuestionRegisterRequest.java new file mode 100644 index 00000000..f5f2bcb9 --- /dev/null +++ b/src/main/java/solitour_backend/solitour/admin/dto/request/QuestionRegisterRequest.java @@ -0,0 +1,18 @@ +package solitour_backend.solitour.admin.dto.request; + +import jakarta.validation.constraints.Min; +import jakarta.validation.constraints.NotNull; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor +public class QuestionRegisterRequest { + + @NotNull + @Min(1) + private String content; + + @NotNull + private Long qnaId; +} diff --git a/src/main/java/solitour_backend/solitour/admin/dto/response/QnaListResponseDto.java b/src/main/java/solitour_backend/solitour/admin/dto/response/QnaListResponseDto.java new file mode 100644 index 00000000..f94ea55c --- /dev/null +++ b/src/main/java/solitour_backend/solitour/admin/dto/response/QnaListResponseDto.java @@ -0,0 +1,19 @@ +package solitour_backend.solitour.admin.dto.response; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +import java.time.LocalDateTime; + +@Getter +@AllArgsConstructor +public class QnaListResponseDto { + private Long id; + private String title; + private LocalDateTime createdAt; + private String status; + private LocalDateTime updatedAt; + private String categoryName; + private Long userId; + private String userNickname; +} diff --git a/src/main/java/solitour_backend/solitour/admin/entity/QnA.java b/src/main/java/solitour_backend/solitour/admin/entity/QnA.java new file mode 100644 index 00000000..f9ee798f --- /dev/null +++ b/src/main/java/solitour_backend/solitour/admin/entity/QnA.java @@ -0,0 +1,52 @@ +package solitour_backend.solitour.admin.entity; + +import com.fasterxml.jackson.annotation.JsonManagedReference; +import jakarta.persistence.*; +import lombok.*; +import org.springframework.data.annotation.CreatedDate; +import org.springframework.data.annotation.LastModifiedDate; +import org.springframework.data.jpa.domain.support.AuditingEntityListener; + +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; + +@Entity +@Table(name = "qna") +@Setter +@Getter +@Builder +@AllArgsConstructor +@NoArgsConstructor +@EntityListeners(AuditingEntityListener.class) +public class QnA { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "qna_id") + private Long id; + + @Column(name = "qna_title") + private String title; + + @CreatedDate + @Column(name = "qna_created_at") + private LocalDateTime createdAt; + + @Column(name = "qna_status") + private String status; + + @LastModifiedDate + @Column(name = "qna_updated_at") + private LocalDateTime updatedAt; + + @Column(name = "qna_category_name") + private String categoryName; + + @Column(name = "user_id") + private Long userId; + + @Builder.Default + @OneToMany(mappedBy = "qna", fetch = FetchType.LAZY, cascade = CascadeType.ALL) + @JsonManagedReference + private List qnaMessages = new ArrayList<>(); +} diff --git a/src/main/java/solitour_backend/solitour/admin/entity/QnAMessage.java b/src/main/java/solitour_backend/solitour/admin/entity/QnAMessage.java new file mode 100644 index 00000000..0e0f7154 --- /dev/null +++ b/src/main/java/solitour_backend/solitour/admin/entity/QnAMessage.java @@ -0,0 +1,38 @@ +package solitour_backend.solitour.admin.entity; + +import com.fasterxml.jackson.annotation.JsonBackReference; +import jakarta.persistence.*; +import lombok.*; +import org.springframework.data.annotation.CreatedDate; +import org.springframework.data.jpa.domain.support.AuditingEntityListener; + +import java.time.LocalDateTime; + +@Entity +@Table(name = "qna_message") +@Setter +@Getter +@Builder +@AllArgsConstructor +@NoArgsConstructor +@EntityListeners(AuditingEntityListener.class) +public class QnAMessage { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @ManyToOne + @JoinColumn(name = "qna_id") + @JsonBackReference + private QnA qna; + + @CreatedDate + @Column(name = "qna_message_created_at") + private LocalDateTime createdAt; + + @Column(name = "qna_message_user_id") + private Long userId; + + @Column(name = "qna_message_content") + private String content; +} diff --git a/src/main/java/solitour_backend/solitour/admin/repository/AnswerRepository.java b/src/main/java/solitour_backend/solitour/admin/repository/AnswerRepository.java new file mode 100644 index 00000000..b5da4522 --- /dev/null +++ b/src/main/java/solitour_backend/solitour/admin/repository/AnswerRepository.java @@ -0,0 +1,7 @@ +package solitour_backend.solitour.admin.repository; + +import org.springframework.data.jpa.repository.JpaRepository; +import solitour_backend.solitour.admin.entity.QnAMessage; + +public interface AnswerRepository extends JpaRepository { +} diff --git a/src/main/java/solitour_backend/solitour/admin/repository/QnARepository.java b/src/main/java/solitour_backend/solitour/admin/repository/QnARepository.java new file mode 100644 index 00000000..5cbf220c --- /dev/null +++ b/src/main/java/solitour_backend/solitour/admin/repository/QnARepository.java @@ -0,0 +1,36 @@ +package solitour_backend.solitour.admin.repository; + +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; +import solitour_backend.solitour.admin.dto.response.QnaListResponseDto; +import solitour_backend.solitour.admin.entity.QnA; + +public interface QnARepository extends JpaRepository { + + Page findByUserId(Long userId, Pageable pageable); + + // 상태에 관계없이 모든 QnA 항목 검색 (updatedAt 기준 오름차순) + @Query("SELECT new solitour_backend.solitour.admin.dto.response.QnaListResponseDto(q.id, q.title, q.createdAt, q.status, q.updatedAt, q.categoryName, u.id, u.nickname) " + + "FROM QnA q JOIN User u ON q.userId = u.id ORDER BY q.updatedAt ASC") + Page findAllByOrderByUpdatedAtAsc(Pageable pageable); + + // 상태를 기준으로 QnA 항목 검색 (updatedAt 기준 오름차순) + @Query("SELECT new solitour_backend.solitour.admin.dto.response.QnaListResponseDto(q.id, q.title, q.createdAt, q.status, q.updatedAt, q.categoryName, u.id, u.nickname) " + + "FROM QnA q JOIN User u ON q.userId = u.id WHERE q.status = :status ORDER BY q.updatedAt ASC") + Page findByStatusOrderByUpdatedAtAsc(@Param("status") String status, Pageable pageable); + + // 상태와 무관하게 키워드와 유저 닉네임을 기준으로 QnA 항목 검색 (updatedAt 기준 오름차순) + @Query("SELECT new solitour_backend.solitour.admin.dto.response.QnaListResponseDto(q.id, q.title, q.createdAt, q.status, q.updatedAt, q.categoryName, u.id, u.nickname) " + + "FROM QnA q JOIN User u ON q.userId = u.id WHERE (q.title LIKE %:keyword% OR q.categoryName LIKE %:keyword% OR u.nickname LIKE %:keyword%) " + + "ORDER BY q.updatedAt ASC") + Page findByKeyword(@Param("keyword") String keyword, Pageable pageable); + + // 상태와 키워드, 유저 닉네임을 기준으로 QnA 항목 검색 (updatedAt 기준 오름차순) + @Query("SELECT new solitour_backend.solitour.admin.dto.response.QnaListResponseDto(q.id, q.title, q.createdAt, q.status, q.updatedAt, q.categoryName, u.id, u.nickname) " + + "FROM QnA q JOIN User u ON q.userId = u.id WHERE q.status = :status AND (q.title LIKE %:keyword% OR q.categoryName LIKE %:keyword% OR u.nickname LIKE %:keyword%) " + + "ORDER BY q.updatedAt ASC") + Page findByStatusAndKeyword(@Param("status") String status, @Param("keyword") String keyword, Pageable pageable); +} diff --git a/src/main/java/solitour_backend/solitour/admin/service/QnAService.java b/src/main/java/solitour_backend/solitour/admin/service/QnAService.java new file mode 100644 index 00000000..d964d707 --- /dev/null +++ b/src/main/java/solitour_backend/solitour/admin/service/QnAService.java @@ -0,0 +1,162 @@ +package solitour_backend.solitour.admin.service; + +import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Sort; +import org.springframework.stereotype.Service; +import solitour_backend.solitour.admin.dto.request.AnswerRegisterRequest; +import solitour_backend.solitour.admin.dto.request.QnARegisterRequest; +import solitour_backend.solitour.admin.dto.request.QuestionRegisterRequest; +import solitour_backend.solitour.admin.dto.response.QnaListResponseDto; +import solitour_backend.solitour.admin.entity.QnA; +import solitour_backend.solitour.admin.entity.QnAMessage; +import solitour_backend.solitour.admin.repository.AnswerRepository; +import solitour_backend.solitour.admin.repository.QnARepository; +import solitour_backend.solitour.error.exception.InvalidTokenException; +import solitour_backend.solitour.user.entity.User; +import solitour_backend.solitour.user.repository.UserRepository; + +import java.util.List; +import java.util.Optional; + +@Service +@RequiredArgsConstructor +public class QnAService { + + private final QnARepository qnaRepository; + private final AnswerRepository answerRepository; + private final UserRepository userRepository; + + public Long createQnA(QnARegisterRequest qnARegisterRequest, Long userId) { + +// title이 1글자보다 많은지 +// categoryName이 있는지 +// content가 1글자보다 큰지 + + User user = userRepository.findByUserId(userId); + + QnA _qna = qnaRepository.save(QnA.builder() + .title(qnARegisterRequest.getTitle()) + .status("WAIT") + .userId(userId) + .categoryName(qnARegisterRequest.getCategoryName()) + .build()); + +// _qna가 잘 저장되었는지 + + answerRepository.save(QnAMessage.builder() + .qna(_qna) + .content(qnARegisterRequest.getContent()) + .userId(userId) + .build()); + + return _qna.getId(); + } + + + public Page getPagedQnAsByUserId(Long userId, int page, int size) { + + if(userId == null) { + throw new InvalidTokenException("토큰이 유효하지 않으니 유저가 없겠지?"); + } + Pageable pageable = PageRequest.of(page, size, Sort.by(Sort.Order.desc("id"))); + return qnaRepository.findByUserId(userId, pageable); + } + + public QnA getQnAById(Long id, Long userId) { + + QnA qna = qnaRepository.findById(id).orElse(null); + if (qna == null) { + // QnA가 존재하지 않는 경우 처리 + return null; + } + + User user = userRepository.findByUserId(userId); + if (qna.getUserId() != userId && !user.getIsAdmin()) { + // 권한이 없는 경우 처리 + } + + List qnAMessages = qna.getQnaMessages(); + qna.setQnaMessages(qnAMessages); + return qna; + } + + public void closeQnA(Long id, Long userId) { + QnA qna = qnaRepository.findById(id).orElse(null); + if(qna == null) { +// qna가 없는 경우에도 경고 + } + if (qna.getUserId() != userId) { + // 권한이 없는 경우 처리 +// throw new AccessDeniedException("권한이 없습니다."); + } + qna.setStatus("CLOSED"); + qnaRepository.save(qna); + } + + public Page getQnAsByPageStatusAndKeyword(int page, String status, String keyword, Long userId) { + User user = userRepository.findByUserId(userId); + // 유저가 없거나 관리자가 아니면 밴 + if(!user.getIsAdmin()) { + return null; + } + Pageable pageable = PageRequest.of(page, 10); + Page qnaPage; + + + if ("ALL".equals(status)) { + if (keyword != null && !keyword.isEmpty()) { + return qnaRepository.findByKeyword(keyword, PageRequest.of(page, 10, Sort.by("updatedAt").ascending())); + } else { + return qnaRepository.findAllByOrderByUpdatedAtAsc(PageRequest.of(page, 10, Sort.by("updatedAt").ascending())); + } + } else { + if (keyword != null && !keyword.isEmpty()) { + return qnaRepository.findByStatusAndKeyword(status, keyword, PageRequest.of(page, 10, Sort.by("updatedAt").ascending())); + } else { + return qnaRepository.findByStatusOrderByUpdatedAtAsc(status, PageRequest.of(page, 10, Sort.by("updatedAt").ascending())); + } + } + } + + public QnAMessage createQuestion(QuestionRegisterRequest questionRegisterRequest, Long userid) { + Optional _qna = qnaRepository.findById(questionRegisterRequest.getQnaId()); + if(_qna.isEmpty()) { +// 없을 경우 에러 처리 + return null; + } + QnAMessage qnaMessage = answerRepository.save(QnAMessage.builder() + .content(questionRegisterRequest.getContent()) + .qna(_qna.get()) + .userId(userid) + .build()); +// 새로운 글을 작성했다면 상태를 다시 대기중으로 변경 + _qna.get().setStatus("WAIT"); + qnaRepository.save(_qna.get()); + return qnaMessage; + } + + public QnAMessage createAnswer(AnswerRegisterRequest answerRegisterRequest, Long userId) { + Optional _qna = qnaRepository.findById(answerRegisterRequest.getQnaId()); + if(_qna.isEmpty()) { +// 없을 경우 에러 처리 + return null; + } + User user = userRepository.findByUserId(userId); + if(!user.getIsAdmin()) { + return null; + } + + QnAMessage qnaMessage = answerRepository.save(QnAMessage.builder() + .content(answerRegisterRequest.getContent()) + .qna(_qna.get()) + .userId(userId) + .build()); +// 답변을 달았으니 변경 + _qna.get().setStatus("ANSWER"); + qnaRepository.save(_qna.get()); + return qnaMessage; + } +} \ No newline at end of file From 60bd7114f9fa46d6d1ccbb7c13f9403dfb1e9320 Mon Sep 17 00:00:00 2001 From: "SK\\ssssk" Date: Tue, 3 Sep 2024 00:56:02 +0900 Subject: [PATCH 217/371] =?UTF-8?q?fix:=20=EC=98=88=EC=99=B8=EC=B2=98?= =?UTF-8?q?=EB=A6=AC=ED=95=98=EB=A0=A4=EB=8B=A4=EA=B0=80=20=EB=82=A8?= =?UTF-8?q?=EA=B2=A8=EB=86=93=EC=9D=80=20=EB=B6=88=ED=95=84=EC=9A=94?= =?UTF-8?q?=ED=95=9C=20=EC=BD=94=EB=93=9C=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../solitour_backend/solitour/admin/service/QnAService.java | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/main/java/solitour_backend/solitour/admin/service/QnAService.java b/src/main/java/solitour_backend/solitour/admin/service/QnAService.java index d964d707..6abd9146 100644 --- a/src/main/java/solitour_backend/solitour/admin/service/QnAService.java +++ b/src/main/java/solitour_backend/solitour/admin/service/QnAService.java @@ -14,7 +14,6 @@ import solitour_backend.solitour.admin.entity.QnAMessage; import solitour_backend.solitour.admin.repository.AnswerRepository; import solitour_backend.solitour.admin.repository.QnARepository; -import solitour_backend.solitour.error.exception.InvalidTokenException; import solitour_backend.solitour.user.entity.User; import solitour_backend.solitour.user.repository.UserRepository; @@ -57,10 +56,6 @@ public Long createQnA(QnARegisterRequest qnARegisterRequest, Long userId) { public Page getPagedQnAsByUserId(Long userId, int page, int size) { - - if(userId == null) { - throw new InvalidTokenException("토큰이 유효하지 않으니 유저가 없겠지?"); - } Pageable pageable = PageRequest.of(page, size, Sort.by(Sort.Order.desc("id"))); return qnaRepository.findByUserId(userId, pageable); } From eadb1fee6cc074f5e52ea935f9ae129add2a0e75 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Tue, 3 Sep 2024 10:23:05 +0900 Subject: [PATCH 218/371] =?UTF-8?q?feat:=20enum=20=ED=81=B4=EB=9E=98?= =?UTF-8?q?=EC=8A=A4=20=ED=95=B4=EB=8B=B9=ED=95=98=EB=8A=94=20=EA=B0=92?= =?UTF-8?q?=EC=9D=B4=20=EC=97=86=EC=9C=BC=EB=A9=B4=20throw=20exception?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../solitour_backend/solitour/gathering/entity/AllowedSex.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/solitour_backend/solitour/gathering/entity/AllowedSex.java b/src/main/java/solitour_backend/solitour/gathering/entity/AllowedSex.java index 0dee7cc6..146ab721 100644 --- a/src/main/java/solitour_backend/solitour/gathering/entity/AllowedSex.java +++ b/src/main/java/solitour_backend/solitour/gathering/entity/AllowedSex.java @@ -1,6 +1,7 @@ package solitour_backend.solitour.gathering.entity; import java.util.Arrays; + import lombok.Getter; @Getter @@ -19,6 +20,6 @@ public static AllowedSex fromName(String name) { return Arrays.stream(AllowedSex.values()) .filter(e -> e.name.equals(name)) .findAny() - .orElse(null); + .orElseThrow(RuntimeException::new); } } From 71c681f015eb8006ee83d399ab3214d4bd2f0db7 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Tue, 3 Sep 2024 10:23:53 +0900 Subject: [PATCH 219/371] feat: user default image getter() --- .../solitour/user/repository/UserRepositoryCustom.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/solitour_backend/solitour/user/repository/UserRepositoryCustom.java b/src/main/java/solitour_backend/solitour/user/repository/UserRepositoryCustom.java index 34b50425..4d98c1ea 100644 --- a/src/main/java/solitour_backend/solitour/user/repository/UserRepositoryCustom.java +++ b/src/main/java/solitour_backend/solitour/user/repository/UserRepositoryCustom.java @@ -20,4 +20,6 @@ public interface UserRepositoryCustom { Page retrieveGatheringBookmark(Pageable pageable, Long userId); Page retrieveGatheringApplicant(Pageable pageable, Long userId); + + String getProfileUrl(String gender); } From ad09f6ef4846a026a70d172bf2cb60e680b5b923 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Tue, 3 Sep 2024 10:25:25 +0900 Subject: [PATCH 220/371] =?UTF-8?q?feat:=20user=20default=20image=20value?= =?UTF-8?q?=20=EA=B0=80=EC=A0=B8=EC=98=A4=EA=B3=A0=20getter?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../user/repository/UserRepositoryImpl.java | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/main/java/solitour_backend/solitour/user/repository/UserRepositoryImpl.java b/src/main/java/solitour_backend/solitour/user/repository/UserRepositoryImpl.java index 44d8ad84..4b734000 100644 --- a/src/main/java/solitour_backend/solitour/user/repository/UserRepositoryImpl.java +++ b/src/main/java/solitour_backend/solitour/user/repository/UserRepositoryImpl.java @@ -8,7 +8,10 @@ import com.querydsl.core.types.dsl.StringExpression; import com.querydsl.jpa.JPAExpressions; import com.querydsl.jpa.JPQLQuery; + import java.util.List; + +import org.springframework.beans.factory.annotation.Value; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageImpl; import org.springframework.data.domain.Pageable; @@ -39,6 +42,12 @@ public UserRepositoryImpl() { super(User.class); } + @Value("${user.profile.url.male}") + private String maleProfileUrl; + + @Value("${user.profile.url.female}") + private String femaleProfileUrl; + QInformation information = QInformation.information; QZoneCategory zoneCategoryChild = QZoneCategory.zoneCategory; QZoneCategory zoneCategoryParent = new QZoneCategory("zoneCategoryParent"); @@ -272,6 +281,16 @@ public Page retrieveGatheringApplicant(Pageable page return new PageImpl<>(list, pageable, total); } + @Override + public String getProfileUrl(String gender) { + if ("male".equalsIgnoreCase(gender)) { + return maleProfileUrl; + } else if ("female".equalsIgnoreCase(gender)) { + return femaleProfileUrl; + } + return null; // Or return a default URL + } + private StringExpression getGatheringStatus() { QGatheringApplicants gatheringApplicants = QGatheringApplicants.gatheringApplicants; return new CaseBuilder() From ceee232526b913a9487fbc879b6abd4e6cc4c431 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Tue, 3 Sep 2024 10:29:32 +0900 Subject: [PATCH 221/371] feat: user default image service --- .../information/service/InformationService.java | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/main/java/solitour_backend/solitour/information/service/InformationService.java b/src/main/java/solitour_backend/solitour/information/service/InformationService.java index 23685ef7..4b9de5cb 100644 --- a/src/main/java/solitour_backend/solitour/information/service/InformationService.java +++ b/src/main/java/solitour_backend/solitour/information/service/InformationService.java @@ -12,7 +12,6 @@ import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import org.springframework.web.multipart.MultipartFile; import solitour_backend.solitour.book_mark_information.entity.BookMarkInformationRepository; import solitour_backend.solitour.category.entity.Category; import solitour_backend.solitour.category.exception.CategoryNotExistsException; @@ -90,10 +89,9 @@ public class InformationService { private final GreatInformationRepository greatInformationRepository; private final BookMarkInformationRepository bookMarkInformationRepository; private final UserImageRepository userImageRepository; - - public static final String IMAGE_PATH = "information"; private final ImageRepository imageRepository; + @Transactional public InformationResponse registerInformation(Long userId, InformationCreateRequest informationCreateRequest) { Category category = categoryRepository.findById(informationCreateRequest.getCategoryId()) @@ -190,8 +188,14 @@ public InformationDetailResponse getDetailInformation(Long userId, Long informat boolean isLike = greatInformationRepository.existsByInformationIdAndUserId(information.getId(), userId); - //TODO - UserImage userImage = userImageRepository.findById(userId).orElse(null); + User user = userRepository.findById(userId) + .orElseThrow( + () -> new UserNotExistsException("해당하는 id의 User 가 없습니다")); + + String userImageUrl = userImageRepository.findById(userId) + .map(UserImage::getAddress) + .orElseGet( + () -> userRepository.getProfileUrl(user.getSex())); return new InformationDetailResponse( information.getTitle(), @@ -206,7 +210,7 @@ public InformationDetailResponse getDetailInformation(Long userId, Long informat zoneCategoryResponse, imageResponseList, likeCount, - Objects.requireNonNull(userImage).getAddress(), + userImageUrl, isLike, informationRecommend); } From e999a7ef6b11a1be68bafd7f1e6e0fd79d95473e Mon Sep 17 00:00:00 2001 From: Donghun Won Date: Tue, 3 Sep 2024 13:37:20 +0900 Subject: [PATCH 222/371] =?UTF-8?q?Fix=20:=20=EC=9C=A0=EC=A0=80=20?= =?UTF-8?q?=EC=A0=95=EB=B3=B4=EA=B8=80=20=EC=A1=B0=ED=9A=8C,=20=EC=9C=A0?= =?UTF-8?q?=EC=A0=80=20=EC=A0=95=EB=B3=B4=20=EB=B6=81=EB=A7=88=ED=81=AC=20?= =?UTF-8?q?=EC=A1=B0=ED=9A=8C=20=EC=95=88=EB=90=98=EB=8A=94=20=EC=98=A4?= =?UTF-8?q?=EB=A5=98=20=EC=88=98=EC=A0=95=20(#137)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Feat : 마이페이지 프로필 이미지 변경 * Feat : 마이페이지 내가 작성한 정보, 구독한 정보 조회 * Style : 코드 포맷팅 * Feat : 마이페이지 모임조회 내가 작성한 모임 조회 내가 신청한 모임 조회 내가 북마크한 모임 조회 * Feat : 유저 모임 가입 상태 필드 추가 * Style : 코드 포맷팅 * Refactor : group by 쿼리 간소화 * Refactor : 불필요한 북마크 조회 로직 삭제 * Fix : 유저 정보글 조회, 유저 정보 북마크 조회 안되는 오류 수정 isLike 구하는 로직 해당 결과 필드에 추가 --- .../controller/BookMarkGatheringController.java | 8 -------- .../service/BookMarkGatheringService.java | 6 ------ .../BookMarkInformationController.java | 8 -------- .../service/BookMarkInformationService.java | 6 ------ .../user/repository/UserRepositoryImpl.java | 17 +++++++++++++++-- 5 files changed, 15 insertions(+), 30 deletions(-) diff --git a/src/main/java/solitour_backend/solitour/book_mark_gathering/controller/BookMarkGatheringController.java b/src/main/java/solitour_backend/solitour/book_mark_gathering/controller/BookMarkGatheringController.java index 100c90c0..5aa16f1d 100644 --- a/src/main/java/solitour_backend/solitour/book_mark_gathering/controller/BookMarkGatheringController.java +++ b/src/main/java/solitour_backend/solitour/book_mark_gathering/controller/BookMarkGatheringController.java @@ -22,14 +22,6 @@ public class BookMarkGatheringController { private final BookMarkGatheringService service; - @GetMapping() - public ResponseEntity getUserBookmark( - @AuthenticationPrincipal Long userId) { - BookMarkGatheringResponse response = service.getUserBookmark(userId); - - return ResponseEntity.ok(response); - } - @Transactional @PostMapping() public ResponseEntity createUserBookmark( diff --git a/src/main/java/solitour_backend/solitour/book_mark_gathering/service/BookMarkGatheringService.java b/src/main/java/solitour_backend/solitour/book_mark_gathering/service/BookMarkGatheringService.java index 9c5f60dc..51dc047b 100644 --- a/src/main/java/solitour_backend/solitour/book_mark_gathering/service/BookMarkGatheringService.java +++ b/src/main/java/solitour_backend/solitour/book_mark_gathering/service/BookMarkGatheringService.java @@ -22,12 +22,6 @@ public class BookMarkGatheringService { private final UserRepository userRepository; private final GatheringRepository gatheringRepository; - public BookMarkGatheringResponse getUserBookmark(Long userId) { - List bookMarkInformation = bookMarkGatheringRepository.findByUserId(userId); - - return new BookMarkGatheringResponse(bookMarkInformation); - } - public void createUserBookmark(Long userId, Long gatheringId) { User user = userRepository.findByUserId(userId); Gathering gathering = gatheringRepository.findById(gatheringId) diff --git a/src/main/java/solitour_backend/solitour/book_mark_information/controller/BookMarkInformationController.java b/src/main/java/solitour_backend/solitour/book_mark_information/controller/BookMarkInformationController.java index 1d9b1081..b0f59d81 100644 --- a/src/main/java/solitour_backend/solitour/book_mark_information/controller/BookMarkInformationController.java +++ b/src/main/java/solitour_backend/solitour/book_mark_information/controller/BookMarkInformationController.java @@ -20,14 +20,6 @@ public class BookMarkInformationController { private final BookMarkInformationService service; - @GetMapping() - public ResponseEntity getUserBookmark( - @AuthenticationPrincipal Long userId) { - BookMarkInformationResponse response = service.getUserBookmark(userId); - - return ResponseEntity.ok(response); - } - @Transactional @PostMapping() public ResponseEntity createUserBookmark( diff --git a/src/main/java/solitour_backend/solitour/book_mark_information/service/BookMarkInformationService.java b/src/main/java/solitour_backend/solitour/book_mark_information/service/BookMarkInformationService.java index 22eb0dae..d7eddaf8 100644 --- a/src/main/java/solitour_backend/solitour/book_mark_information/service/BookMarkInformationService.java +++ b/src/main/java/solitour_backend/solitour/book_mark_information/service/BookMarkInformationService.java @@ -22,12 +22,6 @@ public class BookMarkInformationService { private final UserRepository userRepository; private final InformationRepository informationRepository; - public BookMarkInformationResponse getUserBookmark(Long userId) { - List bookMarkInformation = bookMarkInformationRepository.findByUserId(userId); - - return new BookMarkInformationResponse(bookMarkInformation); - } - public void createUserBookmark(Long userId, Long infoId) { User user = userRepository.findByUserId(userId); Information information = informationRepository.findById(infoId) diff --git a/src/main/java/solitour_backend/solitour/user/repository/UserRepositoryImpl.java b/src/main/java/solitour_backend/solitour/user/repository/UserRepositoryImpl.java index 4b734000..f539de05 100644 --- a/src/main/java/solitour_backend/solitour/user/repository/UserRepositoryImpl.java +++ b/src/main/java/solitour_backend/solitour/user/repository/UserRepositoryImpl.java @@ -86,7 +86,8 @@ public Page retrieveInformationOwner(Pageable pageable information.viewCount, bookMarkInformation.user.id.isNotNull(), image.address, - greatInformation.information.count().coalesce(0L).intValue() + greatInformation.information.count().coalesce(0L).intValue(), + isUserGreatInformation(userId) )) .offset(pageable.getOffset()) .limit(pageable.getPageSize()) @@ -122,7 +123,8 @@ public Page retrieveInformationBookmark(Pageable pagea information.viewCount, bookMarkInformation.user.id.isNotNull(), image.address, - greatInformation.information.count().coalesce(0L).intValue() + greatInformation.information.count().coalesce(0L).intValue(), + isUserGreatInformation(userId) )) .offset(pageable.getOffset()) .limit(pageable.getPageSize()) @@ -313,6 +315,17 @@ private NumberExpression countGreatGatheringByGatheringById() { .intValue(); } + private BooleanExpression isUserGreatInformation(Long userId) { + return new CaseBuilder() + .when(JPAExpressions.selectOne() + .from(greatInformation) + .where(greatInformation.information.id.eq(information.id) + .and(greatInformation.user.id.eq(userId))) + .exists()) + .then(true) + .otherwise(false); + } + private BooleanExpression isUserGreatGathering(Long userId) { return new CaseBuilder() .when(JPAExpressions.selectOne() From 12eead664962d494b4d3d7da3b7a84f07e692c4e Mon Sep 17 00:00:00 2001 From: Donghun Won Date: Wed, 4 Sep 2024 13:55:25 +0900 Subject: [PATCH 223/371] =?UTF-8?q?Feat(#114)=20:=20=EC=A0=95=EB=B3=B4,=20?= =?UTF-8?q?=EB=AA=A8=EC=9E=84=20=ED=83=9C=EA=B7=B8=20=EA=B2=80=EC=83=89=20?= =?UTF-8?q?=20(#138)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Feat : 태그 검색 * Refactor : 마감여부 필드 추가, 가입상태 서술 변경 * Feat : 정보 태그 검색 * Feat: 모임 태그 검색 * Style : 코드 포맷팅 * Refactor : 태그 필터 추가 공백, 특수문자 제거 한글, 영어, 숫자만 허용 From ee7afbf00a65c4368c4de2456cbacbb85c8500f9 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Wed, 4 Sep 2024 21:19:44 +0900 Subject: [PATCH 224/371] =?UTF-8?q?feat:=20image=20s3=20=EA=B0=9D=EC=B2=B4?= =?UTF-8?q?=20lifecycle=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../solitour/image/s3/S3Uploader.java | 48 ++++++++++++++++--- 1 file changed, 41 insertions(+), 7 deletions(-) diff --git a/src/main/java/solitour_backend/solitour/image/s3/S3Uploader.java b/src/main/java/solitour_backend/solitour/image/s3/S3Uploader.java index 69a74f5e..6e054873 100644 --- a/src/main/java/solitour_backend/solitour/image/s3/S3Uploader.java +++ b/src/main/java/solitour_backend/solitour/image/s3/S3Uploader.java @@ -1,12 +1,12 @@ package solitour_backend.solitour.image.s3; import com.amazonaws.services.s3.AmazonS3Client; -import com.amazonaws.services.s3.model.DeleteObjectRequest; -import com.amazonaws.services.s3.model.ObjectMetadata; -import com.amazonaws.services.s3.model.PutObjectRequest; +import com.amazonaws.services.s3.model.*; + import java.io.IOException; import java.io.InputStream; -import java.util.UUID; +import java.util.*; + import lombok.RequiredArgsConstructor; import org.springframework.beans.factory.annotation.Value; import org.springframework.http.HttpStatus; @@ -33,17 +33,46 @@ public String upload(MultipartFile multipartFile, String dirName, Long id) { metadata.setContentLength(multipartFile.getSize()); metadata.setContentType(multipartFile.getContentType()); + List tags = new ArrayList<>(); + tags.add(new Tag("temp", "true")); + + try (InputStream inputStream = multipartFile.getInputStream()) { - amazonS3Client.putObject(new PutObjectRequest(bucket, fileName, inputStream, metadata)); + PutObjectRequest putObjectRequest = + new PutObjectRequest(bucket, fileName, inputStream, metadata).withTagging(new ObjectTagging(tags)); + amazonS3Client.putObject(putObjectRequest); } catch (IOException e) { throw new ResponseStatusException(HttpStatus.INTERNAL_SERVER_ERROR, "이미지 업로드에 실패했습니다."); } return amazonS3Client.getUrl(bucket, fileName).toString(); } + public void markImagePermanent(String imageUrl) { + String fileName = extractFileNameFromUrl(imageUrl); + GetObjectTaggingRequest getTaggingRequest = new GetObjectTaggingRequest(bucket, fileName); + GetObjectTaggingResult getTaggingResult = amazonS3Client.getObjectTagging(getTaggingRequest); + List tags = getTaggingResult.getTagSet(); + + boolean tagFound = false; + + for (Tag tag : tags) { + if (tag.getKey().equals("temp")) { + tag.setValue("false"); + tagFound = true; + break; + } + } + + if (!tagFound) { + tags.add(new Tag("temp", "false")); + } + + SetObjectTaggingRequest setObjectTaggingRequest = new SetObjectTaggingRequest(bucket, fileName, new ObjectTagging(tags)); + amazonS3Client.setObjectTagging(setObjectTaggingRequest); + } + public void deleteImage(String fileUrl) { - String splitStr = ".com/"; - String fileName = fileUrl.substring(fileUrl.lastIndexOf(splitStr) + splitStr.length()); + String fileName = extractFileNameFromUrl(fileUrl); amazonS3Client.deleteObject(new DeleteObjectRequest(bucket, fileName)); } @@ -60,4 +89,9 @@ private String getFileExtension(String fileName) { throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "잘못된 형식의 파일 입니다."); } } + + private String extractFileNameFromUrl(String url) { + final String splitStr = ".com/"; + return url.substring(url.lastIndexOf(splitStr) + splitStr.length()); + } } \ No newline at end of file From 7f1c9fbdb02c814dd05bf0cdf691e4502b3e58f7 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Wed, 4 Sep 2024 21:20:30 +0900 Subject: [PATCH 225/371] =?UTF-8?q?feat:=20information=20=EB=93=B1?= =?UTF-8?q?=EB=A1=9D=EC=8B=9C=20s3=20image=20lifecycle=20=EC=A0=9C?= =?UTF-8?q?=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/InformationService.java | 26 ++++++++++--------- 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/src/main/java/solitour_backend/solitour/information/service/InformationService.java b/src/main/java/solitour_backend/solitour/information/service/InformationService.java index 4b9de5cb..9a9ea83a 100644 --- a/src/main/java/solitour_backend/solitour/information/service/InformationService.java +++ b/src/main/java/solitour_backend/solitour/information/service/InformationService.java @@ -133,25 +133,29 @@ public InformationResponse registerInformation(Long userId, InformationCreateReq ); Information saveInformation = informationRepository.save(information); + + List tags = tagMapper.mapToTags(informationCreateRequest.getTagRegisterRequests()); + List saveTags = tagRepository.saveAll(tags); + + for (Tag tag : saveTags) { + infoTagRepository.save(new InfoTag(tag, saveInformation)); + } + Image thumbImage = new Image(ImageStatus.THUMBNAIL, saveInformation, informationCreateRequest.getThumbNailImageUrl()); + imageRepository.save(thumbImage); + + s3Uploader.markImagePermanent(thumbImage.getAddress()); List contentImagesUrl = informationCreateRequest.getContentImagesUrl(); if (Objects.nonNull(contentImagesUrl) && !contentImagesUrl.isEmpty()) { List contentImageList = new ArrayList<>(); for (String contentImage : contentImagesUrl) { contentImageList.add(new Image(ImageStatus.CONTENT, saveInformation, contentImage)); + s3Uploader.markImagePermanent(contentImage); } imageRepository.saveAll(contentImageList); } - imageRepository.save(thumbImage); - - List tags = tagMapper.mapToTags(informationCreateRequest.getTagRegisterRequests()); - List saveTags = tagRepository.saveAll(tags); - - for (Tag tag : saveTags) { - infoTagRepository.save(new InfoTag(tag, saveInformation)); - } return informationMapper.mapToInformationResponse(saveInformation); } @@ -174,8 +178,7 @@ public InformationDetailResponse getDetailInformation(Long userId, Long informat .toList(); } PlaceResponse placeResponse = placeMapper.mapToPlaceResponse(information.getPlace()); - ZoneCategoryResponse zoneCategoryResponse = zoneCategoryMapper.mapToZoneCategoryResponse( - information.getZoneCategory()); + ZoneCategoryResponse zoneCategoryResponse = zoneCategoryMapper.mapToZoneCategoryResponse(information.getZoneCategory()); List images = imageRepository.findAllByInformationId(information.getId()); @@ -183,8 +186,7 @@ public InformationDetailResponse getDetailInformation(Long userId, Long informat int likeCount = greatInformationRepository.countByInformationId(information.getId()); - List informationRecommend = informationRepository.getInformationRecommend( - information.getId(), information.getCategory().getId(), userId); + List informationRecommend = informationRepository.getInformationRecommend(information.getId(), information.getCategory().getId(), userId); boolean isLike = greatInformationRepository.existsByInformationIdAndUserId(information.getId(), userId); From 582314fb84bc448f682c59f988b5accf7030feb5 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Thu, 5 Sep 2024 02:10:41 +0900 Subject: [PATCH 226/371] =?UTF-8?q?fix:=20home=20=ED=8E=98=EC=9D=B4?= =?UTF-8?q?=EC=A7=80=EC=97=90=20gathering=20=ED=98=84=EC=9E=AC=20=EC=B0=B8?= =?UTF-8?q?=EA=B0=80=20=ED=99=95=EC=A0=95=20=EC=9D=B8=EC=9B=90=20=EC=88=98?= =?UTF-8?q?=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../gathering/repository/GatheringRepositoryImpl.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryImpl.java b/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryImpl.java index a0a7f2f5..7d2e06eb 100644 --- a/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryImpl.java +++ b/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryImpl.java @@ -238,8 +238,7 @@ public List getGatheringLikeCountFromCreatedIn3(Long use .leftJoin(bookMarkGathering) .on(bookMarkGathering.gathering.id.eq(gathering.id).and(bookMarkGathering.user.id.eq(userId))) .leftJoin(category).on(category.id.eq(gathering.gatheringCategory.id)) - .leftJoin(gatheringApplicants).on(gatheringApplicants.gathering.id.eq(gathering.id) - .and(gatheringApplicants.gatheringStatus.eq(GatheringStatus.CONSENT))) + .leftJoin(gatheringApplicants).on(gatheringApplicants.gathering.id.eq(gathering.id).and(gatheringApplicants.gatheringStatus.eq(GatheringStatus.CONSENT))) .where(gathering.isFinish.eq(Boolean.FALSE) .and(gathering.isDeleted.eq(Boolean.FALSE)) .and(gathering.createdAt.after(LocalDateTime.now().minusMonths(3)))) @@ -269,7 +268,7 @@ public List getGatheringLikeCountFromCreatedIn3(Long use gathering.personCount, gatheringApplicants.count().coalesce(0L).intValue(), isUserGreatGathering(userId) - )).limit(6).fetch(); + )).limit(6L).fetch(); } //where 절 From 9a1d13679e7515e0501fd48d2cac3bcf0d482f54 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Thu, 5 Sep 2024 02:16:42 +0900 Subject: [PATCH 227/371] =?UTF-8?q?fix:=20=EB=AA=A8=EC=A7=91=EC=99=84?= =?UTF-8?q?=EB=A3=8C=20=EB=90=9C=20=EB=AA=A8=EC=9E=84=20=EC=A0=9C=EC=99=B8?= =?UTF-8?q?=20where=20=EC=A0=88=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../solitour/gathering/repository/GatheringRepositoryImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryImpl.java b/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryImpl.java index 7d2e06eb..1878ae76 100644 --- a/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryImpl.java +++ b/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryImpl.java @@ -304,7 +304,7 @@ private BooleanBuilder makeWhereSQL(GatheringPageRequest gatheringPageRequest) { } if (Objects.isNull(gatheringPageRequest.getIsExclude())) { - whereClause.and(gathering.isFinish.eq(false)); + whereClause.and(gathering.isFinish.eq(Boolean.FALSE)); } if (Objects.nonNull(gatheringPageRequest.getSearch())) { From f188edcbca74b311b620406ad19887ed434fbf7d Mon Sep 17 00:00:00 2001 From: Donghun Won Date: Thu, 5 Sep 2024 12:17:38 +0900 Subject: [PATCH 228/371] =?UTF-8?q?Feat=20(#142):=20=EB=AA=A8=EC=9E=84=20?= =?UTF-8?q?=EC=A2=8B=EC=95=84=EC=9A=94=20=EA=B8=B0=EB=8A=A5=20/=20?= =?UTF-8?q?=EB=AA=A8=EC=9E=84,=EC=A0=95=EB=B3=B4=20=EB=B6=81=EB=A7=88?= =?UTF-8?q?=ED=81=AC,=20=EC=A2=8B=EC=95=84=EC=9A=94=20=EC=A4=91=EB=B3=B5?= =?UTF-8?q?=20=EC=B2=B4=ED=81=AC=20/=20=EB=AA=A8=EC=9E=84,=EC=A0=95?= =?UTF-8?q?=EB=B3=B4=20=EB=B6=81=EB=A7=88=ED=81=AC,=EC=A2=8B=EC=95=84?= =?UTF-8?q?=EC=9A=94=20=EC=98=88=EC=99=B8,=20=EC=83=81=ED=83=9C=20?= =?UTF-8?q?=EC=BD=94=EB=93=9C=20=EC=B2=98=EB=A6=AC=20=20(#143)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Refactor : 토큰 존재하지 않을때, 유효하지 않을떄 예외 추가 * Refactor : 모임, 정보 예외 처리, 상태코드 변경 * Feat : 모임 좋아요 --- .../solitour/auth/config/AuthInterceptor.java | 17 +++++--- .../solitour/auth/config/TokenResolver.java | 1 + .../exception/TokenNotExistsException.java | 7 +++ .../exception/TokenNotValidException.java | 7 +++ .../BookMarkGatheringController.java | 11 +++-- .../GatheringBookMarkNotExistsException.java | 7 +++ .../service/BookMarkGatheringService.java | 18 ++++---- .../BookMarkInformationController.java | 11 +++-- ...InformationBookMarkNotExistsException.java | 7 +++ .../service/BookMarkInformationService.java | 10 +++-- .../error/GlobalControllerAdvice.java | 20 +++++++++ .../controller/GreatGatheringController.java | 40 +++++++++++++++++ .../entity/GreatGathering.java | 4 ++ .../GatheringGreatNotExistsException.java | 7 +++ .../repository/GreatGatheringRepository.java | 3 ++ .../service/GreatGatheringService.java | 43 +++++++++++++++++++ .../GreatInformationController.java | 11 ++--- .../InformationGreatNotExistsException.java | 7 +++ .../service/GreatInformationService.java | 14 ++---- 19 files changed, 202 insertions(+), 43 deletions(-) create mode 100644 src/main/java/solitour_backend/solitour/auth/exception/TokenNotExistsException.java create mode 100644 src/main/java/solitour_backend/solitour/auth/exception/TokenNotValidException.java create mode 100644 src/main/java/solitour_backend/solitour/book_mark_gathering/exception/GatheringBookMarkNotExistsException.java create mode 100644 src/main/java/solitour_backend/solitour/book_mark_information/exception/InformationBookMarkNotExistsException.java create mode 100644 src/main/java/solitour_backend/solitour/great_gathering/controller/GreatGatheringController.java create mode 100644 src/main/java/solitour_backend/solitour/great_gathering/exception/GatheringGreatNotExistsException.java create mode 100644 src/main/java/solitour_backend/solitour/great_gathering/service/GreatGatheringService.java create mode 100644 src/main/java/solitour_backend/solitour/great_information/exception/InformationGreatNotExistsException.java diff --git a/src/main/java/solitour_backend/solitour/auth/config/AuthInterceptor.java b/src/main/java/solitour_backend/solitour/auth/config/AuthInterceptor.java index 91d93074..093e0c92 100644 --- a/src/main/java/solitour_backend/solitour/auth/config/AuthInterceptor.java +++ b/src/main/java/solitour_backend/solitour/auth/config/AuthInterceptor.java @@ -10,6 +10,8 @@ import org.springframework.web.cors.CorsUtils; import org.springframework.web.method.HandlerMethod; import org.springframework.web.servlet.HandlerInterceptor; +import solitour_backend.solitour.auth.exception.TokenNotExistsException; +import solitour_backend.solitour.auth.exception.TokenNotValidException; import solitour_backend.solitour.auth.support.CookieExtractor; import solitour_backend.solitour.auth.support.JwtTokenProvider; @@ -30,22 +32,27 @@ public boolean preHandle(HttpServletRequest request, HttpServletResponse respons if (authenticated.isPresent()) { try { validateToken(request); - }catch (Exception e) { - response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "토큰이 유효하지 않습니다."); - return false; + }catch (TokenNotValidException e) { + throw new TokenNotExistsException("토큰이 존재하지 않습니다."); } } return true; } private Optional parseAnnotation(HandlerMethod handler, Class clazz) { - return Optional.ofNullable(handler.getMethodAnnotation(clazz)); + T methodAnnotation = handler.getMethodAnnotation(clazz); + + if (methodAnnotation == null) { + methodAnnotation = handler.getBeanType().getAnnotation(clazz); + } + + return Optional.ofNullable(methodAnnotation); } private void validateToken(HttpServletRequest request) { String token = CookieExtractor.findToken("access_token", request.getCookies()); if (jwtTokenProvider.validateTokenNotUsable(token)) { - throw new RuntimeException("토큰이 유효하지 않습니다."); + throw new TokenNotValidException("토큰이 유효하지 않습니다."); } } diff --git a/src/main/java/solitour_backend/solitour/auth/config/TokenResolver.java b/src/main/java/solitour_backend/solitour/auth/config/TokenResolver.java index 440b2779..aec87084 100644 --- a/src/main/java/solitour_backend/solitour/auth/config/TokenResolver.java +++ b/src/main/java/solitour_backend/solitour/auth/config/TokenResolver.java @@ -7,6 +7,7 @@ import org.springframework.web.context.request.NativeWebRequest; import org.springframework.web.method.support.HandlerMethodArgumentResolver; import org.springframework.web.method.support.ModelAndViewContainer; +import solitour_backend.solitour.auth.exception.TokenNotExistsException; import solitour_backend.solitour.auth.support.CookieExtractor; import solitour_backend.solitour.auth.support.JwtTokenProvider; diff --git a/src/main/java/solitour_backend/solitour/auth/exception/TokenNotExistsException.java b/src/main/java/solitour_backend/solitour/auth/exception/TokenNotExistsException.java new file mode 100644 index 00000000..2b454e17 --- /dev/null +++ b/src/main/java/solitour_backend/solitour/auth/exception/TokenNotExistsException.java @@ -0,0 +1,7 @@ +package solitour_backend.solitour.auth.exception; + +public class TokenNotExistsException extends RuntimeException { + public TokenNotExistsException(String message) { + super(message); + } +} diff --git a/src/main/java/solitour_backend/solitour/auth/exception/TokenNotValidException.java b/src/main/java/solitour_backend/solitour/auth/exception/TokenNotValidException.java new file mode 100644 index 00000000..7afc9d57 --- /dev/null +++ b/src/main/java/solitour_backend/solitour/auth/exception/TokenNotValidException.java @@ -0,0 +1,7 @@ +package solitour_backend.solitour.auth.exception; + +public class TokenNotValidException extends RuntimeException { + public TokenNotValidException(String message) { + super(message); + } +} diff --git a/src/main/java/solitour_backend/solitour/book_mark_gathering/controller/BookMarkGatheringController.java b/src/main/java/solitour_backend/solitour/book_mark_gathering/controller/BookMarkGatheringController.java index 5aa16f1d..bd3b2d29 100644 --- a/src/main/java/solitour_backend/solitour/book_mark_gathering/controller/BookMarkGatheringController.java +++ b/src/main/java/solitour_backend/solitour/book_mark_gathering/controller/BookMarkGatheringController.java @@ -9,12 +9,15 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; +import solitour_backend.solitour.auth.config.Authenticated; import solitour_backend.solitour.auth.config.AuthenticationPrincipal; import solitour_backend.solitour.book_mark_gathering.dto.response.BookMarkGatheringResponse; +import solitour_backend.solitour.book_mark_gathering.entity.BookMarkGathering; import solitour_backend.solitour.book_mark_gathering.service.BookMarkGatheringService; import solitour_backend.solitour.book_mark_information.service.BookMarkInformationService; import solitour_backend.solitour.book_mark_information.service.dto.response.BookMarkInformationResponse; +@Authenticated @RestController @RequiredArgsConstructor @RequestMapping("/api/bookmark/gathering") @@ -24,11 +27,11 @@ public class BookMarkGatheringController { @Transactional @PostMapping() - public ResponseEntity createUserBookmark( + public ResponseEntity createUserBookmark( @AuthenticationPrincipal Long userId, @RequestParam Long gatheringId) { - service.createUserBookmark(userId, gatheringId); + BookMarkGathering bookMarkGathering = service.createUserBookmark(userId, gatheringId); - return ResponseEntity.ok().build(); + return ResponseEntity.ok(bookMarkGathering.getId()); } @Transactional @@ -37,6 +40,6 @@ public ResponseEntity deleteUserBookmark(@AuthenticationPrincipal Long use @RequestParam Long gatheringId) { service.deleteUserBookmark(userId, gatheringId); - return ResponseEntity.ok().build(); + return ResponseEntity.noContent().build(); } } diff --git a/src/main/java/solitour_backend/solitour/book_mark_gathering/exception/GatheringBookMarkNotExistsException.java b/src/main/java/solitour_backend/solitour/book_mark_gathering/exception/GatheringBookMarkNotExistsException.java new file mode 100644 index 00000000..1381ce1c --- /dev/null +++ b/src/main/java/solitour_backend/solitour/book_mark_gathering/exception/GatheringBookMarkNotExistsException.java @@ -0,0 +1,7 @@ +package solitour_backend.solitour.book_mark_gathering.exception; + +public class GatheringBookMarkNotExistsException extends RuntimeException { + public GatheringBookMarkNotExistsException(String message) { + super(message); + } +} diff --git a/src/main/java/solitour_backend/solitour/book_mark_gathering/service/BookMarkGatheringService.java b/src/main/java/solitour_backend/solitour/book_mark_gathering/service/BookMarkGatheringService.java index 51dc047b..4b11406e 100644 --- a/src/main/java/solitour_backend/solitour/book_mark_gathering/service/BookMarkGatheringService.java +++ b/src/main/java/solitour_backend/solitour/book_mark_gathering/service/BookMarkGatheringService.java @@ -1,15 +1,14 @@ package solitour_backend.solitour.book_mark_gathering.service; -import jakarta.persistence.EntityNotFoundException; -import java.util.List; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import solitour_backend.solitour.book_mark_gathering.dto.response.BookMarkGatheringResponse; import solitour_backend.solitour.book_mark_gathering.entity.BookMarkGathering; +import solitour_backend.solitour.book_mark_gathering.exception.GatheringBookMarkNotExistsException; import solitour_backend.solitour.book_mark_gathering.repository.BookMarkGatheringRepository; import solitour_backend.solitour.gathering.entity.Gathering; import solitour_backend.solitour.gathering.repository.GatheringRepository; +import solitour_backend.solitour.information.exception.InformationNotExistsException; import solitour_backend.solitour.user.entity.User; import solitour_backend.solitour.user.repository.UserRepository; @@ -22,19 +21,22 @@ public class BookMarkGatheringService { private final UserRepository userRepository; private final GatheringRepository gatheringRepository; - public void createUserBookmark(Long userId, Long gatheringId) { + @Transactional + public BookMarkGathering createUserBookmark(Long userId, Long gatheringId) { User user = userRepository.findByUserId(userId); Gathering gathering = gatheringRepository.findById(gatheringId) - .orElseThrow(() -> new EntityNotFoundException("해당하는 정보가 없습니다")); - BookMarkGathering bookMarkGathering = new BookMarkGathering(user, gathering); + .orElseThrow(() -> new InformationNotExistsException("해당하는 정보가 없습니다")); - bookMarkGatheringRepository.save(bookMarkGathering); + return bookMarkGatheringRepository.findByGatheringIdAndUserId(gatheringId, userId) + .orElseGet( + () -> bookMarkGatheringRepository.save(new BookMarkGathering(user, gathering))); } + @Transactional public void deleteUserBookmark(Long userId, Long gatheringId) { BookMarkGathering bookmark = bookMarkGatheringRepository.findByGatheringIdAndUserId(gatheringId, userId) - .orElseThrow(() -> new EntityNotFoundException("해당하는 북마크가 없습니다")); + .orElseThrow(() -> new GatheringBookMarkNotExistsException("해당하는 북마크가 없습니다")); bookMarkGatheringRepository.delete(bookmark); } diff --git a/src/main/java/solitour_backend/solitour/book_mark_information/controller/BookMarkInformationController.java b/src/main/java/solitour_backend/solitour/book_mark_information/controller/BookMarkInformationController.java index b0f59d81..b8f50dbe 100644 --- a/src/main/java/solitour_backend/solitour/book_mark_information/controller/BookMarkInformationController.java +++ b/src/main/java/solitour_backend/solitour/book_mark_information/controller/BookMarkInformationController.java @@ -9,10 +9,13 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; +import solitour_backend.solitour.auth.config.Authenticated; import solitour_backend.solitour.auth.config.AuthenticationPrincipal; +import solitour_backend.solitour.book_mark_information.entity.BookMarkInformation; import solitour_backend.solitour.book_mark_information.service.BookMarkInformationService; import solitour_backend.solitour.book_mark_information.service.dto.response.BookMarkInformationResponse; +@Authenticated @RestController @RequiredArgsConstructor @RequestMapping("/api/bookmark/information") @@ -22,11 +25,11 @@ public class BookMarkInformationController { @Transactional @PostMapping() - public ResponseEntity createUserBookmark( + public ResponseEntity createUserBookmark( @AuthenticationPrincipal Long userId, @RequestParam Long infoId) { - service.createUserBookmark(userId, infoId); + BookMarkInformation bookMarkInformation = service.createUserBookmark(userId, infoId); - return ResponseEntity.ok().build(); + return ResponseEntity.ok(bookMarkInformation.getId()); } @Transactional @@ -35,6 +38,6 @@ public ResponseEntity deleteUserBookmark(@AuthenticationPrincipal Long use @RequestParam Long infoId) { service.deleteUserBookmark(userId, infoId); - return ResponseEntity.ok().build(); + return ResponseEntity.noContent().build(); } } diff --git a/src/main/java/solitour_backend/solitour/book_mark_information/exception/InformationBookMarkNotExistsException.java b/src/main/java/solitour_backend/solitour/book_mark_information/exception/InformationBookMarkNotExistsException.java new file mode 100644 index 00000000..408696aa --- /dev/null +++ b/src/main/java/solitour_backend/solitour/book_mark_information/exception/InformationBookMarkNotExistsException.java @@ -0,0 +1,7 @@ +package solitour_backend.solitour.book_mark_information.exception; + +public class InformationBookMarkNotExistsException extends RuntimeException { + public InformationBookMarkNotExistsException(String message) { + super(message); + } +} diff --git a/src/main/java/solitour_backend/solitour/book_mark_information/service/BookMarkInformationService.java b/src/main/java/solitour_backend/solitour/book_mark_information/service/BookMarkInformationService.java index d7eddaf8..7a8dc306 100644 --- a/src/main/java/solitour_backend/solitour/book_mark_information/service/BookMarkInformationService.java +++ b/src/main/java/solitour_backend/solitour/book_mark_information/service/BookMarkInformationService.java @@ -5,8 +5,10 @@ import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import solitour_backend.solitour.book_mark_gathering.entity.BookMarkGathering; import solitour_backend.solitour.book_mark_information.entity.BookMarkInformation; import solitour_backend.solitour.book_mark_information.entity.BookMarkInformationRepository; +import solitour_backend.solitour.book_mark_information.exception.InformationBookMarkNotExistsException; import solitour_backend.solitour.book_mark_information.service.dto.response.BookMarkInformationResponse; import solitour_backend.solitour.information.entity.Information; import solitour_backend.solitour.information.repository.InformationRepository; @@ -22,19 +24,19 @@ public class BookMarkInformationService { private final UserRepository userRepository; private final InformationRepository informationRepository; - public void createUserBookmark(Long userId, Long infoId) { + public BookMarkInformation createUserBookmark(Long userId, Long infoId) { User user = userRepository.findByUserId(userId); Information information = informationRepository.findById(infoId) .orElseThrow(() -> new IllegalArgumentException("해당 정보가 없습니다.")); - BookMarkInformation bookMarkInformation = new BookMarkInformation(user, information); - bookMarkInformationRepository.save(bookMarkInformation); + return bookMarkInformationRepository.findByInformationIdAndUserId(infoId, userId) + .orElseGet(() -> bookMarkInformationRepository.save(new BookMarkInformation(user, information))); } public void deleteUserBookmark(Long userId, Long infoId) { BookMarkInformation bookmark = bookMarkInformationRepository.findByInformationIdAndUserId(infoId, userId) - .orElseThrow(() -> new EntityNotFoundException("해당하는 북마크가 없습니다")); + .orElseThrow(() -> new InformationBookMarkNotExistsException("해당하는 북마크가 없습니다")); bookMarkInformationRepository.delete(bookmark); } diff --git a/src/main/java/solitour_backend/solitour/error/GlobalControllerAdvice.java b/src/main/java/solitour_backend/solitour/error/GlobalControllerAdvice.java index 73fbbc3c..4f04c056 100644 --- a/src/main/java/solitour_backend/solitour/error/GlobalControllerAdvice.java +++ b/src/main/java/solitour_backend/solitour/error/GlobalControllerAdvice.java @@ -4,6 +4,9 @@ import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.RestControllerAdvice; +import solitour_backend.solitour.auth.exception.TokenNotExistsException; +import solitour_backend.solitour.book_mark_gathering.exception.GatheringBookMarkNotExistsException; +import solitour_backend.solitour.book_mark_information.exception.InformationBookMarkNotExistsException; import solitour_backend.solitour.category.exception.CategoryNotExistsException; import solitour_backend.solitour.error.exception.RequestValidationFailedException; import solitour_backend.solitour.gathering.exception.GatheringCategoryNotExistsException; @@ -14,6 +17,8 @@ import solitour_backend.solitour.gathering_applicants.exception.GatheringApplicantsManagerException; import solitour_backend.solitour.gathering_applicants.exception.GatheringApplicantsNotExistsException; import solitour_backend.solitour.gathering_applicants.exception.GatheringNotManagerException; +import solitour_backend.solitour.great_gathering.exception.GatheringGreatNotExistsException; +import solitour_backend.solitour.great_information.exception.InformationGreatNotExistsException; import solitour_backend.solitour.image.exception.ImageAlreadyExistsException; import solitour_backend.solitour.image.exception.ImageNotExistsException; import solitour_backend.solitour.image.exception.ImageRequestValidationFailedException; @@ -60,6 +65,11 @@ public ResponseEntity conflictException(Exception exception) { GatheringNotExistsException.class, GatheringApplicantsNotExistsException.class, GatheringDeleteException.class, + InformationGreatNotExistsException.class, + InformationGreatNotExistsException.class, + GatheringGreatNotExistsException.class, + GatheringBookMarkNotExistsException.class, + InformationBookMarkNotExistsException.class }) public ResponseEntity notFoundException(Exception exception) { return ResponseEntity @@ -73,4 +83,14 @@ public ResponseEntity forbiddenException(Exception exception) { .status(HttpStatus.FORBIDDEN) .body(exception.getMessage()); } + + @ExceptionHandler({ + TokenNotExistsException.class + }) + public ResponseEntity unauthorizedException(Exception exception) { + return ResponseEntity + .status(HttpStatus.UNAUTHORIZED) + .body(exception.getMessage()); + } + } diff --git a/src/main/java/solitour_backend/solitour/great_gathering/controller/GreatGatheringController.java b/src/main/java/solitour_backend/solitour/great_gathering/controller/GreatGatheringController.java new file mode 100644 index 00000000..d498cc88 --- /dev/null +++ b/src/main/java/solitour_backend/solitour/great_gathering/controller/GreatGatheringController.java @@ -0,0 +1,40 @@ +package solitour_backend.solitour.great_gathering.controller; + +import lombok.RequiredArgsConstructor; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; +import solitour_backend.solitour.auth.config.Authenticated; +import solitour_backend.solitour.auth.config.AuthenticationPrincipal; +import solitour_backend.solitour.great_gathering.entity.GreatGathering; +import solitour_backend.solitour.great_gathering.service.GreatGatheringService; +import solitour_backend.solitour.great_information.entity.GreatInformation; +import solitour_backend.solitour.great_information.service.GreatInformationService; + +@Authenticated +@RestController +@RequiredArgsConstructor +@RequestMapping("/api/gathering/great") +public class GreatGatheringController { + + private final GreatGatheringService service; + + @PostMapping() + public ResponseEntity createGatheringGreat(@AuthenticationPrincipal Long userId, + @RequestParam Long gatheringId) { + GreatGathering greatGathering = service.createGatheringGreat(userId, gatheringId); + + return ResponseEntity.ok(greatGathering.getId()); + } + + @DeleteMapping() + public ResponseEntity deleteGatheringGreat(@AuthenticationPrincipal Long userId, + @RequestParam Long gatheringId) { + service.deleteGatheringGreat(userId, gatheringId); + + return ResponseEntity.noContent().build(); + } +} diff --git a/src/main/java/solitour_backend/solitour/great_gathering/entity/GreatGathering.java b/src/main/java/solitour_backend/solitour/great_gathering/entity/GreatGathering.java index 7ed4a264..a3712f42 100644 --- a/src/main/java/solitour_backend/solitour/great_gathering/entity/GreatGathering.java +++ b/src/main/java/solitour_backend/solitour/great_gathering/entity/GreatGathering.java @@ -35,4 +35,8 @@ public class GreatGathering { @JoinColumn(name = "gathering_id") private Gathering gathering; + public GreatGathering(User user, Gathering gathering) { + this.user = user; + this.gathering = gathering; + } } diff --git a/src/main/java/solitour_backend/solitour/great_gathering/exception/GatheringGreatNotExistsException.java b/src/main/java/solitour_backend/solitour/great_gathering/exception/GatheringGreatNotExistsException.java new file mode 100644 index 00000000..d59adad0 --- /dev/null +++ b/src/main/java/solitour_backend/solitour/great_gathering/exception/GatheringGreatNotExistsException.java @@ -0,0 +1,7 @@ +package solitour_backend.solitour.great_gathering.exception; + +public class GatheringGreatNotExistsException extends RuntimeException { + public GatheringGreatNotExistsException(String message) { + super(message); + } +} diff --git a/src/main/java/solitour_backend/solitour/great_gathering/repository/GreatGatheringRepository.java b/src/main/java/solitour_backend/solitour/great_gathering/repository/GreatGatheringRepository.java index c0a81cc3..1b9ace47 100644 --- a/src/main/java/solitour_backend/solitour/great_gathering/repository/GreatGatheringRepository.java +++ b/src/main/java/solitour_backend/solitour/great_gathering/repository/GreatGatheringRepository.java @@ -1,5 +1,6 @@ package solitour_backend.solitour.great_gathering.repository; +import java.util.Optional; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; import solitour_backend.solitour.great_gathering.entity.GreatGathering; @@ -10,4 +11,6 @@ public interface GreatGatheringRepository extends JpaRepository findByGatheringIdAndUserId(Long gatheringId, Long userId); } diff --git a/src/main/java/solitour_backend/solitour/great_gathering/service/GreatGatheringService.java b/src/main/java/solitour_backend/solitour/great_gathering/service/GreatGatheringService.java new file mode 100644 index 00000000..f6861744 --- /dev/null +++ b/src/main/java/solitour_backend/solitour/great_gathering/service/GreatGatheringService.java @@ -0,0 +1,43 @@ +package solitour_backend.solitour.great_gathering.service; + +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import solitour_backend.solitour.gathering.entity.Gathering; +import solitour_backend.solitour.gathering.exception.GatheringNotExistsException; +import solitour_backend.solitour.gathering.repository.GatheringRepository; +import solitour_backend.solitour.great_gathering.entity.GreatGathering; +import solitour_backend.solitour.great_gathering.exception.GatheringGreatNotExistsException; +import solitour_backend.solitour.great_gathering.repository.GreatGatheringRepository; +import solitour_backend.solitour.great_information.exception.InformationGreatNotExistsException; +import solitour_backend.solitour.user.entity.User; +import solitour_backend.solitour.user.repository.UserRepository; + +@Service +@RequiredArgsConstructor +@Transactional(readOnly = true) +public class GreatGatheringService { + + private final GreatGatheringRepository greatGatheringRepository; + private final UserRepository userRepository; + private final GatheringRepository gatheringRepository; + + @Transactional + public GreatGathering createGatheringGreat(Long userId, Long gatheringId) { + User user = userRepository.findByUserId(userId); + Gathering gathering = gatheringRepository.findById(gatheringId) + .orElseThrow(() -> new GatheringNotExistsException("해당 모임이 없습니다.")); + + return greatGatheringRepository.findByGatheringIdAndUserId(gatheringId, userId) + .orElseGet(() -> greatGatheringRepository.save(new GreatGathering(user, gathering))); + } + + @Transactional + public void deleteGatheringGreat(Long userId, Long gatheringId) { + GreatGathering greatGathering = greatGatheringRepository.findByGatheringIdAndUserId(gatheringId, + userId) + .orElseThrow(() -> new GatheringGreatNotExistsException("해당 모임에는 좋아요를 하지 않았습니다")); + + greatGatheringRepository.delete(greatGathering); + } +} diff --git a/src/main/java/solitour_backend/solitour/great_information/controller/GreatInformationController.java b/src/main/java/solitour_backend/solitour/great_information/controller/GreatInformationController.java index c9ca8d7e..289fafdd 100644 --- a/src/main/java/solitour_backend/solitour/great_information/controller/GreatInformationController.java +++ b/src/main/java/solitour_backend/solitour/great_information/controller/GreatInformationController.java @@ -8,11 +8,13 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; +import solitour_backend.solitour.auth.config.Authenticated; import solitour_backend.solitour.auth.config.AuthenticationPrincipal; import solitour_backend.solitour.great_information.dto.response.GreatInformationResponse; import solitour_backend.solitour.great_information.entity.GreatInformation; import solitour_backend.solitour.great_information.service.GreatInformationService; +@Authenticated @RestController @RequiredArgsConstructor @RequestMapping("/api/information/great") @@ -20,13 +22,6 @@ public class GreatInformationController { private final GreatInformationService service; - @GetMapping() - public ResponseEntity getInformationGreatCount(@AuthenticationPrincipal Long userId) { - GreatInformationResponse response = service.getInformationGreatCount(userId); - - return ResponseEntity.ok(response); - } - @PostMapping() public ResponseEntity createInformationGreat(@AuthenticationPrincipal Long userId, @RequestParam Long infoId) { @@ -40,6 +35,6 @@ public ResponseEntity deleteInformationGreat(@AuthenticationPrincipal Long @RequestParam Long infoId) { service.deleteInformationGreat(userId, infoId); - return ResponseEntity.ok().build(); + return ResponseEntity.noContent().build(); } } diff --git a/src/main/java/solitour_backend/solitour/great_information/exception/InformationGreatNotExistsException.java b/src/main/java/solitour_backend/solitour/great_information/exception/InformationGreatNotExistsException.java new file mode 100644 index 00000000..2bdf044d --- /dev/null +++ b/src/main/java/solitour_backend/solitour/great_information/exception/InformationGreatNotExistsException.java @@ -0,0 +1,7 @@ +package solitour_backend.solitour.great_information.exception; + +public class InformationGreatNotExistsException extends RuntimeException { + public InformationGreatNotExistsException(String message) { + super(message); + } +} diff --git a/src/main/java/solitour_backend/solitour/great_information/service/GreatInformationService.java b/src/main/java/solitour_backend/solitour/great_information/service/GreatInformationService.java index d583da6f..8bdc402b 100644 --- a/src/main/java/solitour_backend/solitour/great_information/service/GreatInformationService.java +++ b/src/main/java/solitour_backend/solitour/great_information/service/GreatInformationService.java @@ -1,13 +1,13 @@ package solitour_backend.solitour.great_information.service; -import jakarta.persistence.EntityNotFoundException; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import solitour_backend.solitour.great_information.dto.response.GreatInformationResponse; import solitour_backend.solitour.great_information.entity.GreatInformation; +import solitour_backend.solitour.great_information.exception.InformationGreatNotExistsException; import solitour_backend.solitour.great_information.repository.GreatInformationRepository; import solitour_backend.solitour.information.entity.Information; +import solitour_backend.solitour.information.exception.InformationNotExistsException; import solitour_backend.solitour.information.repository.InformationRepository; import solitour_backend.solitour.user.entity.User; import solitour_backend.solitour.user.repository.UserRepository; @@ -21,17 +21,11 @@ public class GreatInformationService { private final UserRepository userRepository; private final InformationRepository informationRepository; - public GreatInformationResponse getInformationGreatCount(Long informationId) { - int greatInformation = greatInformationRepository.countByInformationId(informationId); - - return new GreatInformationResponse(greatInformation); - } - @Transactional public GreatInformation createInformationGreat(Long userId, Long infoId) { User user = userRepository.findByUserId(userId); Information information = informationRepository.findById(infoId) - .orElseThrow(() -> new IllegalArgumentException("해당 정보가 없습니다.")); + .orElseThrow(() -> new InformationNotExistsException("해당 정보가 없습니다.")); return greatInformationRepository.findByInformationIdAndUserId(infoId, userId) .orElseGet( @@ -42,7 +36,7 @@ public GreatInformation createInformationGreat(Long userId, Long infoId) { public void deleteInformationGreat(Long userId, Long infoId) { GreatInformation greatInformation = greatInformationRepository.findByInformationIdAndUserId(infoId, userId) - .orElseThrow(() -> new EntityNotFoundException("해당 정보에는 좋아요를 하지 않았습니다")); + .orElseThrow(() -> new InformationGreatNotExistsException("해당 정보에는 좋아요를 하지 않았습니다")); greatInformationRepository.delete(greatInformation); } From d82a44c2f2dbc5a95aa066ae2ec2220d0a20475c Mon Sep 17 00:00:00 2001 From: Donghun Won Date: Thu, 5 Sep 2024 12:40:13 +0900 Subject: [PATCH 229/371] =?UTF-8?q?Fix=20:=20=EB=82=B4=EA=B0=80=20?= =?UTF-8?q?=EC=8B=A0=EC=B2=AD=ED=95=9C=20=EB=AA=A8=EC=9E=84=20=EC=A1=B0?= =?UTF-8?q?=ED=9A=8C=EC=8B=9C=20=EB=82=B4=EA=B0=80=20=EB=AA=A8=EC=A7=91?= =?UTF-8?q?=ED=95=9C=20=EB=AA=A8=EC=9E=84=20=EC=A0=9C=EC=99=B8=ED=95=98?= =?UTF-8?q?=EB=8F=84=EB=A1=9D=20=EC=88=98=EC=A0=95=20(#145)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../solitour/user/controller/UserController.java | 7 +------ .../solitour/user/repository/UserRepositoryImpl.java | 2 +- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/src/main/java/solitour_backend/solitour/user/controller/UserController.java b/src/main/java/solitour_backend/solitour/user/controller/UserController.java index cad40666..cbffb9e7 100644 --- a/src/main/java/solitour_backend/solitour/user/controller/UserController.java +++ b/src/main/java/solitour_backend/solitour/user/controller/UserController.java @@ -32,6 +32,7 @@ import solitour_backend.solitour.user.service.UserService; import solitour_backend.solitour.user.service.dto.response.UserInfoResponse; +@Authenticated @RestController @RequiredArgsConstructor @RequestMapping("/api/users") @@ -44,7 +45,6 @@ public class UserController { public static final int PAGE_SIZE = 6; - @Authenticated @GetMapping("/info") public ResponseEntity retrieveUserInfo(@AuthenticationPrincipal Long userId) { UserInfoResponse response = userService.retrieveUserInfo(userId); @@ -52,7 +52,6 @@ public ResponseEntity retrieveUserInfo(@AuthenticationPrincipa return ResponseEntity.ok(response); } - @Authenticated @PutMapping("/nickname") public ResponseEntity updateNickname(@AuthenticationPrincipal Long userId, @RequestBody UpdateNicknameRequest request) { @@ -68,7 +67,6 @@ public ResponseEntity updateNickname(@AuthenticationPrincipal Long userI } } - @Authenticated @PutMapping("/age-sex") public ResponseEntity updateAgeAndSex(@AuthenticationPrincipal Long userId, @RequestBody UpdateAgeAndSex request) { @@ -90,7 +88,6 @@ public ResponseEntity updateUserProfile(@AuthenticationPrincipal Long user return ResponseEntity.ok().build(); } - @Authenticated @DeleteMapping() public ResponseEntity deleteUser(HttpServletResponse response, @AuthenticationPrincipal Long id, @RequestParam String type, @@ -109,7 +106,6 @@ public ResponseEntity deleteUser(HttpServletResponse response, @Authenti } } - @Authenticated @GetMapping("/mypage/information/owner") public ResponseEntity> retrieveInformationOwner( @RequestParam(defaultValue = "0") int page, @@ -132,7 +128,6 @@ public ResponseEntity> retrieveInformationBookmar return ResponseEntity.ok(response); } - @Authenticated @GetMapping("/mypage/gathering/host") public ResponseEntity> retrieveGatheringHost( @RequestParam(defaultValue = "0") int page, diff --git a/src/main/java/solitour_backend/solitour/user/repository/UserRepositoryImpl.java b/src/main/java/solitour_backend/solitour/user/repository/UserRepositoryImpl.java index f539de05..6c5c81b3 100644 --- a/src/main/java/solitour_backend/solitour/user/repository/UserRepositoryImpl.java +++ b/src/main/java/solitour_backend/solitour/user/repository/UserRepositoryImpl.java @@ -247,7 +247,7 @@ public Page retrieveGatheringApplicant(Pageable page .leftJoin(gatheringApplicants) .on(gatheringApplicants.gathering.id.eq(gathering.id)) .orderBy(gathering.createdAt.desc()) - .where(gatheringApplicants.user.id.eq(userId)); + .where(gatheringApplicants.user.id.eq(userId).and(gathering.user.id.eq(userId).not())); List list = query .groupBy(gathering.id, zoneCategoryParent.id, zoneCategoryChild.id, From 466b5ffb71696b8aca09a41451abc18e2d365b6f Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Fri, 6 Sep 2024 16:28:54 +0900 Subject: [PATCH 230/371] =?UTF-8?q?feat:=20=EB=AA=A8=EC=9E=84=20=EC=95=84?= =?UTF-8?q?=EC=A7=81=20=EC=95=88=EB=81=9D=EB=82=AC=EB=8B=A4=EA=B3=A0=20?= =?UTF-8?q?=EC=88=98=EC=A0=95=ED=95=A0=EB=95=8C=20=EB=A7=88=EA=B0=90?= =?UTF-8?q?=EC=9D=BC=20=EB=B3=80=EA=B2=BD=20request=20dto?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dto/request/GatheringNotFinishRequest.java | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 src/main/java/solitour_backend/solitour/gathering/dto/request/GatheringNotFinishRequest.java diff --git a/src/main/java/solitour_backend/solitour/gathering/dto/request/GatheringNotFinishRequest.java b/src/main/java/solitour_backend/solitour/gathering/dto/request/GatheringNotFinishRequest.java new file mode 100644 index 00000000..b69abb0d --- /dev/null +++ b/src/main/java/solitour_backend/solitour/gathering/dto/request/GatheringNotFinishRequest.java @@ -0,0 +1,17 @@ +package solitour_backend.solitour.gathering.dto.request; + +import com.fasterxml.jackson.annotation.JsonFormat; +import lombok.Getter; +import lombok.NoArgsConstructor; +import org.springframework.format.annotation.DateTimeFormat; + +import java.time.LocalDateTime; + +@Getter +@NoArgsConstructor +public class GatheringNotFinishRequest { + + @JsonFormat(pattern = "yyyy-MM-dd HH:mm") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm") + private LocalDateTime deadline; +} From ebc7f6d8fee531746a311edf743ed60512ec756d Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Fri, 6 Sep 2024 16:29:14 +0900 Subject: [PATCH 231/371] =?UTF-8?q?feat:=20=EB=A7=88=EA=B0=90=EC=9D=BC=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 --- .../solitour/gathering/service/GatheringService.java | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/main/java/solitour_backend/solitour/gathering/service/GatheringService.java b/src/main/java/solitour_backend/solitour/gathering/service/GatheringService.java index 3836b440..107d0188 100644 --- a/src/main/java/solitour_backend/solitour/gathering/service/GatheringService.java +++ b/src/main/java/solitour_backend/solitour/gathering/service/GatheringService.java @@ -15,6 +15,7 @@ import solitour_backend.solitour.error.exception.RequestValidationFailedException; import solitour_backend.solitour.gathering.dto.mapper.GatheringMapper; import solitour_backend.solitour.gathering.dto.request.GatheringModifyRequest; +import solitour_backend.solitour.gathering.dto.request.GatheringNotFinishRequest; import solitour_backend.solitour.gathering.dto.request.GatheringPageRequest; import solitour_backend.solitour.gathering.dto.request.GatheringRegisterRequest; import solitour_backend.solitour.gathering.dto.response.GatheringBriefResponse; @@ -374,7 +375,7 @@ public void setGatheringFinish(Long userId, Long gatheringId) { gathering.setIsFinish(true); } - public void setGatheringNotFinish(Long userId, Long gatheringId) { + public void setGatheringNotFinish(Long userId, Long gatheringId, GatheringNotFinishRequest gatheringNotFinishRequest) { Gathering gathering = gatheringRepository.findById(gatheringId) .orElseThrow( () -> new GatheringNotExistsException("해당하는 id의 gathering 이 존재 하지 않습니다")); @@ -395,6 +396,14 @@ public void setGatheringNotFinish(Long userId, Long gatheringId) { throw new GatheringFinishConflictException("이미 모임이 not finish 상태입니다"); } + if (gathering.getScheduleStartDate().isBefore(gatheringNotFinishRequest.getDeadline())) { + throw new RequestValidationFailedException("마감일은 시작 날짜 보다 나중일 순 없습니다"); + } + + if (Objects.nonNull(gatheringNotFinishRequest.getDeadline())) { + gathering.setDeadline(gatheringNotFinishRequest.getDeadline()); + } + gathering.setIsFinish(false); } From f42b9c9f17b6b63848dc9cc35d80838af8cbc846 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Fri, 6 Sep 2024 16:29:35 +0900 Subject: [PATCH 232/371] feat: Request body GatheringNotFinishRequest --- .../gathering/controller/GatheringController.java | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/main/java/solitour_backend/solitour/gathering/controller/GatheringController.java b/src/main/java/solitour_backend/solitour/gathering/controller/GatheringController.java index 73918250..bc778053 100644 --- a/src/main/java/solitour_backend/solitour/gathering/controller/GatheringController.java +++ b/src/main/java/solitour_backend/solitour/gathering/controller/GatheringController.java @@ -33,6 +33,7 @@ import solitour_backend.solitour.error.Utils; import solitour_backend.solitour.error.exception.RequestValidationFailedException; import solitour_backend.solitour.gathering.dto.request.GatheringModifyRequest; +import solitour_backend.solitour.gathering.dto.request.GatheringNotFinishRequest; import solitour_backend.solitour.gathering.dto.request.GatheringPageRequest; import solitour_backend.solitour.gathering.dto.request.GatheringRegisterRequest; import solitour_backend.solitour.gathering.dto.response.GatheringBriefResponse; @@ -176,8 +177,12 @@ public ResponseEntity gatheringFinish(@AuthenticationPrincipal Long userId @PutMapping("/not-finish/{gatheringId}") public ResponseEntity gatheringNotFinish(@AuthenticationPrincipal Long userId, - @PathVariable Long gatheringId) { - gatheringService.setGatheringNotFinish(userId, gatheringId); + @PathVariable Long gatheringId, + @RequestBody GatheringNotFinishRequest gatheringNotFinishRequest, + BindingResult bindingResult) { + Utils.validationRequest(bindingResult); + + gatheringService.setGatheringNotFinish(userId, gatheringId, gatheringNotFinishRequest); return ResponseEntity .status(HttpStatus.NO_CONTENT) From 7318b581dba69e04a2aa133951c9862c87dbc109 Mon Sep 17 00:00:00 2001 From: Donghun Won Date: Sat, 7 Sep 2024 13:05:16 +0900 Subject: [PATCH 233/371] =?UTF-8?q?Fix=20:=20=ED=83=9C=EA=B7=B8=20?= =?UTF-8?q?=EA=B2=80=EC=83=89=20=EC=9D=B8=EC=BD=94=EB=94=A9=20=EB=B0=A9?= =?UTF-8?q?=EC=8B=9D=20=EB=B3=80=EA=B2=BD=20(#149)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit url인코딩, 디코딩 방식으로 변경 --- .../gathering/controller/GatheringController.java | 9 +++++---- .../information/controller/InformationController.java | 9 +++++---- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/src/main/java/solitour_backend/solitour/gathering/controller/GatheringController.java b/src/main/java/solitour_backend/solitour/gathering/controller/GatheringController.java index bc778053..27dc3be0 100644 --- a/src/main/java/solitour_backend/solitour/gathering/controller/GatheringController.java +++ b/src/main/java/solitour_backend/solitour/gathering/controller/GatheringController.java @@ -5,6 +5,7 @@ import jakarta.servlet.http.HttpServletRequest; import jakarta.validation.Valid; +import java.io.UnsupportedEncodingException; import java.time.LocalDateTime; import java.util.Base64; import java.util.List; @@ -143,10 +144,10 @@ public ResponseEntity> getPageGatheringByTag(@Reque @Valid @ModelAttribute GatheringPageRequest gatheringPageRequest, @RequestParam(required = false, name = "tagName") String tag, BindingResult bindingResult, - HttpServletRequest request) { - byte[] decodedBytes = Base64.getUrlDecoder().decode(tag); - String decodedTag = new String(decodedBytes); - String filteredTag = decodedTag.replaceAll("[^a-zA-Z0-9가-힣]", ""); + HttpServletRequest request) + throws UnsupportedEncodingException { + String decodedValue = java.net.URLDecoder.decode(tag, "UTF-8"); + String filteredTag = decodedValue.replaceAll("[^a-zA-Z0-9가-힣]", ""); Utils.validationRequest(bindingResult); Long userId = findUser(request); diff --git a/src/main/java/solitour_backend/solitour/information/controller/InformationController.java b/src/main/java/solitour_backend/solitour/information/controller/InformationController.java index 5bb0517d..35fb4ce8 100644 --- a/src/main/java/solitour_backend/solitour/information/controller/InformationController.java +++ b/src/main/java/solitour_backend/solitour/information/controller/InformationController.java @@ -4,6 +4,7 @@ import jakarta.servlet.http.HttpServletRequest; import jakarta.validation.Valid; +import java.io.UnsupportedEncodingException; import java.util.Base64; import java.util.List; import java.util.Objects; @@ -136,10 +137,10 @@ public ResponseEntity> getPageInformationByTag(@R @Valid @ModelAttribute InformationPageRequest informationPageRequest, @RequestParam(required = false, name = "tagName") String tag, BindingResult bindingResult, - HttpServletRequest request) { - byte[] decodedBytes = Base64.getUrlDecoder().decode(tag); - String decodedTag = new String(decodedBytes); - String filteredTag = decodedTag.replaceAll("[^a-zA-Z0-9가-힣]", ""); + HttpServletRequest request) + throws UnsupportedEncodingException { + String decodedValue = java.net.URLDecoder.decode(tag, "UTF-8"); + String filteredTag = decodedValue.replaceAll("[^a-zA-Z0-9가-힣]", ""); Utils.validationRequest(bindingResult); Long userId = findUser(request); From 61052d66335df0185bc1790e9e6c27afd4afc799 Mon Sep 17 00:00:00 2001 From: Donghun Won Date: Sat, 7 Sep 2024 14:08:39 +0900 Subject: [PATCH 234/371] =?UTF-8?q?Refactor(#150)=20:=20=ED=9A=8C=EC=9B=90?= =?UTF-8?q?=20=ED=83=88=ED=87=B4=20=EA=B8=B0=EB=8A=A5=20=ED=96=A5=EC=83=81?= =?UTF-8?q?=20(#151)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Refactor: 최근 로그인 시간 기록, 카카오 로그인 닉네임 랜덤하게 설정 * Feat : 회원 탈퇴 유저 이미지 디폴트 이미지로 변경 유저 정보 null로 변경 s3에 저장된 유저 이미지 삭제 --- .../solitour/auth/service/OauthService.java | 3 +- .../user/controller/UserController.java | 1 - .../solitour/user/entity/User.java | 12 ++++++- .../solitour/user/service/UserService.java | 36 +++++++++++++++++-- .../solitour/user_image/entity/UserImage.java | 4 +++ 5 files changed, 51 insertions(+), 5 deletions(-) diff --git a/src/main/java/solitour_backend/solitour/auth/service/OauthService.java b/src/main/java/solitour_backend/solitour/auth/service/OauthService.java index eac6c057..35737182 100644 --- a/src/main/java/solitour_backend/solitour/auth/service/OauthService.java +++ b/src/main/java/solitour_backend/solitour/auth/service/OauthService.java @@ -55,6 +55,7 @@ public OauthLinkResponse generateAuthUrl(String type, String redirectUrl) { @Transactional public LoginResponse requestAccessToken(String type, String code, String redirectUrl) { User user = checkAndSaveUser(type, code, redirectUrl); + user.updateLoginTime(); final int ACCESS_COOKIE_AGE = (int) TimeUnit.MINUTES.toSeconds(30); final int REFRESH_COOKIE_AGE = (int) TimeUnit.DAYS.toSeconds(30); @@ -139,7 +140,7 @@ private User saveKakaoUser(KakaoUserResponse response) { .isAdmin(false) .userImage(savedUserImage) .name(response.getKakaoAccount().getName()) - .nickname(response.getKakaoAccount().getProfile().getNickName()) + .nickname(RandomNickName.generateRandomNickname()) .age(Integer.valueOf(response.getKakaoAccount().getBirthYear())) .sex(response.getKakaoAccount().getGender()) .email(response.getKakaoAccount().getEmail()) diff --git a/src/main/java/solitour_backend/solitour/user/controller/UserController.java b/src/main/java/solitour_backend/solitour/user/controller/UserController.java index cbffb9e7..fc4fd033 100644 --- a/src/main/java/solitour_backend/solitour/user/controller/UserController.java +++ b/src/main/java/solitour_backend/solitour/user/controller/UserController.java @@ -162,7 +162,6 @@ public ResponseEntity> retrieveGatheringApplica return ResponseEntity.ok(response); } - private String getOauthAccessToken(String type, String code, String redirectUrl) { String token = ""; switch (type) { diff --git a/src/main/java/solitour_backend/solitour/user/entity/User.java b/src/main/java/solitour_backend/solitour/user/entity/User.java index a4b28417..c6d76671 100644 --- a/src/main/java/solitour_backend/solitour/user/entity/User.java +++ b/src/main/java/solitour_backend/solitour/user/entity/User.java @@ -85,12 +85,22 @@ public void updateAgeAndSex(String age, String sex) { this.sex = sex; } - public void deleteUser(Long userId) { + public void deleteUser() { this.userStatus = UserStatus.DELETE; + this.oauthId = null; + this.provider = null; + this.name = null; + this.age = null; + this.phoneNumber = null; + this.email = null; this.deletedAt = LocalDateTime.now(); } public void updateUserImage(String imageUrl) { this.userImage.updateUserImage(imageUrl); } + + public void updateLoginTime() { + this.latestLoginAt = LocalDateTime.now(); + } } diff --git a/src/main/java/solitour_backend/solitour/user/service/UserService.java b/src/main/java/solitour_backend/solitour/user/service/UserService.java index d69f34ef..dfa2073b 100644 --- a/src/main/java/solitour_backend/solitour/user/service/UserService.java +++ b/src/main/java/solitour_backend/solitour/user/service/UserService.java @@ -1,6 +1,7 @@ package solitour_backend.solitour.user.service; import lombok.RequiredArgsConstructor; +import org.springframework.beans.factory.annotation.Value; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Service; @@ -8,12 +9,14 @@ import org.springframework.web.multipart.MultipartFile; import solitour_backend.solitour.gathering.dto.response.GatheringApplicantResponse; import solitour_backend.solitour.gathering.dto.response.GatheringBriefResponse; +import solitour_backend.solitour.image.s3.S3Uploader; import solitour_backend.solitour.information.dto.response.InformationBriefResponse; import solitour_backend.solitour.user.entity.User; import solitour_backend.solitour.user.exception.NicknameAlreadyExistsException; import solitour_backend.solitour.user.repository.UserRepository; import solitour_backend.solitour.user.service.dto.response.UserInfoResponse; import solitour_backend.solitour.user_image.dto.UserImageResponse; +import solitour_backend.solitour.user_image.entity.UserImage; import solitour_backend.solitour.user_image.entity.UserImageRepository; import solitour_backend.solitour.user_image.service.UserImageService; @@ -25,6 +28,11 @@ public class UserService { private final UserRepository userRepository; private final UserImageService userImageService; private final UserImageRepository userImageRepository; + private final S3Uploader s3Uploader; + @Value("${user.profile.url.female}") + private String femaleProfileUrl; + @Value("${user.profile.url.male}") + private String maleProfileUrl; public UserInfoResponse retrieveUserInfo(Long userId) { User user = userRepository.findByUserId(userId); @@ -47,11 +55,12 @@ public void updateAgeAndSex(Long userId, String age, String sex) { user.updateAgeAndSex(age, sex); } - @Transactional public void deleteUser(Long userId) { User user = userRepository.findByUserId(userId); - user.deleteUser(userId); + UserImage userImage = userImageRepository.findById(user.getUserImage().getId()).orElseThrow(); + changeToDefaultProfile(user, userImage); + user.deleteUser(); } public Page retrieveInformationOwner(Pageable pageable, Long userId) { @@ -80,4 +89,27 @@ public Page retrieveGatheringBookmark(Pageable pageable, public Page retrieveGatheringApplicant(Pageable pageable, Long userId) { return userRepository.retrieveGatheringApplicant(pageable, userId); } + + private void changeToDefaultProfile(User user, UserImage userImage) { + String defaultImageUrl = getDefaultProfile(user); + deleteUserProfileFromS3(userImage,defaultImageUrl); + } + + private String getDefaultProfile(User user) { + String sex = user.getSex(); + if(sex.equals("male")){{ + return maleProfileUrl; + }} else { + return femaleProfileUrl; + } + } + + private void deleteUserProfileFromS3(UserImage userImage,String defaultImageUrl) { + String userImageUrl = userImage.getAddress(); + if(userImageUrl.equals(femaleProfileUrl) || userImageUrl.equals(maleProfileUrl)){ + return; + } + s3Uploader.deleteImage(userImageUrl); + userImage.changeToDefaultProfile(defaultImageUrl); + } } diff --git a/src/main/java/solitour_backend/solitour/user_image/entity/UserImage.java b/src/main/java/solitour_backend/solitour/user_image/entity/UserImage.java index 7f0d4cce..10418f95 100644 --- a/src/main/java/solitour_backend/solitour/user_image/entity/UserImage.java +++ b/src/main/java/solitour_backend/solitour/user_image/entity/UserImage.java @@ -35,4 +35,8 @@ public UserImage(String address, LocalDate createdDate) { public void updateUserImage(String imageUrl) { this.address = imageUrl; } + + public void changeToDefaultProfile(String defaultImageUrl) { + this.address = defaultImageUrl; + } } From cf48490a3f49dfc0628181837c0ff35f9829aa6b Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Sat, 7 Sep 2024 14:33:51 +0900 Subject: [PATCH 235/371] =?UTF-8?q?feat:=20=EB=AA=A8=EC=9E=84=20=ED=85=8C?= =?UTF-8?q?=EC=9D=B4=EB=B8=94=20=EC=98=A4=ED=94=88=20=EC=B1=84=ED=8C=85=20?= =?UTF-8?q?=EB=A7=81=ED=81=AC=20=EC=BB=AC=EB=9F=BC=20=EC=B6=94=EA=B0=80?= =?UTF-8?q?=EB=A1=9C=20=EC=9D=B8=ED=95=B4=20entity=20=ED=95=84=EB=93=9C=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../solitour/gathering/entity/Gathering.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/main/java/solitour_backend/solitour/gathering/entity/Gathering.java b/src/main/java/solitour_backend/solitour/gathering/entity/Gathering.java index d0ee7598..7f8368ba 100644 --- a/src/main/java/solitour_backend/solitour/gathering/entity/Gathering.java +++ b/src/main/java/solitour_backend/solitour/gathering/entity/Gathering.java @@ -99,10 +99,13 @@ public class Gathering { @Column(name = "gathering_is_deleted") private Boolean isDeleted; + @Column(name = "gathering_open_chatting_url") + private String openChattingUrl; + public Gathering(User user, ZoneCategory zoneCategory, GatheringCategory gatheringCategory, Place place, String title, String content, Integer personCount, Integer viewCount, LocalDateTime scheduleStartDate, LocalDateTime scheduleEndDate, Boolean isFinish, - LocalDateTime deadline, AllowedSex allowedSex, Integer startAge, Integer endAge) { + LocalDateTime deadline, AllowedSex allowedSex, Integer startAge, Integer endAge, String openChattingUrl) { this.user = user; this.zoneCategory = zoneCategory; this.gatheringCategory = gatheringCategory; @@ -119,5 +122,6 @@ public Gathering(User user, ZoneCategory zoneCategory, GatheringCategory gatheri this.startAge = startAge; this.endAge = endAge; this.isDeleted = false; + this.openChattingUrl = openChattingUrl; } } From e41e8b1e7cb7dd30211715e6db2b4af4cdb7ad43 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Sat, 7 Sep 2024 15:00:15 +0900 Subject: [PATCH 236/371] =?UTF-8?q?refactor:=20=EB=A7=88=EA=B0=90=EC=9D=BC?= =?UTF-8?q?=20=EC=88=98=EC=A0=95=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../solitour/gathering/controller/GatheringController.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/java/solitour_backend/solitour/gathering/controller/GatheringController.java b/src/main/java/solitour_backend/solitour/gathering/controller/GatheringController.java index bc778053..6d4911ac 100644 --- a/src/main/java/solitour_backend/solitour/gathering/controller/GatheringController.java +++ b/src/main/java/solitour_backend/solitour/gathering/controller/GatheringController.java @@ -178,11 +178,10 @@ public ResponseEntity gatheringFinish(@AuthenticationPrincipal Long userId @PutMapping("/not-finish/{gatheringId}") public ResponseEntity gatheringNotFinish(@AuthenticationPrincipal Long userId, @PathVariable Long gatheringId, - @RequestBody GatheringNotFinishRequest gatheringNotFinishRequest, BindingResult bindingResult) { Utils.validationRequest(bindingResult); - gatheringService.setGatheringNotFinish(userId, gatheringId, gatheringNotFinishRequest); + gatheringService.setGatheringNotFinish(userId, gatheringId); return ResponseEntity .status(HttpStatus.NO_CONTENT) From f6b0ef605c2ab56be4c314bdaed9dd9236a3f2f8 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Sat, 7 Sep 2024 15:00:50 +0900 Subject: [PATCH 237/371] =?UTF-8?q?feat:=20=EB=AA=A8=EC=9E=84=20=ED=85=8C?= =?UTF-8?q?=EC=9D=B4=EB=B8=94=20=EC=98=A4=ED=94=88=20=EC=B1=84=ED=8C=85=20?= =?UTF-8?q?=EB=A7=81=ED=81=AC=20=EC=BB=AC=EB=9F=BC=20=EC=B6=94=EA=B0=80?= =?UTF-8?q?=EB=A1=9C=20=EC=9D=B8=ED=95=B4=20request=20dto=20=ED=95=84?= =?UTF-8?q?=EB=93=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../gathering/dto/request/GatheringModifyRequest.java | 6 ++++++ .../gathering/dto/request/GatheringRegisterRequest.java | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/src/main/java/solitour_backend/solitour/gathering/dto/request/GatheringModifyRequest.java b/src/main/java/solitour_backend/solitour/gathering/dto/request/GatheringModifyRequest.java index 366e042f..ee6c2509 100644 --- a/src/main/java/solitour_backend/solitour/gathering/dto/request/GatheringModifyRequest.java +++ b/src/main/java/solitour_backend/solitour/gathering/dto/request/GatheringModifyRequest.java @@ -6,8 +6,10 @@ import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.Size; + import java.time.LocalDateTime; import java.util.List; + import lombok.Getter; import lombok.NoArgsConstructor; import org.springframework.format.annotation.DateTimeFormat; @@ -67,4 +69,8 @@ public class GatheringModifyRequest { private String zoneCategoryNameChild; private List tagRegisterRequests; + + @NotBlank + @Size(min = 1, max = 255) + private String openChattingUrl; } diff --git a/src/main/java/solitour_backend/solitour/gathering/dto/request/GatheringRegisterRequest.java b/src/main/java/solitour_backend/solitour/gathering/dto/request/GatheringRegisterRequest.java index c3815d9c..7e21ba20 100644 --- a/src/main/java/solitour_backend/solitour/gathering/dto/request/GatheringRegisterRequest.java +++ b/src/main/java/solitour_backend/solitour/gathering/dto/request/GatheringRegisterRequest.java @@ -6,8 +6,10 @@ import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.Size; + import java.time.LocalDateTime; import java.util.List; + import lombok.Getter; import lombok.NoArgsConstructor; import org.springframework.format.annotation.DateTimeFormat; @@ -67,4 +69,8 @@ public class GatheringRegisterRequest { private String zoneCategoryNameChild; private List tagRegisterRequests; + + @NotBlank + @Size(min = 1, max = 255) + private String openChattingUrl; } From 992e7e42d5dccd888817d891c3d1da416f7a704b Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Sat, 7 Sep 2024 15:00:59 +0900 Subject: [PATCH 238/371] =?UTF-8?q?feat:=20=EB=AA=A8=EC=9E=84=20=ED=85=8C?= =?UTF-8?q?=EC=9D=B4=EB=B8=94=20=EC=98=A4=ED=94=88=20=EC=B1=84=ED=8C=85=20?= =?UTF-8?q?=EB=A7=81=ED=81=AC=20=EC=BB=AC=EB=9F=BC=20=EC=B6=94=EA=B0=80?= =?UTF-8?q?=EB=A1=9C=20=EC=9D=B8=ED=95=B4=20response=20dto=20=ED=95=84?= =?UTF-8?q?=EB=93=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../gathering/dto/response/GatheringDetailResponse.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/solitour_backend/solitour/gathering/dto/response/GatheringDetailResponse.java b/src/main/java/solitour_backend/solitour/gathering/dto/response/GatheringDetailResponse.java index 68a3106a..fe3bf485 100644 --- a/src/main/java/solitour_backend/solitour/gathering/dto/response/GatheringDetailResponse.java +++ b/src/main/java/solitour_backend/solitour/gathering/dto/response/GatheringDetailResponse.java @@ -44,6 +44,8 @@ public class GatheringDetailResponse { private Boolean isLike; + private String openChattingUrl; + private List gatheringApplicantsResponses; private List gatheringRecommend; From 365aaf06c7550ebc11ebf5a0ce134fc3a151a6f6 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Sat, 7 Sep 2024 15:01:43 +0900 Subject: [PATCH 239/371] =?UTF-8?q?refactor:=20=EB=AA=A8=EC=9E=84=20?= =?UTF-8?q?=ED=85=8C=EC=9D=B4=EB=B8=94=20=EC=98=A4=ED=94=88=20=EC=B1=84?= =?UTF-8?q?=ED=8C=85=20=EB=A7=81=ED=81=AC=20=EC=BB=AC=EB=9F=BC=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80=EB=A1=9C=20=EC=9D=B8=ED=95=B4=20=EC=88=98=EC=A0=95,?= =?UTF-8?q?=20=EC=A1=B0=ED=9A=8C,=20=EC=83=9D=EC=84=B1=20=EB=A1=9C?= =?UTF-8?q?=EC=A7=81=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../gathering/service/GatheringService.java | 24 +++++++++++-------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/src/main/java/solitour_backend/solitour/gathering/service/GatheringService.java b/src/main/java/solitour_backend/solitour/gathering/service/GatheringService.java index 107d0188..c5d200ee 100644 --- a/src/main/java/solitour_backend/solitour/gathering/service/GatheringService.java +++ b/src/main/java/solitour_backend/solitour/gathering/service/GatheringService.java @@ -15,7 +15,6 @@ import solitour_backend.solitour.error.exception.RequestValidationFailedException; import solitour_backend.solitour.gathering.dto.mapper.GatheringMapper; import solitour_backend.solitour.gathering.dto.request.GatheringModifyRequest; -import solitour_backend.solitour.gathering.dto.request.GatheringNotFinishRequest; import solitour_backend.solitour.gathering.dto.request.GatheringPageRequest; import solitour_backend.solitour.gathering.dto.request.GatheringRegisterRequest; import solitour_backend.solitour.gathering.dto.response.GatheringBriefResponse; @@ -163,6 +162,7 @@ public GatheringDetailResponse getGatheringDetail(Long userId, Long gatheringId) likeCount, nowPersonCount, isLike, + gathering.getOpenChattingUrl(), gatheringApplicantsResponses, gatheringRecommend, gatheringStatus @@ -216,7 +216,8 @@ public GatheringResponse registerGathering(Long userId, GatheringRegisterRequest gatheringRegisterRequest.getDeadline(), gatheringRegisterRequest.getAllowedSex(), gatheringRegisterRequest.getStartAge(), - gatheringRegisterRequest.getEndAge() + gatheringRegisterRequest.getEndAge(), + gatheringRegisterRequest.getOpenChattingUrl() ); Gathering saveGathering = gatheringRepository.save(gathering); @@ -287,6 +288,7 @@ public GatheringResponse modifyGathering(Long userId, Long gatheringId, gathering.setEndAge(gatheringModifyRequest.getEndAge()); gathering.setGatheringCategory(gatheringCategory); gathering.setZoneCategory(childZoneCategory); + gathering.setOpenChattingUrl(gatheringModifyRequest.getOpenChattingUrl()); List gatheringTags = gatheringTagRepository.findAllByGathering_Id(gathering.getId()); @@ -351,6 +353,7 @@ public List getGatheringOrderByLikesFilterByCreate3After return gatheringRepository.getGatheringLikeCountFromCreatedIn3(userId); } + @Transactional public void setGatheringFinish(Long userId, Long gatheringId) { Gathering gathering = gatheringRepository.findById(gatheringId) .orElseThrow( @@ -375,7 +378,8 @@ public void setGatheringFinish(Long userId, Long gatheringId) { gathering.setIsFinish(true); } - public void setGatheringNotFinish(Long userId, Long gatheringId, GatheringNotFinishRequest gatheringNotFinishRequest) { + @Transactional + public void setGatheringNotFinish(Long userId, Long gatheringId) { Gathering gathering = gatheringRepository.findById(gatheringId) .orElseThrow( () -> new GatheringNotExistsException("해당하는 id의 gathering 이 존재 하지 않습니다")); @@ -396,13 +400,13 @@ public void setGatheringNotFinish(Long userId, Long gatheringId, GatheringNotFin throw new GatheringFinishConflictException("이미 모임이 not finish 상태입니다"); } - if (gathering.getScheduleStartDate().isBefore(gatheringNotFinishRequest.getDeadline())) { - throw new RequestValidationFailedException("마감일은 시작 날짜 보다 나중일 순 없습니다"); - } - - if (Objects.nonNull(gatheringNotFinishRequest.getDeadline())) { - gathering.setDeadline(gatheringNotFinishRequest.getDeadline()); - } +// if (gathering.getScheduleStartDate().isBefore(gatheringNotFinishRequest.getDeadline())) { +// throw new RequestValidationFailedException("마감일은 시작 날짜 보다 나중일 순 없습니다"); +// } +// +// if (Objects.nonNull(gatheringNotFinishRequest.getDeadline())) { +// gathering.setDeadline(gatheringNotFinishRequest.getDeadline()); +// } gathering.setIsFinish(false); } From 13bb9470d055179f3597ec7608ff925f19aa8c4f Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Sat, 7 Sep 2024 17:15:41 +0900 Subject: [PATCH 240/371] =?UTF-8?q?feat:=20image=20entity=20setter=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/solitour_backend/solitour/image/entity/Image.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/solitour_backend/solitour/image/entity/Image.java b/src/main/java/solitour_backend/solitour/image/entity/Image.java index 289ea75f..8e1419e2 100644 --- a/src/main/java/solitour_backend/solitour/image/entity/Image.java +++ b/src/main/java/solitour_backend/solitour/image/entity/Image.java @@ -6,6 +6,7 @@ import lombok.Getter; import lombok.NoArgsConstructor; +import lombok.Setter; import org.springframework.data.annotation.CreatedDate; import org.springframework.data.jpa.domain.support.AuditingEntityListener; import solitour_backend.solitour.image.image_status.ImageStatus; @@ -14,6 +15,7 @@ @Entity @Getter +@Setter @Table(name = "image") @NoArgsConstructor @EntityListeners(AuditingEntityListener.class) From 2f204db696f3773fa3d01ccf0e48666b347182a6 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Sat, 7 Sep 2024 17:16:07 +0900 Subject: [PATCH 241/371] =?UTF-8?q?feat:=20=EC=9D=B4=EB=AF=B8=EC=A7=80=20?= =?UTF-8?q?=EC=A3=BC=EC=86=8C=EB=A1=9C=20=EC=9D=B4=EB=AF=B8=EC=A7=80=20?= =?UTF-8?q?=EC=B0=BE=EB=8A=94=20=EB=A9=94=EC=84=9C=EB=93=9C=20repository?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../solitour/image/repository/ImageRepository.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main/java/solitour_backend/solitour/image/repository/ImageRepository.java b/src/main/java/solitour_backend/solitour/image/repository/ImageRepository.java index 770ce59d..e097eb59 100644 --- a/src/main/java/solitour_backend/solitour/image/repository/ImageRepository.java +++ b/src/main/java/solitour_backend/solitour/image/repository/ImageRepository.java @@ -1,6 +1,7 @@ package solitour_backend.solitour.image.repository; import java.util.List; +import java.util.Optional; import org.springframework.data.jpa.repository.JpaRepository; import solitour_backend.solitour.image.entity.Image; @@ -10,6 +11,8 @@ public interface ImageRepository extends JpaRepository { boolean existsByInformationIdAndImageStatus(Long informationId, ImageStatus imageStatus); + Optional findImageByAddress(String address); + List findAllByInformationId(Long informationId); boolean existsImageByAddress(String address); From 9e609fc5e33046d014560202b5913ffd66ced4b5 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Sat, 7 Sep 2024 17:18:28 +0900 Subject: [PATCH 242/371] =?UTF-8?q?feat:=20InformationUpdateRequest=20imag?= =?UTF-8?q?e=20=EA=B4=80=EB=A0=A8=20=ED=95=84=EB=93=9C=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dto/request/InformationUpdateRequest.java | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/main/java/solitour_backend/solitour/information/dto/request/InformationUpdateRequest.java b/src/main/java/solitour_backend/solitour/information/dto/request/InformationUpdateRequest.java index 55ad0173..44e19215 100644 --- a/src/main/java/solitour_backend/solitour/information/dto/request/InformationUpdateRequest.java +++ b/src/main/java/solitour_backend/solitour/information/dto/request/InformationUpdateRequest.java @@ -43,12 +43,18 @@ public class InformationUpdateRequest { @Size(min = 1, max = 20) private String zoneCategoryNameChild; - private List deleteImages; + @Size(min = 1, max = 200) + private String newThumbNailUrl; - @Size(min = 0, max = 200) - private String thumbNailUrl; + @Size(min = 1, max = 200) + private String newThumbNailFromContent; - private List contentImagesUrl; + @Size(min = 1, max = 200) + private String moveThumbNailToContent; + + private List<@Size(min = 1, max = 200) String> deleteImagesUrl; + + private List<@Size(min = 1, max = 200) String> newContentImagesUrl; private List tagRegisterRequests; } From 74d98a6ee2243b82eb050e029325c8749b5a19d8 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Sat, 7 Sep 2024 17:20:59 +0900 Subject: [PATCH 243/371] =?UTF-8?q?feat:=20information=20update=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 --- .../service/InformationService.java | 176 ++++++++++++------ 1 file changed, 120 insertions(+), 56 deletions(-) diff --git a/src/main/java/solitour_backend/solitour/information/service/InformationService.java b/src/main/java/solitour_backend/solitour/information/service/InformationService.java index 9a9ea83a..7e68f446 100644 --- a/src/main/java/solitour_backend/solitour/information/service/InformationService.java +++ b/src/main/java/solitour_backend/solitour/information/service/InformationService.java @@ -19,13 +19,10 @@ import solitour_backend.solitour.error.exception.RequestValidationFailedException; import solitour_backend.solitour.great_information.repository.GreatInformationRepository; import solitour_backend.solitour.image.dto.mapper.ImageMapper; -import solitour_backend.solitour.image.dto.request.ImageDeleteRequest; -import solitour_backend.solitour.image.dto.request.ImageUseRequest; import solitour_backend.solitour.image.dto.response.ImageResponse; import solitour_backend.solitour.image.entity.Image; import solitour_backend.solitour.image.exception.ImageAlreadyExistsException; import solitour_backend.solitour.image.exception.ImageNotExistsException; -import solitour_backend.solitour.image.exception.ImageRequestValidationFailedException; import solitour_backend.solitour.image.image_status.ImageStatus; import solitour_backend.solitour.image.repository.ImageRepository; import solitour_backend.solitour.image.s3.S3Uploader; @@ -33,7 +30,6 @@ import solitour_backend.solitour.info_tag.repository.InfoTagRepository; import solitour_backend.solitour.information.dto.mapper.InformationMapper; import solitour_backend.solitour.information.dto.request.InformationCreateRequest; -import solitour_backend.solitour.information.dto.request.InformationModifyRequest; import solitour_backend.solitour.information.dto.request.InformationPageRequest; import solitour_backend.solitour.information.dto.request.InformationUpdateRequest; import solitour_backend.solitour.information.dto.response.InformationBriefResponse; @@ -46,6 +42,7 @@ import solitour_backend.solitour.information.exception.InformationNotManageException; import solitour_backend.solitour.information.repository.InformationRepository; import solitour_backend.solitour.place.dto.mapper.PlaceMapper; +import solitour_backend.solitour.place.dto.request.PlaceModifyRequest; import solitour_backend.solitour.place.dto.response.PlaceResponse; import solitour_backend.solitour.place.entity.Place; import solitour_backend.solitour.place.exception.PlaceNotExistsException; @@ -219,95 +216,162 @@ public InformationDetailResponse getDetailInformation(Long userId, Long informat @Transactional public InformationResponse updateInformation(Long userId, Long informationId, InformationUpdateRequest informationUpdateRequest) { + Information information = getInformation(informationId, userId); + + updateInformationDetails(information, informationUpdateRequest); + updatePlaceDetails(information, informationUpdateRequest); + updateCategory(information, informationUpdateRequest); + updateZoneCategory(information, informationUpdateRequest); + updateTags(information, informationUpdateRequest); + handleImageDeletions(informationUpdateRequest); + handleImageAdditions(information, informationUpdateRequest); + updateThumbnail(information, informationUpdateRequest); + + return informationMapper.mapToInformationResponse(information); + } + + private Information getInformation(Long informationId, Long userId) { Information information = informationRepository.findById(informationId) - .orElseThrow( - () -> new InformationNotExistsException("해당하는 id의 information 이 존재하지 않습니다.")); + .orElseThrow(() -> new InformationNotExistsException("해당하는 id의 information 이 존재하지 않습니다.")); if (!Objects.equals(information.getUser().getId(), userId)) { throw new InformationNotManageException("권한이 없습니다"); } + return information; + } - information.setTitle(informationUpdateRequest.getTitle()); - information.setAddress(informationUpdateRequest.getAddress()); - information.setContent(informationUpdateRequest.getContent()); - information.setTip(informationUpdateRequest.getTips()); + private void updateInformationDetails(Information information, InformationUpdateRequest request) { + information.setTitle(request.getTitle()); + information.setAddress(request.getAddress()); + information.setContent(request.getContent()); + information.setTip(request.getTips()); + } - Place placeInformation = placeRepository.findById(information.getPlace().getId()) - .orElseThrow( - () -> new PlaceNotExistsException("해당하는 information 의 place 에서의 id가 존재하지 않습니다")); - placeInformation.setName(informationUpdateRequest.getPlaceModifyRequest().getName()); - placeInformation.setAddress(informationUpdateRequest.getPlaceModifyRequest().getAddress()); - placeInformation.setXaxis(informationUpdateRequest.getPlaceModifyRequest().getXAxis()); - placeInformation.setYaxis(informationUpdateRequest.getPlaceModifyRequest().getYAxis()); - placeInformation.setSearchId(informationUpdateRequest.getPlaceModifyRequest().getSearchId()); - - Category categoryInformation = categoryRepository.findById(informationUpdateRequest.getCategoryId()) - .orElseThrow( - () -> new CategoryNotExistsException("해당하는 category Id 가 존재하지 않습니다.")); + private void updatePlaceDetails(Information information, InformationUpdateRequest request) { + Place place = placeRepository.findById(information.getPlace().getId()) + .orElseThrow(() -> new PlaceNotExistsException("해당하는 information 의 place 에서의 id가 존재하지 않습니다")); + PlaceModifyRequest placeRequest = request.getPlaceModifyRequest(); + place.setName(placeRequest.getName()); + place.setAddress(placeRequest.getAddress()); + place.setXaxis(placeRequest.getXAxis()); + place.setYaxis(placeRequest.getYAxis()); + place.setSearchId(placeRequest.getSearchId()); + } - if (Objects.isNull(categoryInformation.getParentCategory())) { + private void updateCategory(Information information, InformationUpdateRequest request) { + Category category = categoryRepository.findById(request.getCategoryId()) + .orElseThrow(() -> new CategoryNotExistsException("해당하는 category Id 가 존재하지 않습니다.")); + + if (Objects.isNull(category.getParentCategory())) { throw new RequestValidationFailedException("부모 카테고리는 등록이 안됩니다"); } - information.setCategory(categoryInformation); + information.setCategory(category); + } - ZoneCategory parentZoneCategory = zoneCategoryRepository.findByParentZoneCategoryIdAndName(null, - informationUpdateRequest.getZoneCategoryNameParent()) - .orElseThrow( - () -> new ZoneCategoryNotExistsException("해당하는 name 에 대한 zoneCategory 가 존재하지 않습니다")); + private void updateZoneCategory(Information information, InformationUpdateRequest request) { + ZoneCategory parentZoneCategory = zoneCategoryRepository.findByParentZoneCategoryIdAndName(null, request.getZoneCategoryNameParent()) + .orElseThrow(() -> new ZoneCategoryNotExistsException("해당하는 name 에 대한 zoneCategory 가 존재하지 않습니다")); ZoneCategory childZoneCategory = zoneCategoryRepository.findByParentZoneCategoryIdAndName( - parentZoneCategory.getId(), informationUpdateRequest.getZoneCategoryNameChild()) - .orElseThrow( - () -> new ZoneCategoryNotExistsException("해당하는 name에 대한 zoneCategory가 존재하지 않습니다")); + parentZoneCategory.getId(), request.getZoneCategoryNameChild()) + .orElseThrow(() -> new ZoneCategoryNotExistsException("해당하는 name에 대한 zoneCategory가 존재하지 않습니다")); information.setZoneCategory(childZoneCategory); + } + private void updateTags(Information information, InformationUpdateRequest request) { List infoTags = infoTagRepository.findAllByInformationId(information.getId()); infoTagRepository.deleteAllByInformationId(information.getId()); - for (InfoTag infoTag : infoTags) { tagRepository.deleteById(infoTag.getTag().getTagId()); } - List saveTags = tagRepository.saveAll( - tagMapper.mapToTags( - informationUpdateRequest.getTagRegisterRequests())); - + List saveTags = tagRepository.saveAll(tagMapper.mapToTags(request.getTagRegisterRequests())); for (Tag tag : saveTags) { infoTagRepository.save(new InfoTag(tag, information)); } + } - if (Objects.nonNull(informationUpdateRequest.getPlaceModifyRequest())) { - List deleteImages = informationUpdateRequest.getDeleteImages(); - - for (ImageDeleteRequest imageDeleteRequest : deleteImages) { - s3Uploader.deleteImage(imageDeleteRequest.getAddress()); - imageRepository.deleteByAddress(imageDeleteRequest.getAddress()); + private void handleImageDeletions(InformationUpdateRequest request) { + if (Objects.nonNull(request.getDeleteImagesUrl())) { + for (String deleteImageUrl : request.getDeleteImagesUrl()) { + if (!imageRepository.existsImageByAddress(deleteImageUrl)) { + throw new ImageNotExistsException("해당하는 이미지는 없습니다"); + } + imageRepository.deleteByAddress(deleteImageUrl); } } + } - if (!imageRepository.existsImageByImageStatusAndInformationId(ImageStatus.THUMBNAIL, informationId)) { - if (Objects.isNull(informationUpdateRequest.getThumbNailUrl())) { - throw new ImageRequestValidationFailedException("썸네일 이미지는 있어야 합니다"); + private void handleImageAdditions(Information information, InformationUpdateRequest request) { + if (Objects.nonNull(request.getNewContentImagesUrl())) { + List contentImageList = new ArrayList<>(); + for (String newContentImageUrl : request.getNewContentImagesUrl()) { + contentImageList.add(new Image(ImageStatus.CONTENT, information, newContentImageUrl)); + s3Uploader.markImagePermanent(newContentImageUrl); } + imageRepository.saveAll(contentImageList); + } + } - imageRepository.save(new Image(ImageStatus.THUMBNAIL, information, informationUpdateRequest.getAddress())); + private void updateThumbnail(Information information, InformationUpdateRequest request) { + if (isInvalidThumbnailUpdate(request)) { + validateExistingThumbNailImage(information); + } else if (Objects.isNull(request.getNewThumbNailUrl())) { + handleThumbnailUpdateWithoutNewUrl(information, request); } else { - if (Objects.nonNull(informationUpdateRequest.getThumbNailUrl())) { - if (!imageRepository.existsImageByAddress(informationUpdateRequest.getThumbNailUrl())) { - throw new ImageAlreadyExistsException("썸네일 이미지가 이미 있습니다"); - } - } + handleThumbnailUpdateWithNewUrl(information, request); } + } + + private boolean isInvalidThumbnailUpdate(InformationUpdateRequest request) { + return Objects.isNull(request.getNewThumbNailUrl()) + && Objects.isNull(request.getNewThumbNailFromContent()) + && Objects.isNull(request.getMoveThumbNailToContent()); + } - if (Objects.nonNull(informationUpdateRequest.getContentImagesUrl())) { - List contentImagesUrl = informationUpdateRequest.getContentImagesUrl(); - for (String contentImageUrl : contentImagesUrl) { - imageRepository.save(new Image(ImageStatus.CONTENT, information, contentImageUrl)); + private void validateExistingThumbNailImage(Information information) { + if (!imageRepository.existsImageByImageStatusAndInformationId(ImageStatus.THUMBNAIL, information.getId())) { + throw new ImageNotExistsException("썸네일 이미지가 없습니다"); + } + } + + private void handleThumbnailUpdateWithoutNewUrl(Information information, InformationUpdateRequest request) { + if (Objects.nonNull(request.getNewThumbNailFromContent()) && Objects.nonNull(request.getMoveThumbNailToContent())) { + swapThumbnailAndContent(information, request); + } else if (Objects.nonNull(request.getNewThumbNailFromContent())) { + setNewThumbnailFromContent(information, request); + } + } + + private void handleThumbnailUpdateWithNewUrl(Information information, InformationUpdateRequest request) { + if (Objects.nonNull(request.getMoveThumbNailToContent())) { + Image thumbNailImage = imageRepository.findImageByAddress(request.getMoveThumbNailToContent()).orElseThrow(); + thumbNailImage.setImageStatus(ImageStatus.CONTENT); + } else { + if (imageRepository.existsImageByImageStatusAndInformationId(ImageStatus.THUMBNAIL, information.getId())) { + throw new ImageAlreadyExistsException("해당 정보에 대한 썸네일 이미지가 존재합니다"); } } + Image newImage = new Image(ImageStatus.THUMBNAIL, information, request.getNewThumbNailUrl()); + imageRepository.save(newImage); + s3Uploader.markImagePermanent(newImage.getAddress()); + } - return informationMapper.mapToInformationResponse(information); + private void swapThumbnailAndContent(Information information, InformationUpdateRequest request) { + validateExistingThumbNailImage(information); + Image content = imageRepository.findImageByAddress(request.getNewThumbNailFromContent()).orElseThrow(); + content.setImageStatus(ImageStatus.THUMBNAIL); + Image thumbNail = imageRepository.findImageByAddress(request.getMoveThumbNailToContent()).orElseThrow(); + thumbNail.setImageStatus(ImageStatus.CONTENT); + } + + private void setNewThumbnailFromContent(Information information, InformationUpdateRequest request) { + if (imageRepository.existsImageByImageStatusAndInformationId(ImageStatus.THUMBNAIL, information.getId())) { + throw new IllegalStateException("THUMBNAIL image already exists."); + } + Image content = imageRepository.findImageByAddress(request.getNewThumbNailFromContent()).orElseThrow(); + content.setImageStatus(ImageStatus.THUMBNAIL); } From 47292f663c1798a44fc178ba32cb2c6dffe3ef30 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Sat, 7 Sep 2024 20:13:11 +0900 Subject: [PATCH 244/371] =?UTF-8?q?style:=20import=20=EB=AC=B8=20=EC=A0=95?= =?UTF-8?q?=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../solitour/information/controller/InformationController.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/main/java/solitour_backend/solitour/information/controller/InformationController.java b/src/main/java/solitour_backend/solitour/information/controller/InformationController.java index 35fb4ce8..1d3251ef 100644 --- a/src/main/java/solitour_backend/solitour/information/controller/InformationController.java +++ b/src/main/java/solitour_backend/solitour/information/controller/InformationController.java @@ -5,7 +5,6 @@ import jakarta.validation.Valid; import java.io.UnsupportedEncodingException; -import java.util.Base64; import java.util.List; import java.util.Objects; @@ -17,14 +16,12 @@ import org.springframework.http.ResponseEntity; import org.springframework.validation.BindingResult; import org.springframework.web.bind.annotation.*; -import org.springframework.web.multipart.MultipartFile; import solitour_backend.solitour.auth.config.Authenticated; import solitour_backend.solitour.auth.config.AuthenticationPrincipal; import solitour_backend.solitour.auth.support.CookieExtractor; import solitour_backend.solitour.auth.support.JwtTokenProvider; import solitour_backend.solitour.error.Utils; import solitour_backend.solitour.information.dto.request.InformationCreateRequest; -import solitour_backend.solitour.information.dto.request.InformationModifyRequest; import solitour_backend.solitour.information.dto.request.InformationPageRequest; import solitour_backend.solitour.information.dto.request.InformationUpdateRequest; import solitour_backend.solitour.information.dto.response.InformationBriefResponse; From 5fa8d7504a606ea1325925508913b737fc1051ee Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Sat, 7 Sep 2024 20:16:09 +0900 Subject: [PATCH 245/371] =?UTF-8?q?fix:=20s3=20object=20key=20=EA=B0=92=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 --- .../solitour_backend/solitour/image/s3/S3Uploader.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/main/java/solitour_backend/solitour/image/s3/S3Uploader.java b/src/main/java/solitour_backend/solitour/image/s3/S3Uploader.java index 6e054873..de6680b8 100644 --- a/src/main/java/solitour_backend/solitour/image/s3/S3Uploader.java +++ b/src/main/java/solitour_backend/solitour/image/s3/S3Uploader.java @@ -48,7 +48,7 @@ public String upload(MultipartFile multipartFile, String dirName, Long id) { } public void markImagePermanent(String imageUrl) { - String fileName = extractFileNameFromUrl(imageUrl); + String fileName = extractFileNameFromUrlUseBucketName(imageUrl); GetObjectTaggingRequest getTaggingRequest = new GetObjectTaggingRequest(bucket, fileName); GetObjectTaggingResult getTaggingResult = amazonS3Client.getObjectTagging(getTaggingRequest); List tags = getTaggingResult.getTagSet(); @@ -94,4 +94,9 @@ private String extractFileNameFromUrl(String url) { final String splitStr = ".com/"; return url.substring(url.lastIndexOf(splitStr) + splitStr.length()); } + + private String extractFileNameFromUrlUseBucketName(String url) { + final String splitStr = "solitour-bucket/"; + return url.substring(url.lastIndexOf(splitStr) + splitStr.length()); + } } \ No newline at end of file From 161c42366e70ca98a79e17cb55967af81d209bee Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Sat, 7 Sep 2024 20:58:32 +0900 Subject: [PATCH 246/371] =?UTF-8?q?style:=20=EC=82=AC=EC=9A=A9=ED=95=98?= =?UTF-8?q?=EC=A7=80=20=EC=95=8A=EB=8A=94=20dto=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../image/dto/request/ImageDeleteRequest.java | 14 ----- .../image/dto/request/ImageUseRequest.java | 14 ----- .../dto/request/InformationModifyRequest.java | 54 ------------------- .../request/InformationRegisterRequest.java | 52 ------------------ 4 files changed, 134 deletions(-) delete mode 100644 src/main/java/solitour_backend/solitour/image/dto/request/ImageDeleteRequest.java delete mode 100644 src/main/java/solitour_backend/solitour/image/dto/request/ImageUseRequest.java delete mode 100644 src/main/java/solitour_backend/solitour/information/dto/request/InformationModifyRequest.java delete mode 100644 src/main/java/solitour_backend/solitour/information/dto/request/InformationRegisterRequest.java diff --git a/src/main/java/solitour_backend/solitour/image/dto/request/ImageDeleteRequest.java b/src/main/java/solitour_backend/solitour/image/dto/request/ImageDeleteRequest.java deleted file mode 100644 index c0f10bbb..00000000 --- a/src/main/java/solitour_backend/solitour/image/dto/request/ImageDeleteRequest.java +++ /dev/null @@ -1,14 +0,0 @@ -package solitour_backend.solitour.image.dto.request; - -import jakarta.validation.constraints.NotBlank; -import jakarta.validation.constraints.Size; -import lombok.Getter; -import lombok.NoArgsConstructor; - -@Getter -@NoArgsConstructor -public class ImageDeleteRequest { - @NotBlank - @Size(min = 1, max = 200) - private String address; -} diff --git a/src/main/java/solitour_backend/solitour/image/dto/request/ImageUseRequest.java b/src/main/java/solitour_backend/solitour/image/dto/request/ImageUseRequest.java deleted file mode 100644 index e4621af1..00000000 --- a/src/main/java/solitour_backend/solitour/image/dto/request/ImageUseRequest.java +++ /dev/null @@ -1,14 +0,0 @@ -package solitour_backend.solitour.image.dto.request; - -import jakarta.validation.constraints.NotBlank; -import jakarta.validation.constraints.Size; -import lombok.Getter; -import lombok.NoArgsConstructor; - -@Getter -@NoArgsConstructor -public class ImageUseRequest { - @NotBlank - @Size(min = 1, max = 200) - private String address; -} diff --git a/src/main/java/solitour_backend/solitour/information/dto/request/InformationModifyRequest.java b/src/main/java/solitour_backend/solitour/information/dto/request/InformationModifyRequest.java deleted file mode 100644 index a5bcc333..00000000 --- a/src/main/java/solitour_backend/solitour/information/dto/request/InformationModifyRequest.java +++ /dev/null @@ -1,54 +0,0 @@ -package solitour_backend.solitour.information.dto.request; - -import jakarta.validation.constraints.Min; -import jakarta.validation.constraints.NotBlank; -import jakarta.validation.constraints.NotNull; -import jakarta.validation.constraints.Size; -import java.util.List; -import lombok.Getter; -import lombok.NoArgsConstructor; -import solitour_backend.solitour.image.dto.request.ImageDeleteRequest; -import solitour_backend.solitour.image.dto.request.ImageUseRequest; -import solitour_backend.solitour.place.dto.request.PlaceModifyRequest; -import solitour_backend.solitour.tag.dto.request.TagRegisterRequest; - -@Getter -@NoArgsConstructor -public class InformationModifyRequest { - - @NotBlank - @Size(min = 1, max = 50) - private String title; - - @NotBlank - @Size(min = 1, max = 20) - private String address; - - private String content; - - private String tips; - - @NotNull - private PlaceModifyRequest placeModifyRequest; - - @NotNull - @Min(1) - private Long categoryId; - - @NotBlank - @Size(min = 1, max = 20) - private String zoneCategoryNameParent; - - @NotBlank - @Size(min = 1, max = 20) - private String zoneCategoryNameChild; - - - private List useImages; - - private List deleteImages; - - - private List tagRegisterRequests; - -} diff --git a/src/main/java/solitour_backend/solitour/information/dto/request/InformationRegisterRequest.java b/src/main/java/solitour_backend/solitour/information/dto/request/InformationRegisterRequest.java deleted file mode 100644 index 75fe1ad2..00000000 --- a/src/main/java/solitour_backend/solitour/information/dto/request/InformationRegisterRequest.java +++ /dev/null @@ -1,52 +0,0 @@ -package solitour_backend.solitour.information.dto.request; - -import jakarta.validation.constraints.Min; -import jakarta.validation.constraints.NotBlank; -import jakarta.validation.constraints.NotNull; -import jakarta.validation.constraints.Size; -import java.util.List; -import lombok.AllArgsConstructor; -import lombok.Getter; -import lombok.NoArgsConstructor; -import solitour_backend.solitour.place.dto.request.PlaceRegisterRequest; -import solitour_backend.solitour.tag.dto.request.TagRegisterRequest; - -@Getter -@AllArgsConstructor -@NoArgsConstructor -public class InformationRegisterRequest { - - @NotBlank - @Size(min = 1, max = 50) - private String informationTitle; - - @NotBlank - @Size(min = 1, max = 20) - private String informationAddress; - - private String informationContent; - - private String informationTips; - - @NotNull - @Min(1) - private Long userId; - - @NotNull - private PlaceRegisterRequest placeRegisterRequest; - - @NotNull - @Min(1) - private Long categoryId; - - @NotBlank - @Size(min = 1, max = 20) - private String zoneCategoryNameParent; - - @NotBlank - @Size(min = 1, max = 20) - private String zoneCategoryNameChild; - - private List tagRegisterRequests; - -} \ No newline at end of file From 39a7b6bc70c338c90c1e180f4aceac9e1fba5065 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Sat, 7 Sep 2024 20:58:44 +0900 Subject: [PATCH 247/371] refactor: image request dto --- .../solitour/image/dto/request/ImageRequest.java | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 src/main/java/solitour_backend/solitour/image/dto/request/ImageRequest.java diff --git a/src/main/java/solitour_backend/solitour/image/dto/request/ImageRequest.java b/src/main/java/solitour_backend/solitour/image/dto/request/ImageRequest.java new file mode 100644 index 00000000..eefcebd9 --- /dev/null +++ b/src/main/java/solitour_backend/solitour/image/dto/request/ImageRequest.java @@ -0,0 +1,14 @@ +package solitour_backend.solitour.image.dto.request; + +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.Size; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor +public class ImageRequest { + @NotBlank + @Size(min = 1, max = 200) + private String address; +} From ad3fe0b5047c2a0d653680eb45463175d5ce5065 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Sat, 7 Sep 2024 20:59:15 +0900 Subject: [PATCH 248/371] =?UTF-8?q?refactor:=20address=20=EA=B8=B8?= =?UTF-8?q?=EC=9D=B4=20=EC=A0=9C=ED=95=9C=2050=EC=9C=BC=EB=A1=9C=20?= =?UTF-8?q?=EC=88=98=EC=A0=95=20=EB=B0=8F=20image=20request=20dto=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dto/request/InformationCreateRequest.java | 2 +- .../dto/request/InformationUpdateRequest.java | 17 +++++++---------- 2 files changed, 8 insertions(+), 11 deletions(-) diff --git a/src/main/java/solitour_backend/solitour/information/dto/request/InformationCreateRequest.java b/src/main/java/solitour_backend/solitour/information/dto/request/InformationCreateRequest.java index d581e0b4..182eee52 100644 --- a/src/main/java/solitour_backend/solitour/information/dto/request/InformationCreateRequest.java +++ b/src/main/java/solitour_backend/solitour/information/dto/request/InformationCreateRequest.java @@ -21,7 +21,7 @@ public class InformationCreateRequest { private String informationTitle; @NotBlank - @Size(min = 1, max = 20) + @Size(min = 1, max = 50) private String informationAddress; private String informationContent; diff --git a/src/main/java/solitour_backend/solitour/information/dto/request/InformationUpdateRequest.java b/src/main/java/solitour_backend/solitour/information/dto/request/InformationUpdateRequest.java index 44e19215..9de8e604 100644 --- a/src/main/java/solitour_backend/solitour/information/dto/request/InformationUpdateRequest.java +++ b/src/main/java/solitour_backend/solitour/information/dto/request/InformationUpdateRequest.java @@ -6,7 +6,7 @@ import jakarta.validation.constraints.Size; import lombok.Getter; import lombok.NoArgsConstructor; -import solitour_backend.solitour.image.dto.request.ImageDeleteRequest; +import solitour_backend.solitour.image.dto.request.ImageRequest; import solitour_backend.solitour.place.dto.request.PlaceModifyRequest; import solitour_backend.solitour.tag.dto.request.TagRegisterRequest; @@ -21,7 +21,7 @@ public class InformationUpdateRequest { private String title; @NotBlank - @Size(min = 1, max = 20) + @Size(min = 1, max = 50) private String address; private String content; @@ -43,18 +43,15 @@ public class InformationUpdateRequest { @Size(min = 1, max = 20) private String zoneCategoryNameChild; - @Size(min = 1, max = 200) - private String newThumbNailUrl; + private ImageRequest newThumbNailUrl; - @Size(min = 1, max = 200) - private String newThumbNailFromContent; + private ImageRequest newThumbNailFromContent; - @Size(min = 1, max = 200) - private String moveThumbNailToContent; + private ImageRequest moveThumbNailToContent; - private List<@Size(min = 1, max = 200) String> deleteImagesUrl; + private List deleteImagesUrl; - private List<@Size(min = 1, max = 200) String> newContentImagesUrl; + private List newContentImagesUrl; private List tagRegisterRequests; } From 008a1e2d41bb5fef0645aab1f6647e9b3f4d2fcc Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Sat, 7 Sep 2024 20:59:48 +0900 Subject: [PATCH 249/371] =?UTF-8?q?refactor:=20=20image=20request=20dto=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80=EB=A1=9C=20=EC=9D=B8=ED=95=9C=20refactor,=20?= =?UTF-8?q?=EC=83=81=EC=84=B8=20=ED=8E=98=EC=9D=B4=EC=A7=80=20=EA=B8=80=20?= =?UTF-8?q?=EC=9E=91=EC=84=B1=EC=9E=90=EC=97=90=20=EB=8C=80=ED=95=9C=20?= =?UTF-8?q?=EC=9C=A0=EC=A0=80=20=ED=94=84=EB=A1=9C=ED=95=84=20=EC=9D=B4?= =?UTF-8?q?=EB=AF=B8=EC=A7=80=EB=A1=9C=20=EB=B0=98=ED=99=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/InformationService.java | 131 ++---------------- 1 file changed, 13 insertions(+), 118 deletions(-) diff --git a/src/main/java/solitour_backend/solitour/information/service/InformationService.java b/src/main/java/solitour_backend/solitour/information/service/InformationService.java index 7e68f446..b730f998 100644 --- a/src/main/java/solitour_backend/solitour/information/service/InformationService.java +++ b/src/main/java/solitour_backend/solitour/information/service/InformationService.java @@ -19,6 +19,7 @@ import solitour_backend.solitour.error.exception.RequestValidationFailedException; import solitour_backend.solitour.great_information.repository.GreatInformationRepository; import solitour_backend.solitour.image.dto.mapper.ImageMapper; +import solitour_backend.solitour.image.dto.request.ImageRequest; import solitour_backend.solitour.image.dto.response.ImageResponse; import solitour_backend.solitour.image.entity.Image; import solitour_backend.solitour.image.exception.ImageAlreadyExistsException; @@ -191,7 +192,7 @@ public InformationDetailResponse getDetailInformation(Long userId, Long informat .orElseThrow( () -> new UserNotExistsException("해당하는 id의 User 가 없습니다")); - String userImageUrl = userImageRepository.findById(userId) + String userImageUrl = userImageRepository.findById(information.getUser().getId()) .map(UserImage::getAddress) .orElseGet( () -> userRepository.getProfileUrl(user.getSex())); @@ -294,11 +295,11 @@ private void updateTags(Information information, InformationUpdateRequest reques private void handleImageDeletions(InformationUpdateRequest request) { if (Objects.nonNull(request.getDeleteImagesUrl())) { - for (String deleteImageUrl : request.getDeleteImagesUrl()) { - if (!imageRepository.existsImageByAddress(deleteImageUrl)) { + for (ImageRequest deleteImageUrl : request.getDeleteImagesUrl()) { + if (!imageRepository.existsImageByAddress(deleteImageUrl.getAddress())) { throw new ImageNotExistsException("해당하는 이미지는 없습니다"); } - imageRepository.deleteByAddress(deleteImageUrl); + imageRepository.deleteByAddress(deleteImageUrl.getAddress()); } } } @@ -306,9 +307,9 @@ private void handleImageDeletions(InformationUpdateRequest request) { private void handleImageAdditions(Information information, InformationUpdateRequest request) { if (Objects.nonNull(request.getNewContentImagesUrl())) { List contentImageList = new ArrayList<>(); - for (String newContentImageUrl : request.getNewContentImagesUrl()) { - contentImageList.add(new Image(ImageStatus.CONTENT, information, newContentImageUrl)); - s3Uploader.markImagePermanent(newContentImageUrl); + for (ImageRequest newContentImageUrl : request.getNewContentImagesUrl()) { + contentImageList.add(new Image(ImageStatus.CONTENT, information, newContentImageUrl.getAddress())); + s3Uploader.markImagePermanent(newContentImageUrl.getAddress()); } imageRepository.saveAll(contentImageList); } @@ -346,23 +347,23 @@ private void handleThumbnailUpdateWithoutNewUrl(Information information, Informa private void handleThumbnailUpdateWithNewUrl(Information information, InformationUpdateRequest request) { if (Objects.nonNull(request.getMoveThumbNailToContent())) { - Image thumbNailImage = imageRepository.findImageByAddress(request.getMoveThumbNailToContent()).orElseThrow(); + Image thumbNailImage = imageRepository.findImageByAddress(request.getMoveThumbNailToContent().getAddress()).orElseThrow(); thumbNailImage.setImageStatus(ImageStatus.CONTENT); } else { if (imageRepository.existsImageByImageStatusAndInformationId(ImageStatus.THUMBNAIL, information.getId())) { throw new ImageAlreadyExistsException("해당 정보에 대한 썸네일 이미지가 존재합니다"); } } - Image newImage = new Image(ImageStatus.THUMBNAIL, information, request.getNewThumbNailUrl()); + Image newImage = new Image(ImageStatus.THUMBNAIL, information, request.getNewThumbNailUrl().getAddress()); imageRepository.save(newImage); s3Uploader.markImagePermanent(newImage.getAddress()); } private void swapThumbnailAndContent(Information information, InformationUpdateRequest request) { validateExistingThumbNailImage(information); - Image content = imageRepository.findImageByAddress(request.getNewThumbNailFromContent()).orElseThrow(); + Image content = imageRepository.findImageByAddress(request.getNewThumbNailFromContent().getAddress()).orElseThrow(); content.setImageStatus(ImageStatus.THUMBNAIL); - Image thumbNail = imageRepository.findImageByAddress(request.getMoveThumbNailToContent()).orElseThrow(); + Image thumbNail = imageRepository.findImageByAddress(request.getMoveThumbNailToContent().getAddress()).orElseThrow(); thumbNail.setImageStatus(ImageStatus.CONTENT); } @@ -370,117 +371,11 @@ private void setNewThumbnailFromContent(Information information, InformationUpda if (imageRepository.existsImageByImageStatusAndInformationId(ImageStatus.THUMBNAIL, information.getId())) { throw new IllegalStateException("THUMBNAIL image already exists."); } - Image content = imageRepository.findImageByAddress(request.getNewThumbNailFromContent()).orElseThrow(); + Image content = imageRepository.findImageByAddress(request.getNewThumbNailFromContent().getAddress()).orElseThrow(); content.setImageStatus(ImageStatus.THUMBNAIL); } -// @Transactional -// public InformationResponse modifyInformation(Long id, InformationModifyRequest informationModifyRequest, -// MultipartFile thumbNail, List contentImages) { -// Information information = informationRepository.findById(id) -// .orElseThrow( -// () -> new InformationNotExistsException("해당하는 id의 information 이 존재하지 않습니다.")); -// information.setTitle(informationModifyRequest.getTitle()); -// information.setAddress(informationModifyRequest.getAddress()); -// information.setContent(informationModifyRequest.getContent()); -// information.setTip(informationModifyRequest.getTips()); -// -// Place placeInformation = placeRepository.findById(information.getPlace().getId()) -// .orElseThrow( -// () -> new PlaceNotExistsException("해당하는 information의 place에서의 id가 존재하지 않습니다")); -// placeInformation.setName(informationModifyRequest.getPlaceModifyRequest().getName()); -// placeInformation.setAddress(informationModifyRequest.getPlaceModifyRequest().getAddress()); -// placeInformation.setXaxis(informationModifyRequest.getPlaceModifyRequest().getXAxis()); -// placeInformation.setYaxis(informationModifyRequest.getPlaceModifyRequest().getYAxis()); -// placeInformation.setSearchId(informationModifyRequest.getPlaceModifyRequest().getSearchId()); -// -// Category categoryInformation = categoryRepository.findById(informationModifyRequest.getCategoryId()) -// .orElseThrow( -// () -> new CategoryNotExistsException("해당하는 cateogry Id 가 존재하지 않습니다.")); -// information.setCategory(categoryInformation); -// -// ZoneCategory parentZoneCategory = zoneCategoryRepository.findByParentZoneCategoryIdAndName(null, -// informationModifyRequest.getZoneCategoryNameParent()) -// .orElseThrow( -// () -> new ZoneCategoryNotExistsException("해당하는 name에 대한 zoneCategory가 존재하지 않습니다")); -// -// ZoneCategory childZoneCategory = zoneCategoryRepository.findByParentZoneCategoryIdAndName( -// parentZoneCategory.getId(), informationModifyRequest.getZoneCategoryNameChild()) -// .orElseThrow( -// () -> new ZoneCategoryNotExistsException("해당하는 name에 대한 zoneCategory가 존재하지 않습니다")); -// -// information.setZoneCategory(childZoneCategory); -// -// List useImages = informationModifyRequest.getUseImages(); -// -// for (ImageUseRequest imageUseRequest : useImages) { -// if (!imageRepository.existsImageByAddress(imageUseRequest.getAddress())) { -// throw new ImageNotExistsException("계속 사용하려는 주소의 이미지는 없습니다."); -// } -// } -// -// List deleteImages = informationModifyRequest.getDeleteImages(); -// -// for (ImageDeleteRequest imageDeleteRequest : deleteImages) { -// if (!imageRepository.existsImageByAddress(imageDeleteRequest.getAddress())) { -// throw new ImageNotExistsException("삭제하려는 주소의 이미지가 없습니다."); -// } -// s3Uploader.deleteImage(imageDeleteRequest.getAddress()); -// imageRepository.deleteByAddress(imageDeleteRequest.getAddress()); -// } -// -// List allByInformationId = imageRepository.findAllByInformationId( -// information.getId()); -// -// for (Image image : allByInformationId) { -// s3Uploader.deleteImage(image.getAddress()); -// } -// -// if (!Objects.isNull(thumbNail)) { -// if (imageRepository.existsByInformationIdAndImageStatus(information.getId(), -// ImageStatus.THUMBNAIL)) { -// throw new ImageRequestValidationFailedException("이미 썸네일 이미지가 있습니다"); -// } else { -// String thumbNailImageUrl = s3Uploader.upload(thumbNail, IMAGE_PATH, -// information.getId()); -// Image thumbImage = new Image(ImageStatus.THUMBNAIL, information, thumbNailImageUrl); -// imageRepository.save(thumbImage); -// } -// } else { -// if (!imageRepository.existsByInformationIdAndImageStatus(information.getId(), -// ImageStatus.THUMBNAIL)) { -// throw new ImageRequestValidationFailedException("썸네일 이미지가 없습니다"); -// } -// } -// if (Objects.nonNull(contentImages)) { -// for (MultipartFile multipartFile : contentImages) { -// String upload = s3Uploader.upload(multipartFile, IMAGE_PATH, information.getId()); -// Image contentImage = new Image(ImageStatus.CONTENT, information, upload); -// -// imageRepository.save(contentImage); -// } -// } -// -// List infoTags = infoTagRepository.findAllByInformationId(information.getId()); -// -// infoTagRepository.deleteAllByInformationId(information.getId()); -// -// for (InfoTag infoTag : infoTags) { -// tagRepository.deleteById(infoTag.getTag().getTagId()); -// } -// -// List saveTags = tagRepository.saveAll( -// tagMapper.mapToTags( -// informationModifyRequest.getTagRegisterRequests())); -// -// for (Tag tag : saveTags) { -// infoTagRepository.save(new InfoTag(tag, information)); -// } -// -// return informationMapper.mapToInformationResponse(information); -// } - @Transactional public void deleteInformation(Long userId, Long id) { Information information = informationRepository.findById(id) From 7ad216023945897e11764aef9e3c8d077f6a1058 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Sat, 7 Sep 2024 21:49:28 +0900 Subject: [PATCH 250/371] =?UTF-8?q?fix:=20user=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../solitour/information/service/InformationService.java | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/main/java/solitour_backend/solitour/information/service/InformationService.java b/src/main/java/solitour_backend/solitour/information/service/InformationService.java index b730f998..7f00b966 100644 --- a/src/main/java/solitour_backend/solitour/information/service/InformationService.java +++ b/src/main/java/solitour_backend/solitour/information/service/InformationService.java @@ -188,11 +188,9 @@ public InformationDetailResponse getDetailInformation(Long userId, Long informat boolean isLike = greatInformationRepository.existsByInformationIdAndUserId(information.getId(), userId); - User user = userRepository.findById(userId) - .orElseThrow( - () -> new UserNotExistsException("해당하는 id의 User 가 없습니다")); + User user = information.getUser(); - String userImageUrl = userImageRepository.findById(information.getUser().getId()) + String userImageUrl = userImageRepository.findById(user.getId()) .map(UserImage::getAddress) .orElseGet( () -> userRepository.getProfileUrl(user.getSex())); From 2e8f526e882d4654a53fed3f3583d6c0e6e43979 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Mon, 9 Sep 2024 14:04:37 +0900 Subject: [PATCH 251/371] feat: information entity class viewCount plus method --- .../solitour/information/entity/Information.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/main/java/solitour_backend/solitour/information/entity/Information.java b/src/main/java/solitour_backend/solitour/information/entity/Information.java index 7ec18556..23fc47c9 100644 --- a/src/main/java/solitour_backend/solitour/information/entity/Information.java +++ b/src/main/java/solitour_backend/solitour/information/entity/Information.java @@ -3,6 +3,7 @@ import jakarta.persistence.*; import java.time.LocalDateTime; + import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; @@ -75,4 +76,8 @@ public Information(Category category, ZoneCategory zoneCategory, User user, Plac this.content = content; this.tip = tip; } + + public void upViewCount() { + this.viewCount++; + } } From 4a225534adff8161027faac9203549c30a59f631 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Mon, 9 Sep 2024 14:04:48 +0900 Subject: [PATCH 252/371] feat: gathering entity class viewCount plus method --- .../solitour_backend/solitour/gathering/entity/Gathering.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main/java/solitour_backend/solitour/gathering/entity/Gathering.java b/src/main/java/solitour_backend/solitour/gathering/entity/Gathering.java index 7f8368ba..63983b3f 100644 --- a/src/main/java/solitour_backend/solitour/gathering/entity/Gathering.java +++ b/src/main/java/solitour_backend/solitour/gathering/entity/Gathering.java @@ -124,4 +124,8 @@ public Gathering(User user, ZoneCategory zoneCategory, GatheringCategory gatheri this.isDeleted = false; this.openChattingUrl = openChattingUrl; } + + public void upViewCount() { + this.viewCount++; + } } From 4b0d841735a4a06f0c4add4f6fe0a5f8fa11471b Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Mon, 9 Sep 2024 14:07:24 +0900 Subject: [PATCH 253/371] =?UTF-8?q?feat:=20information=20=EC=A1=B0?= =?UTF-8?q?=ED=9A=8C=EC=88=98=20=EC=98=AC=EB=A6=AC=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/InformationService.java | 46 ++++++++++++++++++- 1 file changed, 45 insertions(+), 1 deletion(-) diff --git a/src/main/java/solitour_backend/solitour/information/service/InformationService.java b/src/main/java/solitour_backend/solitour/information/service/InformationService.java index 7f00b966..1cd4b149 100644 --- a/src/main/java/solitour_backend/solitour/information/service/InformationService.java +++ b/src/main/java/solitour_backend/solitour/information/service/InformationService.java @@ -3,10 +3,16 @@ import static solitour_backend.solitour.information.repository.InformationRepositoryCustom.LIKE_COUNT_SORT; import static solitour_backend.solitour.information.repository.InformationRepositoryCustom.VIEW_COUNT_SORT; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import java.util.Objects; +import jakarta.servlet.http.Cookie; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import lombok.RequiredArgsConstructor; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; @@ -159,11 +165,12 @@ public InformationResponse registerInformation(Long userId, InformationCreateReq } - public InformationDetailResponse getDetailInformation(Long userId, Long informationId) { + public InformationDetailResponse getDetailInformation(Long userId, Long informationId, HttpServletRequest request, HttpServletResponse response) { Information information = informationRepository.findById(informationId) .orElseThrow( () -> new InformationNotExistsException("해당하는 id 의 information 이 존재하지 않습니다.")); + List infoTags = infoTagRepository.findAllByInformationId(information.getId()); UserPostingResponse userPostingResponse = userMapper.mapToUserPostingResponse(information.getUser()); @@ -195,6 +202,8 @@ public InformationDetailResponse getDetailInformation(Long userId, Long informat .orElseGet( () -> userRepository.getProfileUrl(user.getSex())); + updateViewCount(information, request, response); + return new InformationDetailResponse( information.getTitle(), information.getAddress(), @@ -454,4 +463,39 @@ public Page getPageInformationByTag(Pageable pageable, return informationRepository.getInformationPageByTag(pageable, userId, parentCategoryId, informationPageRequest, decodedTag); } + + public void updateViewCount(Information information, HttpServletRequest request, HttpServletResponse response) { + String cookieName = "viewed_information_" + information.getId(); + Cookie[] cookies = request.getCookies(); + Cookie postCookie = null; + + if (Objects.nonNull(cookies)) { + postCookie = Arrays.stream(cookies) + .filter(cookie -> cookieName.equals(cookie.getName())) + .findFirst() + .orElse(null); + } + + LocalDateTime now = LocalDateTime.now(); + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); + + if (Objects.nonNull(postCookie)) { + LocalDateTime lastViewedAt = LocalDateTime.parse(postCookie.getValue(), formatter); + if (lastViewedAt.isBefore(now.minusDays(1))) { + incrementInformationViewCount(information); + postCookie.setValue(now.format(formatter)); + response.addCookie(postCookie); + } + } else { + incrementInformationViewCount(information); + Cookie newCookie = new Cookie(cookieName, now.format(formatter)); + newCookie.setMaxAge(60 * 60 * 24 * 365); + response.addCookie(newCookie); + } + } + + private void incrementInformationViewCount(Information information) { + information.upViewCount(); + } + } From dd49a79292f85f6b48077045e11cdcb58b3822cf Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Mon, 9 Sep 2024 14:08:00 +0900 Subject: [PATCH 254/371] =?UTF-8?q?feat:=20information=20detail=20?= =?UTF-8?q?=EC=A1=B0=ED=9A=8C=20api=20=EC=9A=94=EC=B2=AD=EC=8B=9C=20?= =?UTF-8?q?=EC=A1=B0=ED=9A=8C=EC=88=98=20=EC=98=AC=EB=A6=AC=EA=B8=B0=20?= =?UTF-8?q?=EC=9C=84=ED=95=9C=20HttpServletResponse=20=ED=8C=8C=EB=9D=BC?= =?UTF-8?q?=EB=AF=B8=ED=84=B0=EC=97=90=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/InformationController.java | 24 ++++--------------- 1 file changed, 4 insertions(+), 20 deletions(-) diff --git a/src/main/java/solitour_backend/solitour/information/controller/InformationController.java b/src/main/java/solitour_backend/solitour/information/controller/InformationController.java index 1d3251ef..39d65219 100644 --- a/src/main/java/solitour_backend/solitour/information/controller/InformationController.java +++ b/src/main/java/solitour_backend/solitour/information/controller/InformationController.java @@ -2,6 +2,7 @@ import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import jakarta.validation.Valid; import java.io.UnsupportedEncodingException; @@ -57,33 +58,16 @@ public ResponseEntity createInformation(@AuthenticationPrin @GetMapping("/{informationId}") public ResponseEntity getDetailInformation(@PathVariable Long informationId, - HttpServletRequest request) { + HttpServletRequest request, + HttpServletResponse response) { Long userId = findUser(request); - InformationDetailResponse informationDetailResponse = informationService.getDetailInformation(userId, - informationId); + InformationDetailResponse informationDetailResponse = informationService.getDetailInformation(userId, informationId, request, response); return ResponseEntity .status(HttpStatus.OK) .body(informationDetailResponse); } -// @Authenticated -// @PutMapping("/{informationId}") -// public ResponseEntity modifyInformation(@PathVariable Long informationId, -// @RequestPart(value = "thumbNailImage", required = false) MultipartFile thumbnail, -// @RequestPart(value = "contentImages", required = false) List contentImages, -// @Valid @RequestPart("request") InformationModifyRequest informationModifyRequest, -// BindingResult bindingResult) { -// Utils.validationRequest(bindingResult); -// -// InformationResponse informationResponse = informationService.modifyInformation( -// informationId, informationModifyRequest, thumbnail, contentImages); -// -// return ResponseEntity -// .status(HttpStatus.CREATED) -// .body(informationResponse); -// } - @Authenticated @PutMapping("/{informationId}") public ResponseEntity modifyInformation(@AuthenticationPrincipal Long userId, From c6e26a1245276b0f2feddef10b8f3e386df5ec75 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Mon, 9 Sep 2024 14:08:16 +0900 Subject: [PATCH 255/371] =?UTF-8?q?feat:=20gathering=20=EC=A1=B0=ED=9A=8C?= =?UTF-8?q?=EC=88=98=20=EC=98=AC=EB=A6=AC=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../gathering/service/GatheringService.java | 45 ++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-) diff --git a/src/main/java/solitour_backend/solitour/gathering/service/GatheringService.java b/src/main/java/solitour_backend/solitour/gathering/service/GatheringService.java index c5d200ee..8585ef48 100644 --- a/src/main/java/solitour_backend/solitour/gathering/service/GatheringService.java +++ b/src/main/java/solitour_backend/solitour/gathering/service/GatheringService.java @@ -3,10 +3,16 @@ import static solitour_backend.solitour.gathering.repository.GatheringRepositoryCustom.LIKE_COUNT_SORT; import static solitour_backend.solitour.gathering.repository.GatheringRepositoryCustom.VIEW_COUNT_SORT; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import java.util.Objects; +import jakarta.servlet.http.Cookie; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import lombok.RequiredArgsConstructor; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; @@ -40,6 +46,7 @@ import solitour_backend.solitour.gathering_tag.entity.GatheringTag; import solitour_backend.solitour.gathering_tag.repository.GatheringTagRepository; import solitour_backend.solitour.great_gathering.repository.GreatGatheringRepository; +import solitour_backend.solitour.information.entity.Information; import solitour_backend.solitour.place.dto.mapper.PlaceMapper; import solitour_backend.solitour.place.dto.request.PlaceModifyRequest; import solitour_backend.solitour.place.dto.request.PlaceRegisterRequest; @@ -84,7 +91,7 @@ public class GatheringService { private final GatheringCategoryMapper gatheringCategoryMapper; - public GatheringDetailResponse getGatheringDetail(Long userId, Long gatheringId) { + public GatheringDetailResponse getGatheringDetail(Long userId, Long gatheringId, HttpServletRequest request, HttpServletResponse response) { Gathering gathering = gatheringRepository.findById(gatheringId) .orElseThrow( () -> new GatheringNotExistsException("해당하는 id의 gathering 이 존재 하지 않습니다")); @@ -141,6 +148,8 @@ public GatheringDetailResponse getGatheringDetail(Long userId, Long gatheringId) List gatheringRecommend = gatheringRepository.getGatheringRecommend(gathering.getId(), gathering.getGatheringCategory().getId(), userId); + updateViewCount(gathering, request, response); + return new GatheringDetailResponse( gathering.getTitle(), gathering.getContent(), @@ -457,4 +466,38 @@ private void validateGatheringPageRequest(GatheringPageRequest gatheringPageRequ } } + public void updateViewCount(Gathering gathering, HttpServletRequest request, HttpServletResponse response) { + String cookieName = "viewed_gathering_" + gathering.getId(); + Cookie[] cookies = request.getCookies(); + Cookie postCookie = null; + + if (Objects.nonNull(cookies)) { + postCookie = Arrays.stream(cookies) + .filter(cookie -> cookieName.equals(cookie.getName())) + .findFirst() + .orElse(null); + } + + LocalDateTime now = LocalDateTime.now(); + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); + + if (Objects.nonNull(postCookie)) { + LocalDateTime lastViewedAt = LocalDateTime.parse(postCookie.getValue(), formatter); + if (lastViewedAt.isBefore(now.minusDays(1))) { + incrementGatheringViewCount(gathering); + postCookie.setValue(now.format(formatter)); + response.addCookie(postCookie); + } + } else { + incrementGatheringViewCount(gathering); + Cookie newCookie = new Cookie(cookieName, now.format(formatter)); + newCookie.setMaxAge(60 * 60 * 24 * 365); + response.addCookie(newCookie); + } + } + + private void incrementGatheringViewCount(Gathering gathering) { + gathering.upViewCount(); + } + } \ No newline at end of file From 268186593929cb896f034bdb955ec557c67dcd50 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Mon, 9 Sep 2024 14:08:26 +0900 Subject: [PATCH 256/371] =?UTF-8?q?feat:=20gathering=20detail=20=EC=A1=B0?= =?UTF-8?q?=ED=9A=8C=20api=20=EC=9A=94=EC=B2=AD=EC=8B=9C=20=EC=A1=B0?= =?UTF-8?q?=ED=9A=8C=EC=88=98=20=EC=98=AC=EB=A6=AC=EA=B8=B0=20=EC=9C=84?= =?UTF-8?q?=ED=95=9C=20HttpServletResponse=20=ED=8C=8C=EB=9D=BC=EB=AF=B8?= =?UTF-8?q?=ED=84=B0=EC=97=90=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../gathering/controller/GatheringController.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/solitour_backend/solitour/gathering/controller/GatheringController.java b/src/main/java/solitour_backend/solitour/gathering/controller/GatheringController.java index 177e9761..429f3c5c 100644 --- a/src/main/java/solitour_backend/solitour/gathering/controller/GatheringController.java +++ b/src/main/java/solitour_backend/solitour/gathering/controller/GatheringController.java @@ -3,11 +3,11 @@ import static solitour_backend.solitour.information.controller.InformationController.PAGE_SIZE; import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import jakarta.validation.Valid; import java.io.UnsupportedEncodingException; import java.time.LocalDateTime; -import java.util.Base64; import java.util.List; import java.util.Objects; @@ -34,7 +34,6 @@ import solitour_backend.solitour.error.Utils; import solitour_backend.solitour.error.exception.RequestValidationFailedException; import solitour_backend.solitour.gathering.dto.request.GatheringModifyRequest; -import solitour_backend.solitour.gathering.dto.request.GatheringNotFinishRequest; import solitour_backend.solitour.gathering.dto.request.GatheringPageRequest; import solitour_backend.solitour.gathering.dto.request.GatheringRegisterRequest; import solitour_backend.solitour.gathering.dto.response.GatheringBriefResponse; @@ -76,9 +75,10 @@ public ResponseEntity createGathering(@AuthenticationPrincipa @GetMapping("/{id}") public ResponseEntity getGatheringDetail(@PathVariable Long id, - HttpServletRequest request) { + HttpServletRequest request, + HttpServletResponse response) { Long userId = findUser(request); - GatheringDetailResponse gatheringDetail = gatheringService.getGatheringDetail(userId, id); + GatheringDetailResponse gatheringDetail = gatheringService.getGatheringDetail(userId, id, request, response); return ResponseEntity .status(HttpStatus.OK) From 0f2a31541cf3c8c3d1740bb4b7aef4c4ade3fe3a Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Mon, 9 Sep 2024 14:21:45 +0900 Subject: [PATCH 257/371] =?UTF-8?q?feat:=20=ED=95=9C=20=EB=B8=8C=EB=9D=BC?= =?UTF-8?q?=EC=9A=B0=EC=A0=80=EC=97=90=20a=20=EB=9D=BC=EB=8A=94=20?= =?UTF-8?q?=ED=9A=8C=EC=9B=90=EC=9D=B4=20=EC=A1=B0=ED=9A=8C=EB=A5=BC=20?= =?UTF-8?q?=ED=96=88=EC=96=B4=20=EA=B7=B8=20=EB=8B=A4=EC=9D=8C=EC=97=90=20?= =?UTF-8?q?=EB=A1=9C=EA=B7=B8=EC=95=84=EC=9B=83=ED=95=98=EA=B3=A0=20b=20?= =?UTF-8?q?=ED=9A=8C=EC=9B=90=EC=9D=B4=20=EC=A1=B0=ED=9A=8C=EB=A5=BC=20?= =?UTF-8?q?=ED=96=88=EC=96=B4=20=EA=B7=B8=20=EB=8B=A4=EC=9D=8C=20=EB=A1=9C?= =?UTF-8?q?=EA=B7=B8=EC=95=84=EC=9B=83=20=ED=95=98=EA=B3=A0=20=EB=B9=84?= =?UTF-8?q?=ED=9A=8C=EC=9B=90=EC=9D=B4=20=EC=A1=B0=ED=9A=8C=EB=A5=BC=20?= =?UTF-8?q?=ED=96=88=EC=96=B4=20=EC=9D=B4=EB=A0=87=EA=B2=8C=20=ED=95=98?= =?UTF-8?q?=EB=A9=B4=203=EC=9D=B4=20=EC=A6=9D=EA=B0=80=20=ED=95=B4?= =?UTF-8?q?=EC=95=BC=20=ED=95=9C=EB=8B=A4=20=EC=9D=B4=EB=9F=B0=20=EC=8B=9C?= =?UTF-8?q?=EB=82=98=EB=A6=AC=EC=98=A4=EB=A5=BC=20=EC=9C=84=ED=95=9C=20?= =?UTF-8?q?=EB=A1=9C=EC=A7=81=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../solitour/gathering/service/GatheringService.java | 6 +++--- .../solitour/information/service/InformationService.java | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/main/java/solitour_backend/solitour/gathering/service/GatheringService.java b/src/main/java/solitour_backend/solitour/gathering/service/GatheringService.java index 8585ef48..df895ec7 100644 --- a/src/main/java/solitour_backend/solitour/gathering/service/GatheringService.java +++ b/src/main/java/solitour_backend/solitour/gathering/service/GatheringService.java @@ -148,7 +148,7 @@ public GatheringDetailResponse getGatheringDetail(Long userId, Long gatheringId, List gatheringRecommend = gatheringRepository.getGatheringRecommend(gathering.getId(), gathering.getGatheringCategory().getId(), userId); - updateViewCount(gathering, request, response); + updateViewCount(gathering, request, response, userId); return new GatheringDetailResponse( gathering.getTitle(), @@ -466,8 +466,8 @@ private void validateGatheringPageRequest(GatheringPageRequest gatheringPageRequ } } - public void updateViewCount(Gathering gathering, HttpServletRequest request, HttpServletResponse response) { - String cookieName = "viewed_gathering_" + gathering.getId(); + public void updateViewCount(Gathering gathering, HttpServletRequest request, HttpServletResponse response, Long userId) { + String cookieName = "viewed_gathering_" + userId + "_" + gathering.getId(); Cookie[] cookies = request.getCookies(); Cookie postCookie = null; diff --git a/src/main/java/solitour_backend/solitour/information/service/InformationService.java b/src/main/java/solitour_backend/solitour/information/service/InformationService.java index 1cd4b149..9966d4bc 100644 --- a/src/main/java/solitour_backend/solitour/information/service/InformationService.java +++ b/src/main/java/solitour_backend/solitour/information/service/InformationService.java @@ -202,7 +202,7 @@ public InformationDetailResponse getDetailInformation(Long userId, Long informat .orElseGet( () -> userRepository.getProfileUrl(user.getSex())); - updateViewCount(information, request, response); + updateViewCount(information, request, response, userId); return new InformationDetailResponse( information.getTitle(), @@ -464,8 +464,8 @@ public Page getPageInformationByTag(Pageable pageable, decodedTag); } - public void updateViewCount(Information information, HttpServletRequest request, HttpServletResponse response) { - String cookieName = "viewed_information_" + information.getId(); + public void updateViewCount(Information information, HttpServletRequest request, HttpServletResponse response, Long userId) { + String cookieName = "viewed_information_" + userId + "_" + information.getId(); Cookie[] cookies = request.getCookies(); Cookie postCookie = null; From 99d101538a3c5d5a2222f8a4ffede4a708f8ee8c Mon Sep 17 00:00:00 2001 From: Donghun Won Date: Mon, 9 Sep 2024 17:20:54 +0900 Subject: [PATCH 258/371] =?UTF-8?q?Refactor=20:=20=EB=8B=A4=EC=9D=B4?= =?UTF-8?q?=EC=96=B4=EB=A6=AC=20=EC=BD=98=ED=85=90=ED=8A=B8=20=EC=9D=B4?= =?UTF-8?q?=EB=AF=B8=EC=A7=80=20=ED=95=84=EB=93=9C=20=EC=B6=94=EA=B0=80?= =?UTF-8?q?=EC=97=90=20=EB=94=B0=EB=9D=BC=20=EB=A1=9C=EC=A7=81=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD=20(#161)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../diary/controller/DiaryController.java | 15 ++-- .../diary_day_content/DiaryDayContent.java | 16 ++++ .../DiaryCreateRequest.java} | 5 +- .../diary/dto/request/DiaryUpdateRequest.java | 38 ++++++++ .../dto/{ => response}/DiaryContent.java | 5 +- .../{ => response}/DiaryDayContentDetail.java | 4 +- .../dto/{ => response}/DiaryListResponse.java | 2 +- .../dto/{ => response}/DiaryResponse.java | 4 +- .../solitour/diary/entity/Diary.java | 7 +- .../repository/DiaryRepositoryCustom.java | 2 +- .../diary/repository/DiaryRepositoryImpl.java | 4 +- .../solitour/diary/service/DiaryService.java | 88 ++++++++++++++----- 12 files changed, 146 insertions(+), 44 deletions(-) rename src/main/java/solitour_backend/solitour/diary/dto/{DiaryRequest.java => request/DiaryCreateRequest.java} (79%) create mode 100644 src/main/java/solitour_backend/solitour/diary/dto/request/DiaryUpdateRequest.java rename src/main/java/solitour_backend/solitour/diary/dto/{ => response}/DiaryContent.java (92%) rename src/main/java/solitour_backend/solitour/diary/dto/{ => response}/DiaryDayContentDetail.java (69%) rename src/main/java/solitour_backend/solitour/diary/dto/{ => response}/DiaryListResponse.java (97%) rename src/main/java/solitour_backend/solitour/diary/dto/{ => response}/DiaryResponse.java (91%) diff --git a/src/main/java/solitour_backend/solitour/diary/controller/DiaryController.java b/src/main/java/solitour_backend/solitour/diary/controller/DiaryController.java index d5cf9c42..bbbef91f 100644 --- a/src/main/java/solitour_backend/solitour/diary/controller/DiaryController.java +++ b/src/main/java/solitour_backend/solitour/diary/controller/DiaryController.java @@ -4,7 +4,6 @@ import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Pageable; -import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; @@ -17,9 +16,10 @@ import org.springframework.web.bind.annotation.RestController; import solitour_backend.solitour.auth.config.Authenticated; import solitour_backend.solitour.auth.config.AuthenticationPrincipal; -import solitour_backend.solitour.diary.dto.DiaryContent; -import solitour_backend.solitour.diary.dto.DiaryRequest; -import solitour_backend.solitour.diary.dto.DiaryResponse; +import solitour_backend.solitour.diary.dto.request.DiaryUpdateRequest; +import solitour_backend.solitour.diary.dto.response.DiaryContent; +import solitour_backend.solitour.diary.dto.request.DiaryCreateRequest; +import solitour_backend.solitour.diary.dto.response.DiaryResponse; import solitour_backend.solitour.diary.service.DiaryService; @RestController @@ -30,7 +30,6 @@ public class DiaryController { private final DiaryService diaryService; public static final int PAGE_SIZE = 6; - @Authenticated @GetMapping() public ResponseEntity> getAllDiary(@RequestParam(defaultValue = "0") int page, @@ -53,7 +52,7 @@ public ResponseEntity getDiary(@AuthenticationPrincipal Long user @Authenticated @PostMapping() public ResponseEntity createDiary(@AuthenticationPrincipal Long userId, - @RequestBody DiaryRequest request) { + @RequestBody DiaryCreateRequest request) { Long diaryId = diaryService.createDiary(userId, request); return ResponseEntity.ok(diaryId); @@ -62,7 +61,7 @@ public ResponseEntity createDiary(@AuthenticationPrincipal Long userId, @Authenticated @PutMapping() public ResponseEntity updateDiary(@AuthenticationPrincipal Long userId, @RequestParam Long diaryId, - @RequestBody DiaryRequest request) { + @RequestBody DiaryUpdateRequest request) { diaryService.updateDiary(userId, diaryId, request); return ResponseEntity.ok(diaryId); @@ -73,6 +72,6 @@ public ResponseEntity updateDiary(@AuthenticationPrincipal Long userId, @R public ResponseEntity deleteDiary(@AuthenticationPrincipal Long userId, @RequestParam Long diaryId) { diaryService.deleteDiary(userId, diaryId); - return ResponseEntity.status(HttpStatus.OK).build(); + return ResponseEntity.noContent().build(); } } diff --git a/src/main/java/solitour_backend/solitour/diary/diary_day_content/DiaryDayContent.java b/src/main/java/solitour_backend/solitour/diary/diary_day_content/DiaryDayContent.java index 4a630075..3e32727f 100644 --- a/src/main/java/solitour_backend/solitour/diary/diary_day_content/DiaryDayContent.java +++ b/src/main/java/solitour_backend/solitour/diary/diary_day_content/DiaryDayContent.java @@ -11,6 +11,9 @@ import jakarta.persistence.JoinColumn; import jakarta.persistence.ManyToOne; import jakarta.persistence.Table; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Getter; @@ -41,6 +44,9 @@ public class DiaryDayContent { @Column(name = "diary_day_content_place") private String place; + @Column(name = "diary_day_content_image") + private String contentImage; + @Column(columnDefinition = "LONGTEXT", name = "diary_day_content_content") private String content; @@ -48,4 +54,14 @@ public class DiaryDayContent { @Convert(converter = FeelingStatusConverter.class) private FeelingStatus feelingStatus; + public List getDiaryDayContentImagesList() { + if (contentImage == null || contentImage.isEmpty()) { + return new ArrayList<>(); + } + return Arrays.asList(contentImage.split(",")); + } + + public void setDiaryDayContentImagesList(List imageUrls) { + this.contentImage = String.join(",", imageUrls); + } } diff --git a/src/main/java/solitour_backend/solitour/diary/dto/DiaryRequest.java b/src/main/java/solitour_backend/solitour/diary/dto/request/DiaryCreateRequest.java similarity index 79% rename from src/main/java/solitour_backend/solitour/diary/dto/DiaryRequest.java rename to src/main/java/solitour_backend/solitour/diary/dto/request/DiaryCreateRequest.java index 4501c7c0..1debd1d0 100644 --- a/src/main/java/solitour_backend/solitour/diary/dto/DiaryRequest.java +++ b/src/main/java/solitour_backend/solitour/diary/dto/request/DiaryCreateRequest.java @@ -1,4 +1,4 @@ -package solitour_backend.solitour.diary.dto; +package solitour_backend.solitour.diary.dto.request; import java.time.LocalDateTime; import java.util.List; @@ -7,7 +7,7 @@ @Getter @AllArgsConstructor -public class DiaryRequest { +public class DiaryCreateRequest { private String title; private String titleImage; private LocalDateTime startDatetime; @@ -19,6 +19,7 @@ public class DiaryRequest { public static class DiaryDayRequest { private String content; private String feelingStatus; + private String diaryDayContentImages; private String place; } } diff --git a/src/main/java/solitour_backend/solitour/diary/dto/request/DiaryUpdateRequest.java b/src/main/java/solitour_backend/solitour/diary/dto/request/DiaryUpdateRequest.java new file mode 100644 index 00000000..d7abd567 --- /dev/null +++ b/src/main/java/solitour_backend/solitour/diary/dto/request/DiaryUpdateRequest.java @@ -0,0 +1,38 @@ +package solitour_backend.solitour.diary.dto.request; + +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor +public class DiaryUpdateRequest { + private String title; + private String deleteTitleImage; + private String saveTitleImage; + private LocalDateTime startDatetime; + private LocalDateTime endDatetime; + private List diaryDayRequests; + + @Getter + @AllArgsConstructor + public static class DiaryUpdateDayRequest { + private String content; + private String feelingStatus; + private String deleteImagesUrl; + private String saveImagesUrl; + private String place; + + public List getSplitImageUrl(String urlList) { + if (urlList == null || urlList.isEmpty()) { + return new ArrayList<>(); + } + return Arrays.asList(urlList.split(",")); + } + } + + +} diff --git a/src/main/java/solitour_backend/solitour/diary/dto/DiaryContent.java b/src/main/java/solitour_backend/solitour/diary/dto/response/DiaryContent.java similarity index 92% rename from src/main/java/solitour_backend/solitour/diary/dto/DiaryContent.java rename to src/main/java/solitour_backend/solitour/diary/dto/response/DiaryContent.java index 836f4d78..ca3aa552 100644 --- a/src/main/java/solitour_backend/solitour/diary/dto/DiaryContent.java +++ b/src/main/java/solitour_backend/solitour/diary/dto/response/DiaryContent.java @@ -1,4 +1,4 @@ -package solitour_backend.solitour.diary.dto; +package solitour_backend.solitour.diary.dto.response; import java.time.LocalDateTime; import java.util.List; @@ -41,7 +41,8 @@ public DiaryDayContentResponse(List diaryDayContent) { new DiaryDayContentDetail( diaryDayContentDetail.getContent(), diaryDayContentDetail.getFeelingStatus().name(), - diaryDayContentDetail.getPlace() + diaryDayContentDetail.getPlace(), + diaryDayContentDetail.getContentImage() ) ).collect(Collectors.toList()); } diff --git a/src/main/java/solitour_backend/solitour/diary/dto/DiaryDayContentDetail.java b/src/main/java/solitour_backend/solitour/diary/dto/response/DiaryDayContentDetail.java similarity index 69% rename from src/main/java/solitour_backend/solitour/diary/dto/DiaryDayContentDetail.java rename to src/main/java/solitour_backend/solitour/diary/dto/response/DiaryDayContentDetail.java index 3d64d6d4..96a6f1a4 100644 --- a/src/main/java/solitour_backend/solitour/diary/dto/DiaryDayContentDetail.java +++ b/src/main/java/solitour_backend/solitour/diary/dto/response/DiaryDayContentDetail.java @@ -1,5 +1,6 @@ -package solitour_backend.solitour.diary.dto; +package solitour_backend.solitour.diary.dto.response; +import java.util.List; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Getter; @@ -11,4 +12,5 @@ public class DiaryDayContentDetail { private String content; private String feelingStatus; private String place; + private String contentImage; } diff --git a/src/main/java/solitour_backend/solitour/diary/dto/DiaryListResponse.java b/src/main/java/solitour_backend/solitour/diary/dto/response/DiaryListResponse.java similarity index 97% rename from src/main/java/solitour_backend/solitour/diary/dto/DiaryListResponse.java rename to src/main/java/solitour_backend/solitour/diary/dto/response/DiaryListResponse.java index f0874032..b3fe9ef5 100644 --- a/src/main/java/solitour_backend/solitour/diary/dto/DiaryListResponse.java +++ b/src/main/java/solitour_backend/solitour/diary/dto/response/DiaryListResponse.java @@ -1,4 +1,4 @@ -package solitour_backend.solitour.diary.dto; +package solitour_backend.solitour.diary.dto.response; import java.time.LocalDateTime; import java.util.List; diff --git a/src/main/java/solitour_backend/solitour/diary/dto/DiaryResponse.java b/src/main/java/solitour_backend/solitour/diary/dto/response/DiaryResponse.java similarity index 91% rename from src/main/java/solitour_backend/solitour/diary/dto/DiaryResponse.java rename to src/main/java/solitour_backend/solitour/diary/dto/response/DiaryResponse.java index 1ac8d45e..2620e7d1 100644 --- a/src/main/java/solitour_backend/solitour/diary/dto/DiaryResponse.java +++ b/src/main/java/solitour_backend/solitour/diary/dto/response/DiaryResponse.java @@ -1,4 +1,4 @@ -package solitour_backend.solitour.diary.dto; +package solitour_backend.solitour.diary.dto.response; import java.time.LocalDateTime; import java.util.List; @@ -47,6 +47,7 @@ private DiaryDayContentResponse(List diaryDayContent) { .content(diaryDayContentDetail.getContent()) .feelingStatus(diaryDayContentDetail.getFeelingStatus().name()) .place(diaryDayContentDetail.getPlace()) + .diaryDayContentImages(diaryDayContentDetail.getContentImage()) .build() ).collect(Collectors.toList()); } @@ -59,6 +60,7 @@ private static class DiaryDayContentDetail { private String content; private String feelingStatus; private String place; + private String diaryDayContentImages; } } diff --git a/src/main/java/solitour_backend/solitour/diary/entity/Diary.java b/src/main/java/solitour_backend/solitour/diary/entity/Diary.java index c9b174b5..0b17d215 100644 --- a/src/main/java/solitour_backend/solitour/diary/entity/Diary.java +++ b/src/main/java/solitour_backend/solitour/diary/entity/Diary.java @@ -22,7 +22,8 @@ import org.springframework.data.annotation.LastModifiedDate; import org.springframework.data.jpa.domain.support.AuditingEntityListener; import solitour_backend.solitour.diary.diary_day_content.DiaryDayContent; -import solitour_backend.solitour.diary.dto.DiaryRequest; +import solitour_backend.solitour.diary.dto.request.DiaryCreateRequest; +import solitour_backend.solitour.diary.dto.request.DiaryUpdateRequest; import solitour_backend.solitour.user.entity.User; @@ -67,9 +68,9 @@ public class Diary { @Column(name = "diary_edited_date") private LocalDateTime editedAt; - public void updateDiary(DiaryRequest request) { + public void updateDiary(DiaryUpdateRequest request) { this.title = request.getTitle(); - this.titleImage = request.getTitleImage(); + this.titleImage = request.getSaveTitleImage(); this.startDatetime = request.getStartDatetime(); this.endDatetime = request.getEndDatetime(); } diff --git a/src/main/java/solitour_backend/solitour/diary/repository/DiaryRepositoryCustom.java b/src/main/java/solitour_backend/solitour/diary/repository/DiaryRepositoryCustom.java index c82238e1..f6fefa9e 100644 --- a/src/main/java/solitour_backend/solitour/diary/repository/DiaryRepositoryCustom.java +++ b/src/main/java/solitour_backend/solitour/diary/repository/DiaryRepositoryCustom.java @@ -3,7 +3,7 @@ import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.repository.NoRepositoryBean; -import solitour_backend.solitour.diary.dto.DiaryContent; +import solitour_backend.solitour.diary.dto.response.DiaryContent; @NoRepositoryBean public interface DiaryRepositoryCustom { diff --git a/src/main/java/solitour_backend/solitour/diary/repository/DiaryRepositoryImpl.java b/src/main/java/solitour_backend/solitour/diary/repository/DiaryRepositoryImpl.java index 97aa245e..6582ed5f 100644 --- a/src/main/java/solitour_backend/solitour/diary/repository/DiaryRepositoryImpl.java +++ b/src/main/java/solitour_backend/solitour/diary/repository/DiaryRepositoryImpl.java @@ -11,8 +11,8 @@ import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.support.QuerydslRepositorySupport; import solitour_backend.solitour.diary.diary_day_content.QDiaryDayContent; -import solitour_backend.solitour.diary.dto.DiaryContent; -import solitour_backend.solitour.diary.dto.DiaryContent.DiaryDayContentResponse; +import solitour_backend.solitour.diary.dto.response.DiaryContent; +import solitour_backend.solitour.diary.dto.response.DiaryContent.DiaryDayContentResponse; import solitour_backend.solitour.diary.entity.Diary; import solitour_backend.solitour.diary.entity.QDiary; import solitour_backend.solitour.user.entity.QUser; diff --git a/src/main/java/solitour_backend/solitour/diary/service/DiaryService.java b/src/main/java/solitour_backend/solitour/diary/service/DiaryService.java index 669d53fe..459d8599 100644 --- a/src/main/java/solitour_backend/solitour/diary/service/DiaryService.java +++ b/src/main/java/solitour_backend/solitour/diary/service/DiaryService.java @@ -1,20 +1,25 @@ package solitour_backend.solitour.diary.service; import java.time.LocalDateTime; +import java.util.List; import lombok.RequiredArgsConstructor; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import solitour_backend.solitour.diary.diary_day_content.DiaryDayContent; -import solitour_backend.solitour.diary.dto.DiaryContent; -import solitour_backend.solitour.diary.dto.DiaryRequest; -import solitour_backend.solitour.diary.dto.DiaryRequest.DiaryDayRequest; -import solitour_backend.solitour.diary.dto.DiaryResponse; +import solitour_backend.solitour.diary.dto.request.DiaryUpdateRequest; +import solitour_backend.solitour.diary.dto.request.DiaryUpdateRequest.DiaryUpdateDayRequest; +import solitour_backend.solitour.diary.dto.response.DiaryContent; +import solitour_backend.solitour.diary.dto.request.DiaryCreateRequest; +import solitour_backend.solitour.diary.dto.request.DiaryCreateRequest.DiaryDayRequest; +import solitour_backend.solitour.diary.dto.response.DiaryResponse; import solitour_backend.solitour.diary.entity.Diary; import solitour_backend.solitour.diary.feeling_status.FeelingStatus; import solitour_backend.solitour.diary.repository.DiaryDayContentRepository; import solitour_backend.solitour.diary.repository.DiaryRepository; +import solitour_backend.solitour.image.dto.request.ImageRequest; +import solitour_backend.solitour.image.s3.S3Uploader; import solitour_backend.solitour.user.entity.User; import solitour_backend.solitour.user.repository.UserRepository; @@ -26,9 +31,10 @@ public class DiaryService { private final DiaryRepository diaryRepository; private final DiaryDayContentRepository diaryDayContentRepository; private final UserRepository userRepository; + private final S3Uploader s3Uploader; @Transactional - public Long createDiary(Long userId, DiaryRequest request) { + public Long createDiary(Long userId, DiaryCreateRequest request) { User user = userRepository.findByUserId(userId); Diary diary = Diary.builder() .user(user) @@ -46,24 +52,10 @@ public Long createDiary(Long userId, DiaryRequest request) { return savedDiary.getId(); } - - private void saveDiaryDayContent(Diary savedDiary, DiaryRequest request) { - for (DiaryDayRequest dayRequest : request.getDiaryDayRequests()) { - DiaryDayContent diaryDayContent = DiaryDayContent.builder() - .diary(savedDiary) - .content(dayRequest.getContent()) - .feelingStatus(FeelingStatus.valueOf(dayRequest.getFeelingStatus())) - .place(dayRequest.getPlace()) - .build(); - diaryDayContentRepository.save(diaryDayContent); - } - } - public Page getAllDiary(Pageable pageable, Long userId) { return diaryRepository.getAllDiaryPageFilterAndOrder(pageable, userId); } - public DiaryResponse getDiary(Long userId, Long diaryId) { Diary diary = diaryRepository.findById(diaryId) .orElseThrow(() -> new IllegalArgumentException("해당 일기가 존재하지 않습니다.")); @@ -79,27 +71,77 @@ public DiaryResponse getDiary(Long userId, Long diaryId) { public void deleteDiary(Long userId, Long diaryId) { Diary diary = diaryRepository.findById(diaryId) .orElseThrow(() -> new IllegalArgumentException("해당 일기가 존재하지 않습니다.")); + if (!diary.getUser().getId().equals(userId)) { throw new IllegalArgumentException("해당 일기에 대한 권한이 없습니다."); } + + deleteAllDiaryImage(diary.getDiaryDayContent()); diaryRepository.deleteById(diaryId); } @Transactional - public void updateDiary(Long userId, Long diaryId, DiaryRequest request) { + public void updateDiary(Long userId, Long diaryId, DiaryUpdateRequest request) { Diary diary = diaryRepository.findById(diaryId) .orElseThrow(() -> new IllegalArgumentException("해당 일기가 존재하지 않습니다.")); + if (!diary.getUser().getId().equals(userId)) { throw new IllegalArgumentException("해당 일기에 대한 권한이 없습니다."); } + updateDiary(diaryId, request); } - private void updateDiary(Long diaryId, DiaryRequest request) { + private void updateDiary(Long diaryId, DiaryUpdateRequest request) { Diary diary = diaryRepository.findById(diaryId).orElseThrow(() -> new RuntimeException("Diary not found")); + deleteDiaryImage(request); diary.getDiaryDayContent().clear(); diary.updateDiary(request); - saveDiaryDayContent(diary, request); + updateDiaryDayContent(diary, request); + } + + private void saveDiaryDayContent(Diary savedDiary, DiaryCreateRequest request) { + for (DiaryDayRequest dayRequest : request.getDiaryDayRequests()) { + DiaryDayContent diaryDayContent = DiaryDayContent.builder() + .diary(savedDiary) + .content(dayRequest.getContent()) + .contentImage(dayRequest.getDiaryDayContentImages()) + .feelingStatus(FeelingStatus.valueOf(dayRequest.getFeelingStatus())) + .place(dayRequest.getPlace()) + .build(); + diaryDayContentRepository.save(diaryDayContent); + } + } + + private void updateDiaryDayContent(Diary savedDiary, DiaryUpdateRequest request) { + diaryDayContentRepository.deleteById(savedDiary.getId()); + for (DiaryUpdateDayRequest dayRequest : request.getDiaryDayRequests()) { + DiaryDayContent diaryDayContent = DiaryDayContent.builder() + .diary(savedDiary) + .content(dayRequest.getContent()) + .contentImage(dayRequest.getSaveImagesUrl()) + .feelingStatus(FeelingStatus.valueOf(dayRequest.getFeelingStatus())) + .place(dayRequest.getPlace()) + .build(); + diaryDayContentRepository.save(diaryDayContent); + } } -} \ No newline at end of file + private void deleteDiaryImage(DiaryUpdateRequest request) { + s3Uploader.deleteImage(request.getDeleteTitleImage()); + + for (DiaryUpdateDayRequest dayRequest : request.getDiaryDayRequests()) { + for (String imageUrl : dayRequest.getSplitImageUrl(dayRequest.getDeleteImagesUrl())) { + s3Uploader.deleteImage(imageUrl); + } + } + } + + private void deleteAllDiaryImage(List diaryDayContent) { + for (DiaryDayContent content : diaryDayContent) { + for (String imageUrl : content.getDiaryDayContentImagesList()) { + s3Uploader.deleteImage(imageUrl); + } + } + } +} From 71c25c3cc5490e714403037716e06c70b801bdf0 Mon Sep 17 00:00:00 2001 From: Donghun Won Date: Mon, 9 Sep 2024 19:08:56 +0900 Subject: [PATCH 259/371] =?UTF-8?q?Fix=20:=20qna=20=EA=B2=B0=EA=B3=BC=20?= =?UTF-8?q?=EC=96=BB=EC=9D=84=EB=95=8C=20=EB=B0=9C=EC=83=9D=ED=95=98?= =?UTF-8?q?=EB=8A=94=20no=20session=20=EB=AC=B8=EC=A0=9C=20=ED=95=B4?= =?UTF-8?q?=EA=B2=B0=20(#163)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../solitour/admin/controller/QnAController.java | 4 ++-- .../admin/dto/response/QnaListResponseDto.java | 2 ++ .../solitour/admin/repository/QnARepository.java | 2 ++ .../solitour/admin/service/QnAService.java | 13 +++++++++++-- 4 files changed, 17 insertions(+), 4 deletions(-) diff --git a/src/main/java/solitour_backend/solitour/admin/controller/QnAController.java b/src/main/java/solitour_backend/solitour/admin/controller/QnAController.java index 2f105317..f8e7f502 100644 --- a/src/main/java/solitour_backend/solitour/admin/controller/QnAController.java +++ b/src/main/java/solitour_backend/solitour/admin/controller/QnAController.java @@ -57,8 +57,8 @@ public Page getPagedQnAsByUserId( @Authenticated @GetMapping("/{id}") - public ResponseEntity getQnAById(@AuthenticationPrincipal Long userId, @PathVariable Long id) { - QnA qna = qnaService.getQnAById(id, userId); + public ResponseEntity getQnAById(@AuthenticationPrincipal Long userId, @PathVariable Long id) { + QnaListResponseDto qna = qnaService.getQnAById(id, userId); return ResponseEntity .status(HttpStatus.OK) .body(qna); diff --git a/src/main/java/solitour_backend/solitour/admin/dto/response/QnaListResponseDto.java b/src/main/java/solitour_backend/solitour/admin/dto/response/QnaListResponseDto.java index f94ea55c..8fa0168a 100644 --- a/src/main/java/solitour_backend/solitour/admin/dto/response/QnaListResponseDto.java +++ b/src/main/java/solitour_backend/solitour/admin/dto/response/QnaListResponseDto.java @@ -1,11 +1,13 @@ package solitour_backend.solitour.admin.dto.response; import lombok.AllArgsConstructor; +import lombok.Builder; import lombok.Getter; import java.time.LocalDateTime; @Getter +@Builder @AllArgsConstructor public class QnaListResponseDto { private Long id; diff --git a/src/main/java/solitour_backend/solitour/admin/repository/QnARepository.java b/src/main/java/solitour_backend/solitour/admin/repository/QnARepository.java index 5cbf220c..cd5c505f 100644 --- a/src/main/java/solitour_backend/solitour/admin/repository/QnARepository.java +++ b/src/main/java/solitour_backend/solitour/admin/repository/QnARepository.java @@ -10,6 +10,8 @@ public interface QnARepository extends JpaRepository { + @Query("SELECT new solitour_backend.solitour.admin.dto.response.QnaListResponseDto(q.id, q.title, q.createdAt, q.status, q.updatedAt, q.categoryName, u.id, u.nickname) " + + "FROM QnA q JOIN User u ON q.userId =:userId ORDER BY q.updatedAt ASC") Page findByUserId(Long userId, Pageable pageable); // 상태에 관계없이 모든 QnA 항목 검색 (updatedAt 기준 오름차순) diff --git a/src/main/java/solitour_backend/solitour/admin/service/QnAService.java b/src/main/java/solitour_backend/solitour/admin/service/QnAService.java index 6abd9146..03330774 100644 --- a/src/main/java/solitour_backend/solitour/admin/service/QnAService.java +++ b/src/main/java/solitour_backend/solitour/admin/service/QnAService.java @@ -60,7 +60,7 @@ public Page getPagedQnAsByUserId(Long userId, int page, int size) { return qnaRepository.findByUserId(userId, pageable); } - public QnA getQnAById(Long id, Long userId) { + public QnaListResponseDto getQnAById(Long id, Long userId) { QnA qna = qnaRepository.findById(id).orElse(null); if (qna == null) { @@ -75,7 +75,16 @@ public QnA getQnAById(Long id, Long userId) { List qnAMessages = qna.getQnaMessages(); qna.setQnaMessages(qnAMessages); - return qna; + QnaListResponseDto qnaListResponseDto = QnaListResponseDto.builder() + .title(qna.getTitle()) + .createdAt(qna.getCreatedAt()) + .status(qna.getStatus()) + .updatedAt(qna.getUpdatedAt()) + .categoryName(qna.getCategoryName()) + .userId(qna.getUserId()) + .userNickname(user.getNickname()) + .build(); + return qnaListResponseDto; } public void closeQnA(Long id, Long userId) { From e918af444b8a214756198dfe9ea8ff8d24c53e26 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Mon, 9 Sep 2024 20:18:48 +0900 Subject: [PATCH 260/371] =?UTF-8?q?feat:=20=EB=A7=88=EA=B0=90=EC=9D=BC?= =?UTF-8?q?=EC=9D=B4=20=EC=A7=80=EB=82=9C=20=EB=AA=A8=EC=9E=84=EB=93=A4?= =?UTF-8?q?=EC=9D=80=20=EC=95=88=EB=B3=B4=EC=97=AC=EC=A3=BC=EB=8A=94=20whe?= =?UTF-8?q?re=20=EC=A0=88=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../gathering/repository/GatheringRepositoryImpl.java | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryImpl.java b/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryImpl.java index 1878ae76..7e972c55 100644 --- a/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryImpl.java +++ b/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryImpl.java @@ -63,6 +63,7 @@ public List getGatheringRecommend(Long gatheringId, Long .and(gathering.gatheringCategory.id.eq(gatheringCategoryId)) .and(gathering.id.ne(gatheringId)) .and(gathering.isDeleted.eq(Boolean.FALSE)) + .and(gathering.deadline.after(LocalDateTime.now())) ) .groupBy(gathering.id, zoneCategoryChild.id, zoneCategoryParent.id, category.id, gathering.title, gathering.viewCount, gathering.user.name, @@ -220,7 +221,9 @@ public List getGatheringRankList() { .orderBy(countGreatGatheringByGatheringById().desc()) .groupBy(gathering.id, gathering.title) .where(gathering.isFinish.eq(Boolean.FALSE) - .and(gathering.isDeleted.eq(Boolean.FALSE))) + .and(gathering.isDeleted.eq(Boolean.FALSE)) + .and(gathering.deadline.after(LocalDateTime.now())) + ) .limit(5) .select(Projections.constructor( GatheringRankResponse.class, @@ -241,7 +244,8 @@ public List getGatheringLikeCountFromCreatedIn3(Long use .leftJoin(gatheringApplicants).on(gatheringApplicants.gathering.id.eq(gathering.id).and(gatheringApplicants.gatheringStatus.eq(GatheringStatus.CONSENT))) .where(gathering.isFinish.eq(Boolean.FALSE) .and(gathering.isDeleted.eq(Boolean.FALSE)) - .and(gathering.createdAt.after(LocalDateTime.now().minusMonths(3)))) + .and(gathering.createdAt.after(LocalDateTime.now().minusMonths(3))) + .and(gathering.deadline.after(LocalDateTime.now()))) .groupBy(gathering.id, zoneCategoryChild.id, zoneCategoryParent.id, category.id, gathering.title, gathering.viewCount, gathering.user.name, gathering.scheduleStartDate, gathering.scheduleEndDate, @@ -275,7 +279,7 @@ public List getGatheringLikeCountFromCreatedIn3(Long use private BooleanBuilder makeWhereSQL(GatheringPageRequest gatheringPageRequest) { BooleanBuilder whereClause = new BooleanBuilder(); - whereClause.and(gathering.isDeleted.eq(Boolean.FALSE)); + whereClause.and(gathering.isDeleted.eq(Boolean.FALSE).and(gathering.deadline.after(LocalDateTime.now()))); if (Objects.nonNull(gatheringPageRequest.getCategory())) { whereClause.and(gathering.gatheringCategory.id.eq(gatheringPageRequest.getCategory())); From 9323e8a8f65cdd7a55648ce5705963a4b2ea424b Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Mon, 9 Sep 2024 20:27:34 +0900 Subject: [PATCH 261/371] =?UTF-8?q?fix:=20binding=20result=20=EC=A0=9C?= =?UTF-8?q?=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../solitour/gathering/controller/GatheringController.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/main/java/solitour_backend/solitour/gathering/controller/GatheringController.java b/src/main/java/solitour_backend/solitour/gathering/controller/GatheringController.java index 429f3c5c..7648ea10 100644 --- a/src/main/java/solitour_backend/solitour/gathering/controller/GatheringController.java +++ b/src/main/java/solitour_backend/solitour/gathering/controller/GatheringController.java @@ -178,9 +178,7 @@ public ResponseEntity gatheringFinish(@AuthenticationPrincipal Long userId @PutMapping("/not-finish/{gatheringId}") public ResponseEntity gatheringNotFinish(@AuthenticationPrincipal Long userId, - @PathVariable Long gatheringId, - BindingResult bindingResult) { - Utils.validationRequest(bindingResult); + @PathVariable Long gatheringId) { gatheringService.setGatheringNotFinish(userId, gatheringId); From a3cc20217fe61be0fe5710da2d5b2332a576da68 Mon Sep 17 00:00:00 2001 From: Donghun Won Date: Tue, 10 Sep 2024 14:26:21 +0900 Subject: [PATCH 262/371] =?UTF-8?q?Fix=20:=20=EC=8A=B9=EC=9D=B8=EB=90=9C?= =?UTF-8?q?=20=EC=9C=A0=EC=A0=80=EB=A7=8C=20=EC=9D=B8=EC=9B=90=EC=88=98?= =?UTF-8?q?=EC=97=90=20=ED=8F=AC=ED=95=A8=ED=95=98=EB=8F=84=EB=A1=9D=20?= =?UTF-8?q?=EC=BF=BC=EB=A6=AC=20=EC=88=98=EC=A0=95=20(#168)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../gathering/repository/GatheringRepositoryImpl.java | 2 +- .../solitour/user/repository/UserRepositoryImpl.java | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryImpl.java b/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryImpl.java index 7e972c55..b4e2c3b2 100644 --- a/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryImpl.java +++ b/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryImpl.java @@ -180,7 +180,7 @@ public Page getPageGatheringByTag(Pageable pageable, .join(zoneCategoryChild).on(zoneCategoryChild.id.eq(gathering.zoneCategory.id)) .leftJoin(zoneCategoryParent).on(zoneCategoryParent.id.eq(zoneCategoryChild.parentZoneCategory.id)) .leftJoin(bookMarkGathering) - .on(bookMarkGathering.gathering.id.eq(gathering.id).and(bookMarkGathering.user.id.eq(userId))) + .on(gatheringApplicants.gathering.id.eq(gathering.id).and(gatheringApplicants.gatheringStatus.eq(GatheringStatus.CONSENT))) .leftJoin(gatheringApplicants).on(gatheringApplicants.gathering.id.eq(gathering.id).and(gatheringApplicants.gatheringStatus.eq(GatheringStatus.CONSENT))) .leftJoin(gatheringTag) .on(gatheringTag.gathering.id.eq(gathering.id).and(gatheringTag.tag.name.eq(decodedTag))) diff --git a/src/main/java/solitour_backend/solitour/user/repository/UserRepositoryImpl.java b/src/main/java/solitour_backend/solitour/user/repository/UserRepositoryImpl.java index 6c5c81b3..b2eade67 100644 --- a/src/main/java/solitour_backend/solitour/user/repository/UserRepositoryImpl.java +++ b/src/main/java/solitour_backend/solitour/user/repository/UserRepositoryImpl.java @@ -146,7 +146,7 @@ public Page retrieveGatheringHost(Pageable pageable, Lon .leftJoin(gatheringCategory) .on(gatheringCategory.id.eq(gathering.gatheringCategory.id)) .leftJoin(gatheringApplicants) - .on(gatheringApplicants.gathering.id.eq(gathering.id)) + .on(gatheringApplicants.gathering.id.eq(gathering.id).and(gatheringApplicants.gatheringStatus.eq(GatheringStatus.CONSENT))) .orderBy(gathering.createdAt.desc()) .where(gathering.user.id.eq(userId)); @@ -193,7 +193,7 @@ public Page retrieveGatheringBookmark(Pageable pageable, .leftJoin(gatheringCategory) .on(gatheringCategory.id.eq(gathering.gatheringCategory.id)) .leftJoin(gatheringApplicants) - .on(gatheringApplicants.gathering.id.eq(gathering.id)) + .on(gatheringApplicants.gathering.id.eq(gathering.id).and(gatheringApplicants.gatheringStatus.eq(GatheringStatus.CONSENT))) .leftJoin(bookMarkGathering) .on(bookMarkGathering.gathering.id.eq(gathering.id)) .orderBy(gathering.createdAt.desc()) @@ -243,7 +243,7 @@ public Page retrieveGatheringApplicant(Pageable page .leftJoin(gatheringCategory) .on(gatheringCategory.id.eq(gathering.gatheringCategory.id)) .leftJoin(gatheringApplicants) - .on(gatheringApplicants.gathering.id.eq(gathering.id)) + .on(gatheringApplicants.gathering.id.eq(gathering.id).and(gatheringApplicants.gatheringStatus.eq(GatheringStatus.CONSENT))) .leftJoin(gatheringApplicants) .on(gatheringApplicants.gathering.id.eq(gathering.id)) .orderBy(gathering.createdAt.desc()) From bdc5f0353447b783db72795642bfd1124afa81ab Mon Sep 17 00:00:00 2001 From: Donghun Won Date: Tue, 10 Sep 2024 17:53:30 +0900 Subject: [PATCH 263/371] =?UTF-8?q?Refactor(#169)=20:=20=EC=9D=BC=EA=B8=B0?= =?UTF-8?q?=20=EC=98=88=EC=99=B8=EC=B2=98=EB=A6=AC=20=20(#170)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Refactor : 다이어리 콘텐트 이미지 필드 추가에 따라 로직 변경 * Refactor : authenticated 위치 변경, 상태코드 변경 * Refactor : 일기 없을때, 일기 권한 없을때 예외처리 --- .../diary/controller/DiaryController.java | 19 ++++++++----------- .../exception/DiaryNotExistsException.java | 7 +++++++ .../diary/repository/DiaryRepositoryImpl.java | 5 +++++ .../solitour/diary/service/DiaryService.java | 15 ++++++++------- .../error/GlobalControllerAdvice.java | 9 +++++++-- .../exception/ForbiddenAccessException.java | 7 +++++++ 6 files changed, 42 insertions(+), 20 deletions(-) create mode 100644 src/main/java/solitour_backend/solitour/diary/exception/DiaryNotExistsException.java create mode 100644 src/main/java/solitour_backend/solitour/error/exception/ForbiddenAccessException.java diff --git a/src/main/java/solitour_backend/solitour/diary/controller/DiaryController.java b/src/main/java/solitour_backend/solitour/diary/controller/DiaryController.java index bbbef91f..6e917c73 100644 --- a/src/main/java/solitour_backend/solitour/diary/controller/DiaryController.java +++ b/src/main/java/solitour_backend/solitour/diary/controller/DiaryController.java @@ -4,6 +4,7 @@ import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Pageable; +import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; @@ -22,6 +23,7 @@ import solitour_backend.solitour.diary.dto.response.DiaryResponse; import solitour_backend.solitour.diary.service.DiaryService; +@Authenticated @RestController @RequiredArgsConstructor @RequestMapping("/api/diary") @@ -30,7 +32,6 @@ public class DiaryController { private final DiaryService diaryService; public static final int PAGE_SIZE = 6; - @Authenticated @GetMapping() public ResponseEntity> getAllDiary(@RequestParam(defaultValue = "0") int page, @AuthenticationPrincipal Long userId) { @@ -41,7 +42,6 @@ public ResponseEntity> getAllDiary(@RequestParam(defaultValue return ResponseEntity.ok(response); } - @Authenticated @GetMapping("/{diaryId}") public ResponseEntity getDiary(@AuthenticationPrincipal Long userId, @PathVariable Long diaryId) { DiaryResponse response = diaryService.getDiary(userId, diaryId); @@ -49,27 +49,24 @@ public ResponseEntity getDiary(@AuthenticationPrincipal Long user return ResponseEntity.ok(response); } - @Authenticated @PostMapping() public ResponseEntity createDiary(@AuthenticationPrincipal Long userId, @RequestBody DiaryCreateRequest request) { Long diaryId = diaryService.createDiary(userId, request); - return ResponseEntity.ok(diaryId); + return ResponseEntity.status(HttpStatus.CREATED).body(diaryId); } - @Authenticated - @PutMapping() - public ResponseEntity updateDiary(@AuthenticationPrincipal Long userId, @RequestParam Long diaryId, + @PutMapping("/{diaryId}") + public ResponseEntity updateDiary(@AuthenticationPrincipal Long userId, @PathVariable Long diaryId, @RequestBody DiaryUpdateRequest request) { diaryService.updateDiary(userId, diaryId, request); - return ResponseEntity.ok(diaryId); + return ResponseEntity.noContent().build(); } - @Authenticated - @DeleteMapping() - public ResponseEntity deleteDiary(@AuthenticationPrincipal Long userId, @RequestParam Long diaryId) { + @DeleteMapping("/{diaryId}") + public ResponseEntity deleteDiary(@AuthenticationPrincipal Long userId, @PathVariable Long diaryId) { diaryService.deleteDiary(userId, diaryId); return ResponseEntity.noContent().build(); diff --git a/src/main/java/solitour_backend/solitour/diary/exception/DiaryNotExistsException.java b/src/main/java/solitour_backend/solitour/diary/exception/DiaryNotExistsException.java new file mode 100644 index 00000000..09c94eff --- /dev/null +++ b/src/main/java/solitour_backend/solitour/diary/exception/DiaryNotExistsException.java @@ -0,0 +1,7 @@ +package solitour_backend.solitour.diary.exception; + +public class DiaryNotExistsException extends RuntimeException { + public DiaryNotExistsException(String message) { + super(message); + } +} diff --git a/src/main/java/solitour_backend/solitour/diary/repository/DiaryRepositoryImpl.java b/src/main/java/solitour_backend/solitour/diary/repository/DiaryRepositoryImpl.java index 6582ed5f..600608f4 100644 --- a/src/main/java/solitour_backend/solitour/diary/repository/DiaryRepositoryImpl.java +++ b/src/main/java/solitour_backend/solitour/diary/repository/DiaryRepositoryImpl.java @@ -15,6 +15,7 @@ import solitour_backend.solitour.diary.dto.response.DiaryContent.DiaryDayContentResponse; import solitour_backend.solitour.diary.entity.Diary; import solitour_backend.solitour.diary.entity.QDiary; +import solitour_backend.solitour.diary.exception.DiaryNotExistsException; import solitour_backend.solitour.user.entity.QUser; public class DiaryRepositoryImpl extends QuerydslRepositorySupport implements DiaryRepositoryCustom { @@ -52,6 +53,10 @@ public Page getAllDiaryPageFilterAndOrder(Pageable pageable, Long .limit(pageable.getPageSize()) .fetch(); + if (diaries == null) { + throw new DiaryNotExistsException("해당 일기가 존재하지 않습니다."); + } + List diaryContents = diaries.stream() .map(diary -> DiaryContent.builder() .diaryId(diary.getId()) diff --git a/src/main/java/solitour_backend/solitour/diary/service/DiaryService.java b/src/main/java/solitour_backend/solitour/diary/service/DiaryService.java index 459d8599..6f4d0dde 100644 --- a/src/main/java/solitour_backend/solitour/diary/service/DiaryService.java +++ b/src/main/java/solitour_backend/solitour/diary/service/DiaryService.java @@ -15,10 +15,11 @@ import solitour_backend.solitour.diary.dto.request.DiaryCreateRequest.DiaryDayRequest; import solitour_backend.solitour.diary.dto.response.DiaryResponse; import solitour_backend.solitour.diary.entity.Diary; +import solitour_backend.solitour.diary.exception.DiaryNotExistsException; import solitour_backend.solitour.diary.feeling_status.FeelingStatus; import solitour_backend.solitour.diary.repository.DiaryDayContentRepository; import solitour_backend.solitour.diary.repository.DiaryRepository; -import solitour_backend.solitour.image.dto.request.ImageRequest; +import solitour_backend.solitour.error.exception.ForbiddenAccessException; import solitour_backend.solitour.image.s3.S3Uploader; import solitour_backend.solitour.user.entity.User; import solitour_backend.solitour.user.repository.UserRepository; @@ -58,10 +59,10 @@ public Page getAllDiary(Pageable pageable, Long userId) { public DiaryResponse getDiary(Long userId, Long diaryId) { Diary diary = diaryRepository.findById(diaryId) - .orElseThrow(() -> new IllegalArgumentException("해당 일기가 존재하지 않습니다.")); + .orElseThrow(() -> new DiaryNotExistsException("해당하는 일기가 존재하지 않습니다.")); if (!diary.getUser().getId().equals(userId)) { - throw new IllegalArgumentException("해당 일기에 대한 권한이 없습니다."); + throw new ForbiddenAccessException("해당 일기에 대한 권한이 없습니다."); } return new DiaryResponse(diary); @@ -70,10 +71,10 @@ public DiaryResponse getDiary(Long userId, Long diaryId) { @Transactional public void deleteDiary(Long userId, Long diaryId) { Diary diary = diaryRepository.findById(diaryId) - .orElseThrow(() -> new IllegalArgumentException("해당 일기가 존재하지 않습니다.")); + .orElseThrow(() -> new DiaryNotExistsException("해당 일기가 존재하지 않습니다.")); if (!diary.getUser().getId().equals(userId)) { - throw new IllegalArgumentException("해당 일기에 대한 권한이 없습니다."); + throw new ForbiddenAccessException("해당 일기에 대한 권한이 없습니다."); } deleteAllDiaryImage(diary.getDiaryDayContent()); @@ -83,10 +84,10 @@ public void deleteDiary(Long userId, Long diaryId) { @Transactional public void updateDiary(Long userId, Long diaryId, DiaryUpdateRequest request) { Diary diary = diaryRepository.findById(diaryId) - .orElseThrow(() -> new IllegalArgumentException("해당 일기가 존재하지 않습니다.")); + .orElseThrow(() -> new DiaryNotExistsException("해당 일기가 존재하지 않습니다.")); if (!diary.getUser().getId().equals(userId)) { - throw new IllegalArgumentException("해당 일기에 대한 권한이 없습니다."); + throw new ForbiddenAccessException("해당 일기에 대한 권한이 없습니다."); } updateDiary(diaryId, request); diff --git a/src/main/java/solitour_backend/solitour/error/GlobalControllerAdvice.java b/src/main/java/solitour_backend/solitour/error/GlobalControllerAdvice.java index 4f04c056..eacf1021 100644 --- a/src/main/java/solitour_backend/solitour/error/GlobalControllerAdvice.java +++ b/src/main/java/solitour_backend/solitour/error/GlobalControllerAdvice.java @@ -8,6 +8,8 @@ import solitour_backend.solitour.book_mark_gathering.exception.GatheringBookMarkNotExistsException; import solitour_backend.solitour.book_mark_information.exception.InformationBookMarkNotExistsException; import solitour_backend.solitour.category.exception.CategoryNotExistsException; +import solitour_backend.solitour.diary.exception.DiaryNotExistsException; +import solitour_backend.solitour.error.exception.ForbiddenAccessException; import solitour_backend.solitour.error.exception.RequestValidationFailedException; import solitour_backend.solitour.gathering.exception.GatheringCategoryNotExistsException; import solitour_backend.solitour.gathering.exception.GatheringDeleteException; @@ -69,7 +71,8 @@ public ResponseEntity conflictException(Exception exception) { InformationGreatNotExistsException.class, GatheringGreatNotExistsException.class, GatheringBookMarkNotExistsException.class, - InformationBookMarkNotExistsException.class + InformationBookMarkNotExistsException.class, + DiaryNotExistsException.class, }) public ResponseEntity notFoundException(Exception exception) { return ResponseEntity @@ -77,7 +80,9 @@ public ResponseEntity notFoundException(Exception exception) { .body(exception.getMessage()); } - @ExceptionHandler({GatheringNotManagerException.class}) + @ExceptionHandler({GatheringNotManagerException.class, + ForbiddenAccessException.class + }) public ResponseEntity forbiddenException(Exception exception) { return ResponseEntity .status(HttpStatus.FORBIDDEN) diff --git a/src/main/java/solitour_backend/solitour/error/exception/ForbiddenAccessException.java b/src/main/java/solitour_backend/solitour/error/exception/ForbiddenAccessException.java new file mode 100644 index 00000000..195b8c34 --- /dev/null +++ b/src/main/java/solitour_backend/solitour/error/exception/ForbiddenAccessException.java @@ -0,0 +1,7 @@ +package solitour_backend.solitour.error.exception; + +public class ForbiddenAccessException extends RuntimeException { + public ForbiddenAccessException(String message) { + super(message); + } +} From 4c409a8c5206cd58ff898145df8a07bbfa6b6f6e Mon Sep 17 00:00:00 2001 From: "SK\\ssssk" Date: Tue, 10 Sep 2024 17:54:10 +0900 Subject: [PATCH 264/371] =?UTF-8?q?fix:=20qna=20=EC=83=81=EC=84=B8?= =?UTF-8?q?=EC=A0=95=EB=B3=B4=20=EC=A1=B0=ED=9A=8C=EC=8B=9C=20=EB=A9=94?= =?UTF-8?q?=EC=8B=9C=EC=A7=80=EB=93=A4=20=EC=95=88=EB=B3=B4=EC=9D=B4?= =?UTF-8?q?=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 --- .../admin/controller/QnAController.java | 5 ++-- .../admin/dto/response/QnaResponseDto.java | 24 +++++++++++++++++++ .../solitour/admin/service/QnAService.java | 16 +++++++------ 3 files changed, 36 insertions(+), 9 deletions(-) create mode 100644 src/main/java/solitour_backend/solitour/admin/dto/response/QnaResponseDto.java diff --git a/src/main/java/solitour_backend/solitour/admin/controller/QnAController.java b/src/main/java/solitour_backend/solitour/admin/controller/QnAController.java index f8e7f502..a28e301d 100644 --- a/src/main/java/solitour_backend/solitour/admin/controller/QnAController.java +++ b/src/main/java/solitour_backend/solitour/admin/controller/QnAController.java @@ -9,6 +9,7 @@ import solitour_backend.solitour.admin.dto.request.QnARegisterRequest; import solitour_backend.solitour.admin.dto.request.QuestionRegisterRequest; import solitour_backend.solitour.admin.dto.response.QnaListResponseDto; +import solitour_backend.solitour.admin.dto.response.QnaResponseDto; import solitour_backend.solitour.admin.entity.QnAMessage; import solitour_backend.solitour.admin.entity.QnA; import solitour_backend.solitour.admin.service.QnAService; @@ -57,8 +58,8 @@ public Page getPagedQnAsByUserId( @Authenticated @GetMapping("/{id}") - public ResponseEntity getQnAById(@AuthenticationPrincipal Long userId, @PathVariable Long id) { - QnaListResponseDto qna = qnaService.getQnAById(id, userId); + public ResponseEntity getQnAById(@AuthenticationPrincipal Long userId, @PathVariable Long id) { + QnaResponseDto qna = qnaService.getQnAById(id, userId); return ResponseEntity .status(HttpStatus.OK) .body(qna); diff --git a/src/main/java/solitour_backend/solitour/admin/dto/response/QnaResponseDto.java b/src/main/java/solitour_backend/solitour/admin/dto/response/QnaResponseDto.java new file mode 100644 index 00000000..c4268c28 --- /dev/null +++ b/src/main/java/solitour_backend/solitour/admin/dto/response/QnaResponseDto.java @@ -0,0 +1,24 @@ +package solitour_backend.solitour.admin.dto.response; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import solitour_backend.solitour.admin.entity.QnAMessage; + +import java.time.LocalDateTime; +import java.util.List; + +@Getter +@Builder +@AllArgsConstructor +public class QnaResponseDto { + private Long id; + private String title; + private LocalDateTime createdAt; + private String status; + private LocalDateTime updatedAt; + private String categoryName; + private Long userId; + private String userNickname; + private List qnaMessages; +} diff --git a/src/main/java/solitour_backend/solitour/admin/service/QnAService.java b/src/main/java/solitour_backend/solitour/admin/service/QnAService.java index 03330774..e42d0289 100644 --- a/src/main/java/solitour_backend/solitour/admin/service/QnAService.java +++ b/src/main/java/solitour_backend/solitour/admin/service/QnAService.java @@ -6,10 +6,12 @@ import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; import solitour_backend.solitour.admin.dto.request.AnswerRegisterRequest; import solitour_backend.solitour.admin.dto.request.QnARegisterRequest; import solitour_backend.solitour.admin.dto.request.QuestionRegisterRequest; import solitour_backend.solitour.admin.dto.response.QnaListResponseDto; +import solitour_backend.solitour.admin.dto.response.QnaResponseDto; import solitour_backend.solitour.admin.entity.QnA; import solitour_backend.solitour.admin.entity.QnAMessage; import solitour_backend.solitour.admin.repository.AnswerRepository; @@ -17,7 +19,6 @@ import solitour_backend.solitour.user.entity.User; import solitour_backend.solitour.user.repository.UserRepository; -import java.util.List; import java.util.Optional; @Service @@ -60,7 +61,8 @@ public Page getPagedQnAsByUserId(Long userId, int page, int size) { return qnaRepository.findByUserId(userId, pageable); } - public QnaListResponseDto getQnAById(Long id, Long userId) { + @Transactional + public QnaResponseDto getQnAById(Long id, Long userId) { QnA qna = qnaRepository.findById(id).orElse(null); if (qna == null) { @@ -72,10 +74,9 @@ public QnaListResponseDto getQnAById(Long id, Long userId) { if (qna.getUserId() != userId && !user.getIsAdmin()) { // 권한이 없는 경우 처리 } - - List qnAMessages = qna.getQnaMessages(); - qna.setQnaMessages(qnAMessages); - QnaListResponseDto qnaListResponseDto = QnaListResponseDto.builder() +// qna.getQnaMessages().size(); + QnaResponseDto qnaResponseDto = QnaResponseDto.builder() + .id(qna.getId()) .title(qna.getTitle()) .createdAt(qna.getCreatedAt()) .status(qna.getStatus()) @@ -83,8 +84,9 @@ public QnaListResponseDto getQnAById(Long id, Long userId) { .categoryName(qna.getCategoryName()) .userId(qna.getUserId()) .userNickname(user.getNickname()) + .qnaMessages(qna.getQnaMessages()) .build(); - return qnaListResponseDto; + return qnaResponseDto; } public void closeQnA(Long id, Long userId) { From 9b7ab8bcd63e1ba2212d8667f0c2f7f874a2434f Mon Sep 17 00:00:00 2001 From: "SK\\ssssk" Date: Tue, 10 Sep 2024 17:54:46 +0900 Subject: [PATCH 265/371] =?UTF-8?q?fix:=20qna=20=EB=A6=AC=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20=EC=A1=B0=ED=9A=8C=EC=8B=9C=20mysql=20=EC=BF=BC?= =?UTF-8?q?=EB=A6=AC=EA=B0=80=20=EC=9E=98=EB=AA=BB=EB=90=98=EC=96=B4?= =?UTF-8?q?=EC=84=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../solitour/admin/dto/response/QnaListResponseDto.java | 2 ++ .../solitour/admin/repository/QnARepository.java | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/solitour_backend/solitour/admin/dto/response/QnaListResponseDto.java b/src/main/java/solitour_backend/solitour/admin/dto/response/QnaListResponseDto.java index 8fa0168a..7851f6ee 100644 --- a/src/main/java/solitour_backend/solitour/admin/dto/response/QnaListResponseDto.java +++ b/src/main/java/solitour_backend/solitour/admin/dto/response/QnaListResponseDto.java @@ -3,8 +3,10 @@ import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Getter; +import solitour_backend.solitour.admin.entity.QnAMessage; import java.time.LocalDateTime; +import java.util.List; @Getter @Builder diff --git a/src/main/java/solitour_backend/solitour/admin/repository/QnARepository.java b/src/main/java/solitour_backend/solitour/admin/repository/QnARepository.java index cd5c505f..9b2a5254 100644 --- a/src/main/java/solitour_backend/solitour/admin/repository/QnARepository.java +++ b/src/main/java/solitour_backend/solitour/admin/repository/QnARepository.java @@ -11,7 +11,7 @@ public interface QnARepository extends JpaRepository { @Query("SELECT new solitour_backend.solitour.admin.dto.response.QnaListResponseDto(q.id, q.title, q.createdAt, q.status, q.updatedAt, q.categoryName, u.id, u.nickname) " + - "FROM QnA q JOIN User u ON q.userId =:userId ORDER BY q.updatedAt ASC") + "FROM QnA q JOIN User u ON q.userId = u.id WHERE q.userId = :userId ORDER BY q.updatedAt ASC") Page findByUserId(Long userId, Pageable pageable); // 상태에 관계없이 모든 QnA 항목 검색 (updatedAt 기준 오름차순) From 5ca08901a832bf8d583c5c9533a3bfb9520fd882 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Tue, 10 Sep 2024 20:11:44 +0900 Subject: [PATCH 266/371] =?UTF-8?q?fix:=20=EC=A1=B0=ED=9A=8C=EC=88=98=20?= =?UTF-8?q?=EC=BF=A0=ED=82=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../solitour/gathering/service/GatheringService.java | 10 +--------- .../information/service/InformationService.java | 2 +- 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/src/main/java/solitour_backend/solitour/gathering/service/GatheringService.java b/src/main/java/solitour_backend/solitour/gathering/service/GatheringService.java index df895ec7..cfdb6690 100644 --- a/src/main/java/solitour_backend/solitour/gathering/service/GatheringService.java +++ b/src/main/java/solitour_backend/solitour/gathering/service/GatheringService.java @@ -409,14 +409,6 @@ public void setGatheringNotFinish(Long userId, Long gatheringId) { throw new GatheringFinishConflictException("이미 모임이 not finish 상태입니다"); } -// if (gathering.getScheduleStartDate().isBefore(gatheringNotFinishRequest.getDeadline())) { -// throw new RequestValidationFailedException("마감일은 시작 날짜 보다 나중일 순 없습니다"); -// } -// -// if (Objects.nonNull(gatheringNotFinishRequest.getDeadline())) { -// gathering.setDeadline(gatheringNotFinishRequest.getDeadline()); -// } - gathering.setIsFinish(false); } @@ -479,7 +471,7 @@ public void updateViewCount(Gathering gathering, HttpServletRequest request, Htt } LocalDateTime now = LocalDateTime.now(); - DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-ddHH:mm:ss"); if (Objects.nonNull(postCookie)) { LocalDateTime lastViewedAt = LocalDateTime.parse(postCookie.getValue(), formatter); diff --git a/src/main/java/solitour_backend/solitour/information/service/InformationService.java b/src/main/java/solitour_backend/solitour/information/service/InformationService.java index 9966d4bc..67317445 100644 --- a/src/main/java/solitour_backend/solitour/information/service/InformationService.java +++ b/src/main/java/solitour_backend/solitour/information/service/InformationService.java @@ -477,7 +477,7 @@ public void updateViewCount(Information information, HttpServletRequest request, } LocalDateTime now = LocalDateTime.now(); - DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-ddHH:mm:ss"); if (Objects.nonNull(postCookie)) { LocalDateTime lastViewedAt = LocalDateTime.parse(postCookie.getValue(), formatter); From 65fb5b8256b3eaaa493bb020eb77c3a3d80719e9 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Thu, 12 Sep 2024 00:19:27 +0900 Subject: [PATCH 267/371] =?UTF-8?q?style:=20=ED=95=84=EC=9A=94=EC=97=86?= =?UTF-8?q?=EB=8A=94=20import=20=EB=AC=B8=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../solitour/gathering/service/GatheringService.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/solitour_backend/solitour/gathering/service/GatheringService.java b/src/main/java/solitour_backend/solitour/gathering/service/GatheringService.java index cfdb6690..7a60b8fb 100644 --- a/src/main/java/solitour_backend/solitour/gathering/service/GatheringService.java +++ b/src/main/java/solitour_backend/solitour/gathering/service/GatheringService.java @@ -46,7 +46,6 @@ import solitour_backend.solitour.gathering_tag.entity.GatheringTag; import solitour_backend.solitour.gathering_tag.repository.GatheringTagRepository; import solitour_backend.solitour.great_gathering.repository.GreatGatheringRepository; -import solitour_backend.solitour.information.entity.Information; import solitour_backend.solitour.place.dto.mapper.PlaceMapper; import solitour_backend.solitour.place.dto.request.PlaceModifyRequest; import solitour_backend.solitour.place.dto.request.PlaceRegisterRequest; From c70c4f1fa91e1d50e3d229902ab466f7f49e256e Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Thu, 12 Sep 2024 00:20:14 +0900 Subject: [PATCH 268/371] =?UTF-8?q?feat:=20=EC=A0=95=EB=B3=B4=20=EC=83=81?= =?UTF-8?q?=EC=84=B8=20dto=20response=20category=20=ED=95=84=EB=93=9C=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../information/dto/response/InformationDetailResponse.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/solitour_backend/solitour/information/dto/response/InformationDetailResponse.java b/src/main/java/solitour_backend/solitour/information/dto/response/InformationDetailResponse.java index 2c8a3337..ef5c47e6 100644 --- a/src/main/java/solitour_backend/solitour/information/dto/response/InformationDetailResponse.java +++ b/src/main/java/solitour_backend/solitour/information/dto/response/InformationDetailResponse.java @@ -2,8 +2,10 @@ import java.time.LocalDateTime; import java.util.List; + import lombok.AllArgsConstructor; import lombok.Getter; +import solitour_backend.solitour.category.dto.response.CategoryResponse; import solitour_backend.solitour.image.dto.response.ImageResponse; import solitour_backend.solitour.place.dto.response.PlaceResponse; import solitour_backend.solitour.tag.dto.response.TagResponse; @@ -26,7 +28,7 @@ public class InformationDetailResponse { private PlaceResponse placeResponse; private ZoneCategoryResponse zoneCategoryResponse; - + private CategoryResponse categoryResponse; private List imageResponses; private int likeCount; private String userImage; From fbaaf8ddb10ed5abd57e60c4ff0765a68d2e641d Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Thu, 12 Sep 2024 00:20:40 +0900 Subject: [PATCH 269/371] =?UTF-8?q?feat:=20information=20page=20request=20?= =?UTF-8?q?dto=20=EA=B2=80=EC=83=89=20=ED=95=84=EB=93=9C=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../information/dto/request/InformationPageRequest.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/solitour_backend/solitour/information/dto/request/InformationPageRequest.java b/src/main/java/solitour_backend/solitour/information/dto/request/InformationPageRequest.java index c3221822..2f175e8d 100644 --- a/src/main/java/solitour_backend/solitour/information/dto/request/InformationPageRequest.java +++ b/src/main/java/solitour_backend/solitour/information/dto/request/InformationPageRequest.java @@ -20,4 +20,6 @@ public class InformationPageRequest { @Min(1) private Long zoneCategoryId; + + private String search; } From 51f7fadbe70c5d4a79cdc09a3558b1cce859aa46 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Thu, 12 Sep 2024 00:21:55 +0900 Subject: [PATCH 270/371] =?UTF-8?q?feat:=20information=20page=20=20?= =?UTF-8?q?=EA=B2=80=EC=83=89=20=EA=B8=B0=EB=8A=A5=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../information/repository/InformationRepositoryImpl.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/main/java/solitour_backend/solitour/information/repository/InformationRepositoryImpl.java b/src/main/java/solitour_backend/solitour/information/repository/InformationRepositoryImpl.java index b8dc83f1..e1e083a0 100644 --- a/src/main/java/solitour_backend/solitour/information/repository/InformationRepositoryImpl.java +++ b/src/main/java/solitour_backend/solitour/information/repository/InformationRepositoryImpl.java @@ -9,9 +9,11 @@ import com.querydsl.core.types.dsl.NumberExpression; import com.querydsl.jpa.JPAExpressions; import com.querydsl.jpa.JPQLQuery; + import java.time.LocalDateTime; import java.util.List; import java.util.Objects; + import org.springframework.data.domain.Page; import org.springframework.data.domain.PageImpl; import org.springframework.data.domain.Pageable; @@ -65,6 +67,11 @@ public Page getInformationPageFilterAndOrder(Pageable categoryCondition.and(category.parentCategory.id.eq(parentCategoryId)); } + if (Objects.nonNull(informationPageRequest.getSearch())) { + String searchKeyword = informationPageRequest.getSearch().trim().replace(" ", ""); + whereClause.and(information.title.trim().containsIgnoreCase(searchKeyword)); + } + OrderSpecifier orderSpecifier = getOrderSpecifier(informationPageRequest.getSort()); NumberExpression countGreatInformation = countGreatInformationByInformationById(); From f87c60e210ef1ec9dafa88ed2f6a947950c94cf4 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Thu, 12 Sep 2024 00:22:19 +0900 Subject: [PATCH 271/371] =?UTF-8?q?feat:=20information=20detail=20?= =?UTF-8?q?=EC=A1=B0=ED=9A=8C=EC=8B=9C=20category=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../solitour/information/service/InformationService.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/main/java/solitour_backend/solitour/information/service/InformationService.java b/src/main/java/solitour_backend/solitour/information/service/InformationService.java index 67317445..586e50be 100644 --- a/src/main/java/solitour_backend/solitour/information/service/InformationService.java +++ b/src/main/java/solitour_backend/solitour/information/service/InformationService.java @@ -19,6 +19,8 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import solitour_backend.solitour.book_mark_information.entity.BookMarkInformationRepository; +import solitour_backend.solitour.category.dto.mapper.CategoryMapper; +import solitour_backend.solitour.category.dto.response.CategoryResponse; import solitour_backend.solitour.category.entity.Category; import solitour_backend.solitour.category.exception.CategoryNotExistsException; import solitour_backend.solitour.category.repository.CategoryRepository; @@ -94,6 +96,7 @@ public class InformationService { private final BookMarkInformationRepository bookMarkInformationRepository; private final UserImageRepository userImageRepository; private final ImageRepository imageRepository; + private final CategoryMapper categoryMapper; @Transactional @@ -184,6 +187,7 @@ public InformationDetailResponse getDetailInformation(Long userId, Long informat } PlaceResponse placeResponse = placeMapper.mapToPlaceResponse(information.getPlace()); ZoneCategoryResponse zoneCategoryResponse = zoneCategoryMapper.mapToZoneCategoryResponse(information.getZoneCategory()); + CategoryResponse categoryResponse = categoryMapper.mapToCategoryResponse(information.getCategory()); List images = imageRepository.findAllByInformationId(information.getId()); @@ -215,6 +219,7 @@ public InformationDetailResponse getDetailInformation(Long userId, Long informat tagResponses, placeResponse, zoneCategoryResponse, + categoryResponse, imageResponseList, likeCount, userImageUrl, @@ -445,8 +450,7 @@ public Page getPageInformation(Pageable pageable, Long } } - return informationRepository.getInformationPageFilterAndOrder(pageable, informationPageRequest, userId, - parentCategoryId); + return informationRepository.getInformationPageFilterAndOrder(pageable, informationPageRequest, userId, parentCategoryId); } public List getRankInformation() { From 9d643712d8626f018453d8f68fb2c31e9b3d13c7 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Thu, 12 Sep 2024 00:53:11 +0900 Subject: [PATCH 272/371] =?UTF-8?q?feat:=20gathering=20detail=20response?= =?UTF-8?q?=20userImage=20=ED=95=84=EB=93=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../gathering/dto/response/GatheringDetailResponse.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/solitour_backend/solitour/gathering/dto/response/GatheringDetailResponse.java b/src/main/java/solitour_backend/solitour/gathering/dto/response/GatheringDetailResponse.java index fe3bf485..6aaeb5fc 100644 --- a/src/main/java/solitour_backend/solitour/gathering/dto/response/GatheringDetailResponse.java +++ b/src/main/java/solitour_backend/solitour/gathering/dto/response/GatheringDetailResponse.java @@ -46,6 +46,8 @@ public class GatheringDetailResponse { private String openChattingUrl; + private String userImage; + private List gatheringApplicantsResponses; private List gatheringRecommend; From 77aa25e8084e06785e405273fb3afb5948aaf310 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Thu, 12 Sep 2024 00:53:29 +0900 Subject: [PATCH 273/371] =?UTF-8?q?feat:=20gathering=20detail=20service=20?= =?UTF-8?q?userImage=20=ED=95=84=EB=93=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../solitour/gathering/service/GatheringService.java | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/main/java/solitour_backend/solitour/gathering/service/GatheringService.java b/src/main/java/solitour_backend/solitour/gathering/service/GatheringService.java index 7a60b8fb..b0fb7fb9 100644 --- a/src/main/java/solitour_backend/solitour/gathering/service/GatheringService.java +++ b/src/main/java/solitour_backend/solitour/gathering/service/GatheringService.java @@ -61,6 +61,8 @@ import solitour_backend.solitour.user.entity.User; import solitour_backend.solitour.user.exception.UserNotExistsException; import solitour_backend.solitour.user.repository.UserRepository; +import solitour_backend.solitour.user_image.entity.UserImage; +import solitour_backend.solitour.user_image.entity.UserImageRepository; import solitour_backend.solitour.zone_category.dto.mapper.ZoneCategoryMapper; import solitour_backend.solitour.zone_category.dto.response.ZoneCategoryResponse; import solitour_backend.solitour.zone_category.entity.ZoneCategory; @@ -88,6 +90,7 @@ public class GatheringService { private final GatheringApplicantsRepository gatheringApplicantsRepository; private final GatheringApplicantsMapper gatheringApplicantsMapper; private final GatheringCategoryMapper gatheringCategoryMapper; + private final UserImageRepository userImageRepository; public GatheringDetailResponse getGatheringDetail(Long userId, Long gatheringId, HttpServletRequest request, HttpServletResponse response) { @@ -125,7 +128,13 @@ public GatheringDetailResponse getGatheringDetail(Long userId, Long gatheringId, List gatheringApplicantsResponses = null; -// boolean isApplicants = gatheringApplicantsRepository.existsByGatheringIdAndUserId(gathering.getId(), userId); + User user = gathering.getUser(); + + String userImageUrl = userImageRepository.findById(user.getUserImage().getId()) + .map(UserImage::getAddress) + .orElseGet( + () -> userRepository.getProfileUrl(user.getSex()) + ); GatheringStatus gatheringStatus = null; GatheringApplicants gatheringApplicants = gatheringApplicantsRepository.findByGatheringIdAndUserId(gathering.getId(), userId).orElse(null); @@ -171,6 +180,7 @@ public GatheringDetailResponse getGatheringDetail(Long userId, Long gatheringId, nowPersonCount, isLike, gathering.getOpenChattingUrl(), + userImageUrl, gatheringApplicantsResponses, gatheringRecommend, gatheringStatus From e0772e3e8f993c92b75102581d7830bb13fa0b05 Mon Sep 17 00:00:00 2001 From: Donghun Won Date: Fri, 13 Sep 2024 14:37:29 +0900 Subject: [PATCH 274/371] =?UTF-8?q?Feat(#150)=20:=20=ED=9A=8C=EC=9B=90=20?= =?UTF-8?q?=ED=83=88=ED=87=B4=20=EB=B0=A9=EB=B2=95=20=EB=B3=80=EA=B2=BD(?= =?UTF-8?q?=EC=B9=B4=EC=B9=B4=EC=98=A4)=20(#175)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Refactor: 최근 로그인 시간 기록, 카카오 로그인 닉네임 랜덤하게 설정 * Feat : 회원 탈퇴 유저 이미지 디폴트 이미지로 변경 유저 정보 null로 변경 s3에 저장된 유저 이미지 삭제 * Refactor : 회원 탈퇴 방법 변경 kakao 로 부터 받은 refresh token을 저장해서 access token 재발급하여 회원 탈퇴 요청 하는 방법으로 변경 --- .../auth/controller/OauthController.java | 45 +++++++++++++ .../solitour/auth/entity/Token.java | 9 ++- .../solitour/auth/service/OauthService.java | 65 +++++++++++++++++-- .../solitour/auth/service/TokenService.java | 21 ++++-- .../auth/support/google/GoogleConnector.java | 20 +++++- .../auth/support/google/GoogleProvider.java | 3 + .../auth/support/kakao/KakaoConnector.java | 40 ++++++++---- .../auth/support/kakao/KakaoProvider.java | 3 + .../kakao/dto/KakaoTokenAndUserResponse.java | 17 +++++ .../support/kakao/dto/KakaoTokenResponse.java | 1 + .../user/controller/UserController.java | 33 ---------- .../solitour/user/service/UserService.java | 37 ----------- 12 files changed, 198 insertions(+), 96 deletions(-) create mode 100644 src/main/java/solitour_backend/solitour/auth/support/kakao/dto/KakaoTokenAndUserResponse.java diff --git a/src/main/java/solitour_backend/solitour/auth/controller/OauthController.java b/src/main/java/solitour_backend/solitour/auth/controller/OauthController.java index a55d1119..6428b2dd 100644 --- a/src/main/java/solitour_backend/solitour/auth/controller/OauthController.java +++ b/src/main/java/solitour_backend/solitour/auth/controller/OauthController.java @@ -4,18 +4,26 @@ import jakarta.servlet.http.Cookie; import jakarta.servlet.http.HttpServletResponse; import lombok.RequiredArgsConstructor; +import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; +import solitour_backend.solitour.auth.config.Authenticated; import solitour_backend.solitour.auth.config.AuthenticationPrincipal; import solitour_backend.solitour.auth.config.AuthenticationRefreshPrincipal; +import solitour_backend.solitour.auth.entity.Token; +import solitour_backend.solitour.auth.entity.TokenRepository; +import solitour_backend.solitour.auth.exception.TokenNotExistsException; import solitour_backend.solitour.auth.service.OauthService; import solitour_backend.solitour.auth.service.dto.response.AccessTokenResponse; import solitour_backend.solitour.auth.service.dto.response.LoginResponse; import solitour_backend.solitour.auth.service.dto.response.OauthLinkResponse; +import solitour_backend.solitour.auth.support.google.GoogleConnector; +import solitour_backend.solitour.auth.support.kakao.KakaoConnector; @RequiredArgsConstructor @@ -24,6 +32,9 @@ public class OauthController { private final OauthService oauthService; + private final KakaoConnector kakaoConnector; + private final GoogleConnector googleConnector; + private final TokenRepository tokenRepository; @GetMapping(value = "/login", params = {"type", "redirectUrl"}) public ResponseEntity access(@RequestParam String type, @RequestParam String redirectUrl) { @@ -64,8 +75,42 @@ public ResponseEntity reissueAccessToken(HttpServletResponse response, return ResponseEntity.ok().build(); } + @Authenticated + @DeleteMapping() + public ResponseEntity deleteUser(HttpServletResponse response, @AuthenticationPrincipal Long id, @RequestParam String type) { + Token token = tokenRepository.findByUserId(id) + .orElseThrow(() -> new TokenNotExistsException("토큰이 존재하지 않습니다")); + String oauthRefreshToken = getOauthAccessToken(type, token.getOauthToken()); + + try { + oauthService.revokeToken(type, oauthRefreshToken); + + oauthService.logout(response, id); + oauthService.deleteUser(id); + + return ResponseEntity.ok("User deleted successfully"); + } catch (Exception e) { + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("An error occurred"); + } + } + private String setCookieHeader(Cookie cookie) { return String.format("%s=%s; Path=%s; Max-Age=%d;Secure; HttpOnly; SameSite=Lax", cookie.getName(), cookie.getValue(), cookie.getPath(), cookie.getMaxAge()); } + + private String getOauthAccessToken(String type, String refreshToken) { + String token = ""; + switch (type) { + case "kakao" -> { + token = kakaoConnector.refreshToken(refreshToken); + } + case "google" -> { + token = googleConnector.refreshToken(refreshToken); + } + default -> throw new RuntimeException("Unsupported oauth type"); + } + return token; + } + } diff --git a/src/main/java/solitour_backend/solitour/auth/entity/Token.java b/src/main/java/solitour_backend/solitour/auth/entity/Token.java index c7b1b118..096b17c7 100644 --- a/src/main/java/solitour_backend/solitour/auth/entity/Token.java +++ b/src/main/java/solitour_backend/solitour/auth/entity/Token.java @@ -9,6 +9,8 @@ import jakarta.persistence.JoinColumn; import jakarta.persistence.OneToOne; import jakarta.persistence.Table; +import lombok.AllArgsConstructor; +import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; import solitour_backend.solitour.user.entity.User; @@ -16,6 +18,8 @@ @Getter @NoArgsConstructor() @Entity +@Builder +@AllArgsConstructor @Table(name = "token") public class Token { @@ -28,9 +32,12 @@ public class Token { @JoinColumn(name = "user_id") private User user; - @Column(nullable = false) + @Column(nullable = false,name = "refresh_token") private String refreshToken; + @Column(nullable = false,name = "oauth_token") + private String oauthToken; + public Token(User user, String refreshToken) { this.user = user; this.refreshToken = refreshToken; diff --git a/src/main/java/solitour_backend/solitour/auth/service/OauthService.java b/src/main/java/solitour_backend/solitour/auth/service/OauthService.java index 35737182..ca47091e 100644 --- a/src/main/java/solitour_backend/solitour/auth/service/OauthService.java +++ b/src/main/java/solitour_backend/solitour/auth/service/OauthService.java @@ -12,6 +12,8 @@ import org.springframework.http.HttpStatusCode; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import solitour_backend.solitour.auth.entity.Token; +import solitour_backend.solitour.auth.entity.TokenRepository; import solitour_backend.solitour.auth.service.dto.response.AccessTokenResponse; import solitour_backend.solitour.auth.service.dto.response.LoginResponse; import solitour_backend.solitour.auth.service.dto.response.OauthLinkResponse; @@ -22,11 +24,15 @@ import solitour_backend.solitour.auth.support.google.dto.GoogleUserResponse; import solitour_backend.solitour.auth.support.kakao.KakaoConnector; import solitour_backend.solitour.auth.support.kakao.KakaoProvider; +import solitour_backend.solitour.auth.support.kakao.dto.KakaoTokenAndUserResponse; +import solitour_backend.solitour.auth.support.kakao.dto.KakaoTokenResponse; import solitour_backend.solitour.auth.support.kakao.dto.KakaoUserResponse; +import solitour_backend.solitour.image.s3.S3Uploader; import solitour_backend.solitour.user.entity.User; import solitour_backend.solitour.user.repository.UserRepository; import solitour_backend.solitour.user.user_status.UserStatus; import solitour_backend.solitour.user_image.entity.UserImage; +import solitour_backend.solitour.user_image.entity.UserImageRepository; import solitour_backend.solitour.user_image.service.UserImageService; @RequiredArgsConstructor @@ -41,12 +47,16 @@ public class OauthService { private final GoogleConnector googleConnector; private final GoogleProvider googleProvider; private final UserImageService userImageService; + private final TokenRepository tokenRepository; + private final UserImageRepository userImageRepository; + private final S3Uploader s3Uploader; @Value("${user.profile.url.male}") private String USER_PROFILE_MALE; @Value("${user.profile.url.female}") private String USER_PROFILE_FEMALE; + public OauthLinkResponse generateAuthUrl(String type, String redirectUrl) { String oauthLink = getAuthLink(type, redirectUrl); return new OauthLinkResponse(oauthLink); @@ -81,11 +91,17 @@ private Cookie createCookie(String name, String value, int maxAge) { private User checkAndSaveUser(String type, String code, String redirectUrl) { if (Objects.equals(type, "kakao")) { - KakaoUserResponse response = kakaoConnector.requestKakaoUserInfo(code, redirectUrl) - .getBody(); - String id = response.getId().toString(); - return userRepository.findByOauthId(id) - .orElseGet(() -> saveKakaoUser(response)); + KakaoTokenAndUserResponse response = kakaoConnector.requestKakaoUserInfo(code, redirectUrl); + KakaoTokenResponse tokenResponse = response.getKakaoTokenResponse(); + KakaoUserResponse kakaoUserResponse = response.getKakaoUserResponse(); + + String id = kakaoUserResponse.getId().toString(); + User user = userRepository.findByOauthId(id) + .orElseGet(() -> saveKakaoUser(kakaoUserResponse)); + + tokenService.saveToken(tokenResponse, user); + + return user; } if (Objects.equals(type, "google")) { GoogleUserResponse response = googleConnector.requestGoogleUserInfo(code, redirectUrl) @@ -98,6 +114,15 @@ private User checkAndSaveUser(String type, String code, String redirectUrl) { } } + private void saveToken(KakaoTokenResponse tokenResponse, User user) { + Token token = Token.builder() + .user(user) + .oauthToken(tokenResponse.getRefreshToken()) + .build(); + + tokenRepository.save(token); + } + private User saveGoogleUser(GoogleUserResponse response) { String imageUrl = getGoogleUserImage(response); UserImage savedUserImage = userImageService.saveUserImage(imageUrl); @@ -210,4 +235,34 @@ public void revokeToken(String type, String token) throws IOException { } } + @Transactional + public void deleteUser(Long userId) { + User user = userRepository.findByUserId(userId); + UserImage userImage = userImageRepository.findById(user.getUserImage().getId()).orElseThrow(); + changeToDefaultProfile(user, userImage); + user.deleteUser(); + } + + private void changeToDefaultProfile(User user, UserImage userImage) { + String defaultImageUrl = getDefaultProfile(user); + deleteUserProfileFromS3(userImage,defaultImageUrl); + } + + private String getDefaultProfile(User user) { + String sex = user.getSex(); + if(sex.equals("male")){{ + return USER_PROFILE_MALE; + }} else { + return USER_PROFILE_FEMALE; + } + } + + private void deleteUserProfileFromS3(UserImage userImage,String defaultImageUrl) { + String userImageUrl = userImage.getAddress(); + if(userImageUrl.equals(USER_PROFILE_MALE) || userImageUrl.equals(USER_PROFILE_FEMALE)){ + return; + } + s3Uploader.deleteImage(userImageUrl); + userImage.changeToDefaultProfile(defaultImageUrl); + } } diff --git a/src/main/java/solitour_backend/solitour/auth/service/TokenService.java b/src/main/java/solitour_backend/solitour/auth/service/TokenService.java index c359f617..d66d0a71 100644 --- a/src/main/java/solitour_backend/solitour/auth/service/TokenService.java +++ b/src/main/java/solitour_backend/solitour/auth/service/TokenService.java @@ -5,6 +5,8 @@ import org.springframework.transaction.annotation.Transactional; import solitour_backend.solitour.auth.entity.Token; import solitour_backend.solitour.auth.entity.TokenRepository; +import solitour_backend.solitour.auth.exception.TokenNotExistsException; +import solitour_backend.solitour.auth.support.kakao.dto.KakaoTokenResponse; import solitour_backend.solitour.user.entity.User; @RequiredArgsConstructor @@ -16,15 +18,24 @@ public class TokenService { @Transactional public void synchronizeRefreshToken(User user, String refreshToken) { - tokenRepository.findByUserId(user.getId()) - .ifPresentOrElse( - token -> token.updateRefreshToken(refreshToken), - () -> tokenRepository.save(new Token(user, refreshToken)) - ); + Token token = tokenRepository.findByUserId(user.getId()) + .orElseThrow(() -> new TokenNotExistsException("토큰이 존재하지 않습니다")); + + token.updateRefreshToken(refreshToken); } @Transactional public void deleteByMemberId(Long memberId) { tokenRepository.deleteByUserId(memberId); } + + @Transactional + public void saveToken(KakaoTokenResponse tokenResponse, User user) { + Token token = Token.builder() + .user(user) + .oauthToken(tokenResponse.getRefreshToken()) + .build(); + + tokenRepository.save(token); + } } diff --git a/src/main/java/solitour_backend/solitour/auth/support/google/GoogleConnector.java b/src/main/java/solitour_backend/solitour/auth/support/google/GoogleConnector.java index decb3703..58c0da6d 100644 --- a/src/main/java/solitour_backend/solitour/auth/support/google/GoogleConnector.java +++ b/src/main/java/solitour_backend/solitour/auth/support/google/GoogleConnector.java @@ -18,6 +18,7 @@ import org.springframework.web.client.RestTemplate; import solitour_backend.solitour.auth.support.google.dto.GoogleTokenResponse; import solitour_backend.solitour.auth.support.google.dto.GoogleUserResponse; +import solitour_backend.solitour.auth.support.kakao.dto.KakaoTokenResponse; @Getter @RequiredArgsConstructor @@ -61,6 +62,15 @@ public HttpStatusCode requestRevoke(String token) throws IOException { return response.getStatusCode(); } + public String refreshToken(String refreshToken) { + HttpEntity> entity = new HttpEntity<>( + createRefreshBody(refreshToken), createLoginHeaders()); + + return REST_TEMPLATE.postForEntity( + provider.getAccessTokenUrl(), + entity, KakaoTokenResponse.class).getBody().getAccessToken(); + } + private HttpHeaders createLoginHeaders() { HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED); @@ -78,6 +88,15 @@ private MultiValueMap createLoginBody(String code, String redire return body; } + private MultiValueMap createRefreshBody(String refreshToken) { + MultiValueMap body = new LinkedMultiValueMap<>(); + body.add("client_id", provider.getClientId()); + body.add("client_secret", provider.getClientSecret()); + body.add("grant_type", provider.getRefreshGrantType()); + body.add("refresh_token", refreshToken); + return body; + } + private HttpHeaders createRevokeHeaders() { HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED); @@ -96,5 +115,4 @@ private String extractAccessToken(ResponseEntity responseEn return response.getAccessToken(); } - } diff --git a/src/main/java/solitour_backend/solitour/auth/support/google/GoogleProvider.java b/src/main/java/solitour_backend/solitour/auth/support/google/GoogleProvider.java index c11140db..be927c3b 100644 --- a/src/main/java/solitour_backend/solitour/auth/support/google/GoogleProvider.java +++ b/src/main/java/solitour_backend/solitour/auth/support/google/GoogleProvider.java @@ -18,6 +18,7 @@ public class GoogleProvider { private final String userInfoUrl; private final String revokeUrl; private final String grantType; + private final String refreshGrantType; private final String scope; public GoogleProvider(@Value("${oauth2.google.client.id}") String clientId, @@ -27,6 +28,7 @@ public GoogleProvider(@Value("${oauth2.google.client.id}") String clientId, @Value("${oauth2.google.url.userinfo}") String userInfoUrl, @Value("${oauth2.google.url.revoke}") String revokeUrl, @Value("${oauth2.google.grant-type}") String grantType, + @Value("${oauth2.google.refresh-grant-type}") String refreshGrantType, @Value("${oauth2.google.scope}") String scope) { this.clientId = clientId; this.clientSecret = clientSecret; @@ -35,6 +37,7 @@ public GoogleProvider(@Value("${oauth2.google.client.id}") String clientId, this.userInfoUrl = userInfoUrl; this.revokeUrl = revokeUrl; this.grantType = grantType; + this.refreshGrantType = refreshGrantType; this.scope = scope; } diff --git a/src/main/java/solitour_backend/solitour/auth/support/kakao/KakaoConnector.java b/src/main/java/solitour_backend/solitour/auth/support/kakao/KakaoConnector.java index a690fcc3..3da5d8b3 100644 --- a/src/main/java/solitour_backend/solitour/auth/support/kakao/KakaoConnector.java +++ b/src/main/java/solitour_backend/solitour/auth/support/kakao/KakaoConnector.java @@ -16,6 +16,7 @@ import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; import org.springframework.web.client.RestTemplate; +import solitour_backend.solitour.auth.support.kakao.dto.KakaoTokenAndUserResponse; import solitour_backend.solitour.auth.support.kakao.dto.KakaoTokenResponse; import solitour_backend.solitour.auth.support.kakao.dto.KakaoUserResponse; @@ -29,26 +30,36 @@ public class KakaoConnector { private final KakaoProvider provider; - public ResponseEntity requestKakaoUserInfo(String code, String redirectUrl) { - String kakaoToken = requestAccessToken(code, redirectUrl); + public KakaoTokenAndUserResponse requestKakaoUserInfo(String code, String redirectUrl) { + KakaoTokenResponse kakaoToken = requestAccessToken(code, redirectUrl); HttpHeaders headers = new HttpHeaders(); - headers.set("Authorization", String.join(" ", BEARER_TYPE, kakaoToken)); + headers.set("Authorization", String.join(" ", BEARER_TYPE, kakaoToken.getAccessToken())); HttpEntity entity = new HttpEntity<>(headers); - return REST_TEMPLATE.exchange(provider.getUserInfoUrl(), HttpMethod.GET, entity, + ResponseEntity responseEntity = REST_TEMPLATE.exchange(provider.getUserInfoUrl(), HttpMethod.GET, entity, KakaoUserResponse.class); + + return new KakaoTokenAndUserResponse(kakaoToken,responseEntity.getBody()); + } - public String requestAccessToken(String code, String redirectUrl) { + public KakaoTokenResponse requestAccessToken(String code, String redirectUrl) { HttpEntity> entity = new HttpEntity<>( createBody(code, redirectUrl), createHeaders()); - ResponseEntity response = REST_TEMPLATE.postForEntity( + return REST_TEMPLATE.postForEntity( provider.getAccessTokenUrl(), - entity, KakaoTokenResponse.class); + entity, KakaoTokenResponse.class).getBody(); + } - return extractAccessToken(response); + public String refreshToken(String refreshToken) { + HttpEntity> entity = new HttpEntity<>( + createRefreshBody(refreshToken), createHeaders()); + + return REST_TEMPLATE.postForEntity( + provider.getAccessTokenUrl(), + entity, KakaoTokenResponse.class).getBody().getAccessToken(); } private HttpHeaders createHeaders() { @@ -68,11 +79,13 @@ private MultiValueMap createBody(String code, String redirectUrl return body; } - private String extractAccessToken(ResponseEntity responseEntity) { - KakaoTokenResponse response = Optional.ofNullable(responseEntity.getBody()) - .orElseThrow(() -> new RuntimeException("카카오 토큰을 가져오는데 실패했습니다.")); - - return response.getAccessToken(); + private MultiValueMap createRefreshBody(String refreshToken) { + MultiValueMap body = new LinkedMultiValueMap<>(); + body.add("client_id", provider.getClientId()); + body.add("client_secret", provider.getClientSecret()); + body.add("grant_type", provider.getRefreshGrantType()); + body.add("refresh_token", refreshToken); + return body; } public HttpStatusCode requestRevoke(String token) throws IOException { @@ -89,5 +102,4 @@ private HttpHeaders createRevokeHeaders(String token) { headers.set("Authorization", String.join(" ", BEARER_TYPE, token)); return headers; } - } diff --git a/src/main/java/solitour_backend/solitour/auth/support/kakao/KakaoProvider.java b/src/main/java/solitour_backend/solitour/auth/support/kakao/KakaoProvider.java index bfbb1ad8..cabf5158 100644 --- a/src/main/java/solitour_backend/solitour/auth/support/kakao/KakaoProvider.java +++ b/src/main/java/solitour_backend/solitour/auth/support/kakao/KakaoProvider.java @@ -17,6 +17,7 @@ public class KakaoProvider { private final String accessTokenUrl; private final String userInfoUrl; private final String grantType; + private final String refreshGrantType; private final String revokeUrl; private final String scope; @@ -27,6 +28,7 @@ public KakaoProvider(@Value("${oauth2.kakao.client.id}") String clientId, @Value("${oauth2.kakao.url.token}") String accessTokenUrl, @Value("${oauth2.kakao.url.userinfo}") String userInfoUrl, @Value("${oauth2.kakao.grant-type}") String grantType, + @Value("${oauth2.kakao.refresh-grant-type}") String refreshGrantType, @Value("${oauth2.kakao.url.revoke}") String revokeUrl, @Value("${oauth2.kakao.scope}") String scope) { this.clientId = clientId; @@ -35,6 +37,7 @@ public KakaoProvider(@Value("${oauth2.kakao.client.id}") String clientId, this.accessTokenUrl = accessTokenUrl; this.userInfoUrl = userInfoUrl; this.grantType = grantType; + this.refreshGrantType = refreshGrantType; this.revokeUrl = revokeUrl; this.scope = scope; } diff --git a/src/main/java/solitour_backend/solitour/auth/support/kakao/dto/KakaoTokenAndUserResponse.java b/src/main/java/solitour_backend/solitour/auth/support/kakao/dto/KakaoTokenAndUserResponse.java new file mode 100644 index 00000000..0bfa374f --- /dev/null +++ b/src/main/java/solitour_backend/solitour/auth/support/kakao/dto/KakaoTokenAndUserResponse.java @@ -0,0 +1,17 @@ +package solitour_backend.solitour.auth.support.kakao.dto; + +import com.fasterxml.jackson.databind.PropertyNamingStrategies; +import com.fasterxml.jackson.databind.annotation.JsonNaming; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class) +@Getter +@NoArgsConstructor +@AllArgsConstructor +public class KakaoTokenAndUserResponse { + + private KakaoTokenResponse kakaoTokenResponse; + private KakaoUserResponse kakaoUserResponse; +} diff --git a/src/main/java/solitour_backend/solitour/auth/support/kakao/dto/KakaoTokenResponse.java b/src/main/java/solitour_backend/solitour/auth/support/kakao/dto/KakaoTokenResponse.java index 7bc3e5e0..bb3895a2 100644 --- a/src/main/java/solitour_backend/solitour/auth/support/kakao/dto/KakaoTokenResponse.java +++ b/src/main/java/solitour_backend/solitour/auth/support/kakao/dto/KakaoTokenResponse.java @@ -13,4 +13,5 @@ public class KakaoTokenResponse { private String accessToken; + private String refreshToken; } diff --git a/src/main/java/solitour_backend/solitour/user/controller/UserController.java b/src/main/java/solitour_backend/solitour/user/controller/UserController.java index fc4fd033..73796131 100644 --- a/src/main/java/solitour_backend/solitour/user/controller/UserController.java +++ b/src/main/java/solitour_backend/solitour/user/controller/UserController.java @@ -88,24 +88,6 @@ public ResponseEntity updateUserProfile(@AuthenticationPrincipal Long user return ResponseEntity.ok().build(); } - @DeleteMapping() - public ResponseEntity deleteUser(HttpServletResponse response, @AuthenticationPrincipal Long id, - @RequestParam String type, - @RequestParam String code, @RequestParam String redirectUrl) { - String token = getOauthAccessToken(type, code, redirectUrl); - - try { - oauthservice.revokeToken(type, token); - - oauthservice.logout(response, id); - userService.deleteUser(id); - - return ResponseEntity.ok("User deleted successfully"); - } catch (Exception e) { - return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("An error occurred"); - } - } - @GetMapping("/mypage/information/owner") public ResponseEntity> retrieveInformationOwner( @RequestParam(defaultValue = "0") int page, @@ -161,19 +143,4 @@ public ResponseEntity> retrieveGatheringApplica return ResponseEntity.ok(response); } - - private String getOauthAccessToken(String type, String code, String redirectUrl) { - String token = ""; - switch (type) { - case "kakao" -> { - token = kakaoConnector.requestAccessToken(code, redirectUrl); - } - case "google" -> { - token = googleConnector.requestAccessToken(code, redirectUrl); - } - default -> throw new RuntimeException("Unsupported oauth type"); - } - return token; - } - } diff --git a/src/main/java/solitour_backend/solitour/user/service/UserService.java b/src/main/java/solitour_backend/solitour/user/service/UserService.java index dfa2073b..a8dc03ad 100644 --- a/src/main/java/solitour_backend/solitour/user/service/UserService.java +++ b/src/main/java/solitour_backend/solitour/user/service/UserService.java @@ -27,12 +27,6 @@ public class UserService { private final UserRepository userRepository; private final UserImageService userImageService; - private final UserImageRepository userImageRepository; - private final S3Uploader s3Uploader; - @Value("${user.profile.url.female}") - private String femaleProfileUrl; - @Value("${user.profile.url.male}") - private String maleProfileUrl; public UserInfoResponse retrieveUserInfo(Long userId) { User user = userRepository.findByUserId(userId); @@ -55,14 +49,6 @@ public void updateAgeAndSex(Long userId, String age, String sex) { user.updateAgeAndSex(age, sex); } - @Transactional - public void deleteUser(Long userId) { - User user = userRepository.findByUserId(userId); - UserImage userImage = userImageRepository.findById(user.getUserImage().getId()).orElseThrow(); - changeToDefaultProfile(user, userImage); - user.deleteUser(); - } - public Page retrieveInformationOwner(Pageable pageable, Long userId) { return userRepository.retrieveInformationOwner(pageable, userId); } @@ -89,27 +75,4 @@ public Page retrieveGatheringBookmark(Pageable pageable, public Page retrieveGatheringApplicant(Pageable pageable, Long userId) { return userRepository.retrieveGatheringApplicant(pageable, userId); } - - private void changeToDefaultProfile(User user, UserImage userImage) { - String defaultImageUrl = getDefaultProfile(user); - deleteUserProfileFromS3(userImage,defaultImageUrl); - } - - private String getDefaultProfile(User user) { - String sex = user.getSex(); - if(sex.equals("male")){{ - return maleProfileUrl; - }} else { - return femaleProfileUrl; - } - } - - private void deleteUserProfileFromS3(UserImage userImage,String defaultImageUrl) { - String userImageUrl = userImage.getAddress(); - if(userImageUrl.equals(femaleProfileUrl) || userImageUrl.equals(maleProfileUrl)){ - return; - } - s3Uploader.deleteImage(userImageUrl); - userImage.changeToDefaultProfile(defaultImageUrl); - } } From 3f96d82b3f76ba95951ce41573f5610a2f458198 Mon Sep 17 00:00:00 2001 From: Donghun Won Date: Fri, 13 Sep 2024 14:43:29 +0900 Subject: [PATCH 275/371] =?UTF-8?q?Fix=20:=20=EC=A0=95=EB=B3=B4,=20?= =?UTF-8?q?=EB=AA=A8=EC=9E=84=20=EC=A1=B0=ED=9A=8C=EC=8B=9C=20=EB=A1=9C?= =?UTF-8?q?=EA=B7=B8=EC=9D=B8=20=EC=9C=A0=EC=A0=80=20=ED=86=A0=ED=81=B0=20?= =?UTF-8?q?=EA=B2=80=EC=A6=9D=20=EB=A1=9C=EC=A7=81=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../solitour/gathering/controller/GatheringController.java | 5 +++++ .../information/controller/InformationController.java | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/src/main/java/solitour_backend/solitour/gathering/controller/GatheringController.java b/src/main/java/solitour_backend/solitour/gathering/controller/GatheringController.java index 7648ea10..73ffeee6 100644 --- a/src/main/java/solitour_backend/solitour/gathering/controller/GatheringController.java +++ b/src/main/java/solitour_backend/solitour/gathering/controller/GatheringController.java @@ -29,6 +29,7 @@ import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import solitour_backend.solitour.auth.config.AuthenticationPrincipal; +import solitour_backend.solitour.auth.exception.TokenNotValidException; import solitour_backend.solitour.auth.support.CookieExtractor; import solitour_backend.solitour.auth.support.JwtTokenProvider; import solitour_backend.solitour.error.Utils; @@ -210,6 +211,10 @@ private Long findUser(HttpServletRequest request) { return (long) 0; } + if (jwtTokenProvider.validateTokenNotUsable(token)) { + throw new TokenNotValidException("토큰이 유효하지 않습니다."); + } + return jwtTokenProvider.getPayload(token); } diff --git a/src/main/java/solitour_backend/solitour/information/controller/InformationController.java b/src/main/java/solitour_backend/solitour/information/controller/InformationController.java index 39d65219..e188c9e5 100644 --- a/src/main/java/solitour_backend/solitour/information/controller/InformationController.java +++ b/src/main/java/solitour_backend/solitour/information/controller/InformationController.java @@ -19,6 +19,7 @@ import org.springframework.web.bind.annotation.*; import solitour_backend.solitour.auth.config.Authenticated; import solitour_backend.solitour.auth.config.AuthenticationPrincipal; +import solitour_backend.solitour.auth.exception.TokenNotValidException; import solitour_backend.solitour.auth.support.CookieExtractor; import solitour_backend.solitour.auth.support.JwtTokenProvider; import solitour_backend.solitour.error.Utils; @@ -163,6 +164,10 @@ private Long findUser(HttpServletRequest request) { return (long) 0; } + if (jwtTokenProvider.validateTokenNotUsable(token)) { + throw new TokenNotValidException("토큰이 유효하지 않습니다."); + } + return jwtTokenProvider.getPayload(token); } From eb1cba0adff71773d67022b7da7f5caadb834c60 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Fri, 13 Sep 2024 15:09:46 +0900 Subject: [PATCH 276/371] fix: and -> or --- .../gathering/repository/GatheringRepositoryImpl.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryImpl.java b/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryImpl.java index b4e2c3b2..d7151223 100644 --- a/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryImpl.java +++ b/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryImpl.java @@ -298,11 +298,10 @@ private BooleanBuilder makeWhereSQL(GatheringPageRequest gatheringPageRequest) { int userMinBirthYear = currentYear - gatheringPageRequest.getEndAge() + 1; int userMaxBirthYear = currentYear - gatheringPageRequest.getStartAge() + 1; - whereClause.and(gathering.startAge.goe(userMaxBirthYear)).and(gathering.endAge.loe(userMinBirthYear)); + whereClause.and(gathering.startAge.goe(userMaxBirthYear)).or(gathering.endAge.loe(userMinBirthYear)); } - if (Objects.nonNull(gatheringPageRequest.getStartDate()) && Objects.nonNull( - gatheringPageRequest.getEndDate())) { + if (Objects.nonNull(gatheringPageRequest.getStartDate()) && Objects.nonNull(gatheringPageRequest.getEndDate())) { whereClause.and(gathering.scheduleStartDate.goe(gatheringPageRequest.getStartDate().atStartOfDay())) .and(gathering.scheduleEndDate.loe(gatheringPageRequest.getEndDate().atTime(LocalTime.MAX))); } From 90c69d0ddffb68fed5a06c783cfc7c0f4d1153de Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Fri, 13 Sep 2024 15:10:48 +0900 Subject: [PATCH 277/371] =?UTF-8?q?fix:=20gathering=20=EC=A1=B0=ED=9A=8C?= =?UTF-8?q?=EC=88=98=20=EA=B8=B0=EB=8A=A5=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../gathering/service/GatheringService.java | 41 ++++++++++++------- 1 file changed, 26 insertions(+), 15 deletions(-) diff --git a/src/main/java/solitour_backend/solitour/gathering/service/GatheringService.java b/src/main/java/solitour_backend/solitour/gathering/service/GatheringService.java index b0fb7fb9..40c776de 100644 --- a/src/main/java/solitour_backend/solitour/gathering/service/GatheringService.java +++ b/src/main/java/solitour_backend/solitour/gathering/service/GatheringService.java @@ -3,12 +3,9 @@ import static solitour_backend.solitour.gathering.repository.GatheringRepositoryCustom.LIKE_COUNT_SORT; import static solitour_backend.solitour.gathering.repository.GatheringRepositoryCustom.VIEW_COUNT_SORT; -import java.time.LocalDateTime; +import java.time.LocalDate; import java.time.format.DateTimeFormatter; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.Objects; +import java.util.*; import jakarta.servlet.http.Cookie; import jakarta.servlet.http.HttpServletRequest; @@ -63,6 +60,7 @@ import solitour_backend.solitour.user.repository.UserRepository; import solitour_backend.solitour.user_image.entity.UserImage; import solitour_backend.solitour.user_image.entity.UserImageRepository; +import solitour_backend.solitour.util.HmacUtils; import solitour_backend.solitour.zone_category.dto.mapper.ZoneCategoryMapper; import solitour_backend.solitour.zone_category.dto.response.ZoneCategoryResponse; import solitour_backend.solitour.zone_category.entity.ZoneCategory; @@ -93,6 +91,7 @@ public class GatheringService { private final UserImageRepository userImageRepository; + @Transactional public GatheringDetailResponse getGatheringDetail(Long userId, Long gatheringId, HttpServletRequest request, HttpServletResponse response) { Gathering gathering = gatheringRepository.findById(gatheringId) .orElseThrow( @@ -156,7 +155,12 @@ public GatheringDetailResponse getGatheringDetail(Long userId, Long gatheringId, List gatheringRecommend = gatheringRepository.getGatheringRecommend(gathering.getId(), gathering.getGatheringCategory().getId(), userId); - updateViewCount(gathering, request, response, userId); + try { + updateViewCount(gathering, request, response, userId); + } catch (Exception e) { + throw new IllegalArgumentException(); + } + return new GatheringDetailResponse( gathering.getTitle(), @@ -467,7 +471,7 @@ private void validateGatheringPageRequest(GatheringPageRequest gatheringPageRequ } } - public void updateViewCount(Gathering gathering, HttpServletRequest request, HttpServletResponse response, Long userId) { + public void updateViewCount(Gathering gathering, HttpServletRequest request, HttpServletResponse response, Long userId) throws Exception { String cookieName = "viewed_gathering_" + userId + "_" + gathering.getId(); Cookie[] cookies = request.getCookies(); Cookie postCookie = null; @@ -479,19 +483,25 @@ public void updateViewCount(Gathering gathering, HttpServletRequest request, Htt .orElse(null); } - LocalDateTime now = LocalDateTime.now(); - DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-ddHH:mm:ss"); + LocalDate now = LocalDate.now(); + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); + String cookieData = now.format(formatter); if (Objects.nonNull(postCookie)) { - LocalDateTime lastViewedAt = LocalDateTime.parse(postCookie.getValue(), formatter); - if (lastViewedAt.isBefore(now.minusDays(1))) { - incrementGatheringViewCount(gathering); - postCookie.setValue(now.format(formatter)); - response.addCookie(postCookie); + String[] parts = postCookie.getValue().split("\\|"); + if (parts.length == 2 && HmacUtils.verifyHmac(parts[0], parts[1])) { + LocalDate lastViewedAt = LocalDate.parse(parts[0], formatter); + if (lastViewedAt.isBefore(now.minusDays(1))) { + incrementGatheringViewCount(gathering); + String newHmac = HmacUtils.generateHmac(cookieData); + postCookie.setValue(cookieData + "|" + newHmac); + response.addCookie(postCookie); + } } } else { incrementGatheringViewCount(gathering); - Cookie newCookie = new Cookie(cookieName, now.format(formatter)); + String hmac = HmacUtils.generateHmac(cookieData); + Cookie newCookie = new Cookie(cookieName, cookieData + "|" + hmac); newCookie.setMaxAge(60 * 60 * 24 * 365); response.addCookie(newCookie); } @@ -501,4 +511,5 @@ private void incrementGatheringViewCount(Gathering gathering) { gathering.upViewCount(); } + } \ No newline at end of file From a63c8ea8a4872fabdb181a4f4c99d5919d2d3071 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Fri, 13 Sep 2024 15:11:14 +0900 Subject: [PATCH 278/371] =?UTF-8?q?fix:=20information=20=EC=A1=B0=ED=9A=8C?= =?UTF-8?q?=EC=88=98=20=EA=B8=B0=EB=8A=A5=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/InformationService.java | 35 ++++++++++++------- 1 file changed, 23 insertions(+), 12 deletions(-) diff --git a/src/main/java/solitour_backend/solitour/information/service/InformationService.java b/src/main/java/solitour_backend/solitour/information/service/InformationService.java index 586e50be..b234f725 100644 --- a/src/main/java/solitour_backend/solitour/information/service/InformationService.java +++ b/src/main/java/solitour_backend/solitour/information/service/InformationService.java @@ -3,7 +3,7 @@ import static solitour_backend.solitour.information.repository.InformationRepositoryCustom.LIKE_COUNT_SORT; import static solitour_backend.solitour.information.repository.InformationRepositoryCustom.VIEW_COUNT_SORT; -import java.time.LocalDateTime; +import java.time.LocalDate; import java.time.format.DateTimeFormatter; import java.util.ArrayList; import java.util.Arrays; @@ -67,6 +67,7 @@ import solitour_backend.solitour.user.repository.UserRepository; import solitour_backend.solitour.user_image.entity.UserImage; import solitour_backend.solitour.user_image.entity.UserImageRepository; +import solitour_backend.solitour.util.HmacUtils; import solitour_backend.solitour.zone_category.dto.mapper.ZoneCategoryMapper; import solitour_backend.solitour.zone_category.dto.response.ZoneCategoryResponse; import solitour_backend.solitour.zone_category.entity.ZoneCategory; @@ -167,7 +168,7 @@ public InformationResponse registerInformation(Long userId, InformationCreateReq return informationMapper.mapToInformationResponse(saveInformation); } - + @Transactional public InformationDetailResponse getDetailInformation(Long userId, Long informationId, HttpServletRequest request, HttpServletResponse response) { Information information = informationRepository.findById(informationId) .orElseThrow( @@ -206,7 +207,11 @@ public InformationDetailResponse getDetailInformation(Long userId, Long informat .orElseGet( () -> userRepository.getProfileUrl(user.getSex())); - updateViewCount(information, request, response, userId); + try { + updateViewCount(information, request, response, userId); + } catch (Exception e) { + throw new IllegalArgumentException(); + } return new InformationDetailResponse( information.getTitle(), @@ -468,7 +473,7 @@ public Page getPageInformationByTag(Pageable pageable, decodedTag); } - public void updateViewCount(Information information, HttpServletRequest request, HttpServletResponse response, Long userId) { + public void updateViewCount(Information information, HttpServletRequest request, HttpServletResponse response, Long userId) throws Exception { String cookieName = "viewed_information_" + userId + "_" + information.getId(); Cookie[] cookies = request.getCookies(); Cookie postCookie = null; @@ -480,19 +485,25 @@ public void updateViewCount(Information information, HttpServletRequest request, .orElse(null); } - LocalDateTime now = LocalDateTime.now(); - DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-ddHH:mm:ss"); + LocalDate now = LocalDate.now(); + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); + String cookieData = now.format(formatter); if (Objects.nonNull(postCookie)) { - LocalDateTime lastViewedAt = LocalDateTime.parse(postCookie.getValue(), formatter); - if (lastViewedAt.isBefore(now.minusDays(1))) { - incrementInformationViewCount(information); - postCookie.setValue(now.format(formatter)); - response.addCookie(postCookie); + String[] parts = postCookie.getValue().split("\\|"); + if (parts.length == 2 && HmacUtils.verifyHmac(parts[0], parts[1])) { + LocalDate lastViewedAt = LocalDate.parse(parts[0], formatter); + if (lastViewedAt.isBefore(now.minusDays(1))) { + incrementInformationViewCount(information); + String newHmac = HmacUtils.generateHmac(cookieData); + postCookie.setValue(cookieData + "|" + newHmac); + response.addCookie(postCookie); + } } } else { incrementInformationViewCount(information); - Cookie newCookie = new Cookie(cookieName, now.format(formatter)); + String hmac = HmacUtils.generateHmac(cookieData); + Cookie newCookie = new Cookie(cookieName, cookieData + "|" + hmac); newCookie.setMaxAge(60 * 60 * 24 * 365); response.addCookie(newCookie); } From 3ebc5b55c0f59522772c9a00387bed4e548a366d Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Fri, 13 Sep 2024 15:11:42 +0900 Subject: [PATCH 279/371] =?UTF-8?q?feat:=20=ED=95=B4=EC=8B=9C=20=ED=95=A8?= =?UTF-8?q?=EC=88=98=20=EC=95=94=ED=98=B8=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../solitour/util/HmacUtils.java | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 src/main/java/solitour_backend/solitour/util/HmacUtils.java diff --git a/src/main/java/solitour_backend/solitour/util/HmacUtils.java b/src/main/java/solitour_backend/solitour/util/HmacUtils.java new file mode 100644 index 00000000..23b8ac95 --- /dev/null +++ b/src/main/java/solitour_backend/solitour/util/HmacUtils.java @@ -0,0 +1,41 @@ +package solitour_backend.solitour.util; + +import jakarta.annotation.PostConstruct; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +import javax.crypto.Mac; +import javax.crypto.spec.SecretKeySpec; +import java.util.Base64; + +@Component +public class HmacUtils { + private HmacUtils() { + } + + @Value("${view.count.cookie.key}") + private String viewCountKeyTemp; + + private static String viewCountKey; + + public static final String HMAC_SHA256 = "HmacSHA256"; + + @PostConstruct + public void init() { + viewCountKey = this.viewCountKeyTemp; + } + + public static String generateHmac(String data) throws Exception { + Mac mac = Mac.getInstance(HMAC_SHA256); + SecretKeySpec secretKeySpec = new SecretKeySpec(viewCountKey.getBytes(), HMAC_SHA256); + mac.init(secretKeySpec); + + byte[] hmacBytes = mac.doFinal(data.getBytes()); + return Base64.getEncoder().encodeToString(hmacBytes); // Base64로 인코딩된 HMAC 값 반환 + } + + public static boolean verifyHmac(String data, String providedHmac) throws Exception { + String generatedHmac = generateHmac(data); + return providedHmac.equals(generatedHmac); // 제공된 HMAC과 생성된 HMAC 비교 + } +} From b0a4ff7e2f00ef5f5bbbd017be28b421ddbcc383 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Fri, 13 Sep 2024 15:12:41 +0900 Subject: [PATCH 280/371] =?UTF-8?q?fix:=20=EC=9D=B4=EB=AF=B8=EC=A7=80=20?= =?UTF-8?q?=EC=82=AD=EC=A0=9C=20=ED=95=A0=EB=95=8C=20=EC=9D=B4=EB=AF=B8?= =?UTF-8?q?=EC=A7=80=20url=20=ED=8C=8C=EC=8B=B1=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/solitour_backend/solitour/image/s3/S3Uploader.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/solitour_backend/solitour/image/s3/S3Uploader.java b/src/main/java/solitour_backend/solitour/image/s3/S3Uploader.java index de6680b8..fe474ff0 100644 --- a/src/main/java/solitour_backend/solitour/image/s3/S3Uploader.java +++ b/src/main/java/solitour_backend/solitour/image/s3/S3Uploader.java @@ -72,7 +72,7 @@ public void markImagePermanent(String imageUrl) { } public void deleteImage(String fileUrl) { - String fileName = extractFileNameFromUrl(fileUrl); + String fileName = extractFileNameFromUrlUseBucketName(fileUrl); amazonS3Client.deleteObject(new DeleteObjectRequest(bucket, fileName)); } From 936ca4f3c739862254fa02c0db634af6173be6b1 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Sun, 15 Sep 2024 04:03:57 +0900 Subject: [PATCH 281/371] =?UTF-8?q?feature:=20=EB=AA=A8=EC=9E=84=20?= =?UTF-8?q?=EC=A1=B0=ED=9A=8C=EC=88=98=20=EA=B8=B0=EB=8A=A5=20=EA=B0=9C?= =?UTF-8?q?=EC=84=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../gathering/service/GatheringService.java | 62 +++++++++++++++---- 1 file changed, 49 insertions(+), 13 deletions(-) diff --git a/src/main/java/solitour_backend/solitour/gathering/service/GatheringService.java b/src/main/java/solitour_backend/solitour/gathering/service/GatheringService.java index 40c776de..98213347 100644 --- a/src/main/java/solitour_backend/solitour/gathering/service/GatheringService.java +++ b/src/main/java/solitour_backend/solitour/gathering/service/GatheringService.java @@ -3,6 +3,9 @@ import static solitour_backend.solitour.gathering.repository.GatheringRepositoryCustom.LIKE_COUNT_SORT; import static solitour_backend.solitour.gathering.repository.GatheringRepositoryCustom.VIEW_COUNT_SORT; +import java.net.URLDecoder; +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; import java.time.LocalDate; import java.time.format.DateTimeFormatter; import java.util.*; @@ -471,8 +474,9 @@ private void validateGatheringPageRequest(GatheringPageRequest gatheringPageRequ } } + public void updateViewCount(Gathering gathering, HttpServletRequest request, HttpServletResponse response, Long userId) throws Exception { - String cookieName = "viewed_gathering_" + userId + "_" + gathering.getId(); + String cookieName = "viewed_gatherings"; Cookie[] cookies = request.getCookies(); Cookie postCookie = null; @@ -485,24 +489,56 @@ public void updateViewCount(Gathering gathering, HttpServletRequest request, Htt LocalDate now = LocalDate.now(); DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); - String cookieData = now.format(formatter); + String cookieData = userId + "_" + gathering.getId() + "_" + now.format(formatter); + + if (Objects.nonNull(postCookie) && postCookie.getValue() != null) { + String[] gatheringDataArray = URLDecoder.decode(postCookie.getValue(), StandardCharsets.UTF_8).split(","); + boolean isUpdated = false; + boolean hasExistingData = false; + + for (int i = 0; i < gatheringDataArray.length; i++) { + String[] parts = gatheringDataArray[i].split("\\|"); + + if (parts.length == 2) { + if (HmacUtils.verifyHmac(parts[0], parts[1])) { + String[] cookieInfo = parts[0].split("_"); + Long cookieUserId = Long.parseLong(cookieInfo[0]); + Long cookieGatheringId = Long.parseLong(cookieInfo[1]); + LocalDate lastViewedAt = LocalDate.parse(cookieInfo[2], formatter); + + if (cookieUserId.equals(userId) && cookieGatheringId.equals(gathering.getId())) { + hasExistingData = true; + if (lastViewedAt.isBefore(now.minusDays(1))) { + incrementGatheringViewCount(gathering); + String newHmac = HmacUtils.generateHmac(cookieData); + gatheringDataArray[i] = cookieData + "|" + newHmac; + isUpdated = true; + } + break; + } + } + + } + } - if (Objects.nonNull(postCookie)) { - String[] parts = postCookie.getValue().split("\\|"); - if (parts.length == 2 && HmacUtils.verifyHmac(parts[0], parts[1])) { - LocalDate lastViewedAt = LocalDate.parse(parts[0], formatter); - if (lastViewedAt.isBefore(now.minusDays(1))) { + if (isUpdated || !hasExistingData) { + if (!hasExistingData) { incrementGatheringViewCount(gathering); - String newHmac = HmacUtils.generateHmac(cookieData); - postCookie.setValue(cookieData + "|" + newHmac); - response.addCookie(postCookie); } + String hmac = HmacUtils.generateHmac(cookieData); + String updatedValue = String.join(",", gatheringDataArray) + "," + cookieData + "|" + hmac; + postCookie.setValue(URLEncoder.encode(updatedValue, StandardCharsets.UTF_8)); + postCookie.setPath("/"); + response.addCookie(postCookie); } + + } else { incrementGatheringViewCount(gathering); String hmac = HmacUtils.generateHmac(cookieData); - Cookie newCookie = new Cookie(cookieName, cookieData + "|" + hmac); - newCookie.setMaxAge(60 * 60 * 24 * 365); + Cookie newCookie = new Cookie(cookieName, URLEncoder.encode(cookieData + "|" + hmac, StandardCharsets.UTF_8)); + newCookie.setMaxAge(60 * 60 * 24); + newCookie.setPath("/"); response.addCookie(newCookie); } } @@ -512,4 +548,4 @@ private void incrementGatheringViewCount(Gathering gathering) { } -} \ No newline at end of file +} From feb44eddcb6f9e48c417cab0125636fcbe221aa1 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Sun, 15 Sep 2024 04:04:05 +0900 Subject: [PATCH 282/371] =?UTF-8?q?feature:=20=EC=A0=95=EB=B3=B4=20?= =?UTF-8?q?=EC=A1=B0=ED=9A=8C=EC=88=98=20=EA=B8=B0=EB=8A=A5=20=EA=B0=9C?= =?UTF-8?q?=EC=84=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/InformationService.java | 56 +++++++++++++++---- 1 file changed, 44 insertions(+), 12 deletions(-) diff --git a/src/main/java/solitour_backend/solitour/information/service/InformationService.java b/src/main/java/solitour_backend/solitour/information/service/InformationService.java index b234f725..8cfef9ed 100644 --- a/src/main/java/solitour_backend/solitour/information/service/InformationService.java +++ b/src/main/java/solitour_backend/solitour/information/service/InformationService.java @@ -3,6 +3,9 @@ import static solitour_backend.solitour.information.repository.InformationRepositoryCustom.LIKE_COUNT_SORT; import static solitour_backend.solitour.information.repository.InformationRepositoryCustom.VIEW_COUNT_SORT; +import java.net.URLDecoder; +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; import java.time.LocalDate; import java.time.format.DateTimeFormatter; import java.util.ArrayList; @@ -474,7 +477,7 @@ public Page getPageInformationByTag(Pageable pageable, } public void updateViewCount(Information information, HttpServletRequest request, HttpServletResponse response, Long userId) throws Exception { - String cookieName = "viewed_information_" + userId + "_" + information.getId(); + String cookieName = "viewed_informations"; Cookie[] cookies = request.getCookies(); Cookie postCookie = null; @@ -487,24 +490,53 @@ public void updateViewCount(Information information, HttpServletRequest request, LocalDate now = LocalDate.now(); DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); - String cookieData = now.format(formatter); + String cookieData = userId + "_" + information.getId() + "_" + now.format(formatter); + + if (Objects.nonNull(postCookie) && postCookie.getValue() != null) { + String[] informationDataArray = URLDecoder.decode(postCookie.getValue(), StandardCharsets.UTF_8).split(","); + boolean isUpdated = false; + boolean hasExistingData = false; + + for (int i = 0; i < informationDataArray.length; i++) { + String[] parts = informationDataArray[i].split("\\|"); + if (parts.length == 2) { + if (HmacUtils.verifyHmac(parts[0], parts[1])) { + String[] cookieInfo = parts[0].split("_"); + Long cookieUserId = Long.parseLong(cookieInfo[0]); + Long cookieGatheringId = Long.parseLong(cookieInfo[1]); + LocalDate lastViewedAt = LocalDate.parse(cookieInfo[2], formatter); + + if (cookieUserId.equals(userId) && cookieGatheringId.equals(information.getId())) { + hasExistingData = true; + if (lastViewedAt.isBefore(now.minusDays(1))) { + incrementInformationViewCount(information); + String newHmac = HmacUtils.generateHmac(cookieData); + informationDataArray[i] = cookieData + "|" + newHmac; + isUpdated = true; + } + break; + } + } - if (Objects.nonNull(postCookie)) { - String[] parts = postCookie.getValue().split("\\|"); - if (parts.length == 2 && HmacUtils.verifyHmac(parts[0], parts[1])) { - LocalDate lastViewedAt = LocalDate.parse(parts[0], formatter); - if (lastViewedAt.isBefore(now.minusDays(1))) { + } + } + + if (isUpdated || !hasExistingData) { + if (!hasExistingData) { incrementInformationViewCount(information); - String newHmac = HmacUtils.generateHmac(cookieData); - postCookie.setValue(cookieData + "|" + newHmac); - response.addCookie(postCookie); } + String hmac = HmacUtils.generateHmac(cookieData); + String updatedValue = String.join(",", informationDataArray) + "," + cookieData + "|" + hmac; + postCookie.setValue(URLEncoder.encode(updatedValue, StandardCharsets.UTF_8)); + postCookie.setPath("/"); + response.addCookie(postCookie); } } else { incrementInformationViewCount(information); String hmac = HmacUtils.generateHmac(cookieData); - Cookie newCookie = new Cookie(cookieName, cookieData + "|" + hmac); - newCookie.setMaxAge(60 * 60 * 24 * 365); + Cookie newCookie = new Cookie(cookieName, URLEncoder.encode(cookieData + "|" + hmac, StandardCharsets.UTF_8)); + newCookie.setMaxAge(60 * 60 * 24); + newCookie.setPath("/"); response.addCookie(newCookie); } } From ceb8f3300aca3cf6c867c44c5f12308ef9119bd3 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Mon, 16 Sep 2024 20:07:56 +0900 Subject: [PATCH 283/371] =?UTF-8?q?fix:=20error=20=EC=9E=84=EC=8B=9C=20?= =?UTF-8?q?=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../solitour/auth/service/TokenService.java | 5 +++-- .../solitour/diary/service/DiaryService.java | 6 +++++- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/main/java/solitour_backend/solitour/auth/service/TokenService.java b/src/main/java/solitour_backend/solitour/auth/service/TokenService.java index d66d0a71..f6cc983c 100644 --- a/src/main/java/solitour_backend/solitour/auth/service/TokenService.java +++ b/src/main/java/solitour_backend/solitour/auth/service/TokenService.java @@ -21,7 +21,7 @@ public void synchronizeRefreshToken(User user, String refreshToken) { Token token = tokenRepository.findByUserId(user.getId()) .orElseThrow(() -> new TokenNotExistsException("토큰이 존재하지 않습니다")); - token.updateRefreshToken(refreshToken); + token.updateRefreshToken(refreshToken); } @Transactional @@ -31,9 +31,10 @@ public void deleteByMemberId(Long memberId) { @Transactional public void saveToken(KakaoTokenResponse tokenResponse, User user) { - Token token = Token.builder() + Token token = Token.builder() .user(user) .oauthToken(tokenResponse.getRefreshToken()) + .refreshToken("test") .build(); tokenRepository.save(token); diff --git a/src/main/java/solitour_backend/solitour/diary/service/DiaryService.java b/src/main/java/solitour_backend/solitour/diary/service/DiaryService.java index 6f4d0dde..5fbfdcd5 100644 --- a/src/main/java/solitour_backend/solitour/diary/service/DiaryService.java +++ b/src/main/java/solitour_backend/solitour/diary/service/DiaryService.java @@ -2,6 +2,7 @@ import java.time.LocalDateTime; import java.util.List; + import lombok.RequiredArgsConstructor; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; @@ -129,7 +130,10 @@ private void updateDiaryDayContent(Diary savedDiary, DiaryUpdateRequest request) } private void deleteDiaryImage(DiaryUpdateRequest request) { - s3Uploader.deleteImage(request.getDeleteTitleImage()); + if (request.getDeleteTitleImage() != "") { + s3Uploader.deleteImage(request.getDeleteTitleImage()); + } + for (DiaryUpdateDayRequest dayRequest : request.getDiaryDayRequests()) { for (String imageUrl : dayRequest.getSplitImageUrl(dayRequest.getDeleteImagesUrl())) { From c0e9ad789e54fd893f73009652902bf8ad77f86e Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Wed, 18 Sep 2024 02:31:53 +0900 Subject: [PATCH 284/371] =?UTF-8?q?docs:=20git=20ignore=20resources/=20.ym?= =?UTF-8?q?l=20=ED=8C=8C=EC=9D=BC=EB=A1=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 6492e3c0..0678df47 100644 --- a/.gitignore +++ b/.gitignore @@ -180,4 +180,4 @@ Temporary Items /docker/db/ # 설정 파일 -/src/main/resources +/src/main/resources/**.yml From 1677e84dbd37e155bb264a6e15e2912aed1bba07 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Wed, 18 Sep 2024 02:32:15 +0900 Subject: [PATCH 285/371] docs: schema.sql --- src/main/resources/schema.sql | 313 ++++++++++++++++++++++++++++++++++ 1 file changed, 313 insertions(+) create mode 100644 src/main/resources/schema.sql diff --git a/src/main/resources/schema.sql b/src/main/resources/schema.sql new file mode 100644 index 00000000..32ea927d --- /dev/null +++ b/src/main/resources/schema.sql @@ -0,0 +1,313 @@ +DROP TABLE IF EXISTS `great_information`; +DROP TABLE IF EXISTS `great_gathering`; +DROP TABLE IF EXISTS `book_mark_information`; +DROP TABLE IF EXISTS `book_mark_gathering`; +DROP TABLE IF EXISTS `info_tag`; +DROP TABLE IF EXISTS `gathering_tag`; +DROP TABLE IF EXISTS `comment`; +DROP TABLE IF EXISTS `image`; +DROP TABLE IF EXISTS `information`; +DROP TABLE IF EXISTS `gathering_applicants`; +DROP TABLE IF EXISTS `gathering`; +DROP TABLE IF EXISTS `tag`; +DROP TABLE IF EXISTS `category`; +DROP TABLE IF EXISTS `gathering_category`; +DROP TABLE IF EXISTS `zone_category`; +DROP TABLE IF EXISTS `place`; +DROP TABLE IF EXISTS `token`; +DROP TABLE IF EXISTS `banner`; +DROP TABLE IF EXISTS `notice`; +DROP TABLE IF EXISTS `qna_message`; +DROP TABLE IF EXISTS `qna`; +DROP TABLE IF EXISTS `user`; +DROP TABLE IF EXISTS `user_image`; +DROP TABLE IF EXISTS `diary_day_content`; +DROP TABLE IF EXISTS `diary`; + +CREATE TABLE `user_image` +( + `user_image_id` BIGINT NOT NULL AUTO_INCREMENT, + `user_image_address` VARCHAR(200) NOT NULL, + `user_image_created_date` DATE NOT NULL, + CONSTRAINT PK_user_image PRIMARY KEY (`user_image_id`) +); + +CREATE TABLE `user` +( + `user_id` BIGINT NOT NULL AUTO_INCREMENT, + `user_image_id` BIGINT NOT NULL, + `user_status_id` VARCHAR(20) NOT NULL, + `user_oauth_id` VARCHAR(100) NULL UNIQUE, + `provider` VARCHAR(10) NULL, + `user_nickname` VARCHAR(30) NULL, + `user_name` VARCHAR(20) NULL, + `user_age` INT NULL, + `user_sex` VARCHAR(10) NULL, + `user_email` VARCHAR(30) NULL, + `user_phone_number` VARCHAR(13) NULL, + `is_admin` BOOLEAN NOT NULL, + `user_latest_login_at` DATETIME NULL, + `user_created_at` DATETIME NOT NULL, + `user_deleted_at` DATETIME NULL, + CONSTRAINT PK_USER PRIMARY KEY (`user_id`), + CONSTRAINT FK_USER_IMAGE_TO_USER FOREIGN KEY (`user_image_id`) REFERENCES `user_image` (`user_image_id`) +); + +CREATE TABLE `token` +( + `token_id` BIGINT NOT NULL AUTO_INCREMENT, + `user_id` BIGINT NOT NULL, + `refresh_token` VARCHAR(250) NOT NULL, + CONSTRAINT PK_TOKEN PRIMARY KEY (`token_id`), + CONSTRAINT FK_USER_TO_TOKEN FOREIGN KEY (`user_id`) REFERENCES `user` (`user_id`) +); + +CREATE TABLE `place` +( + `place_id` BIGINT NOT NULL AUTO_INCREMENT, + `place_search_id` VARCHAR(30) NULL, + `place_name` VARCHAR(30) NOT NULL, + `place_x_axis` DECIMAL(10, 7) NOT NULL, + `place_y_axis` DECIMAL(10, 7) NOT NULL, + `place_address` VARCHAR(50) NOT NULL, + CONSTRAINT PK_PLACE PRIMARY KEY (`place_id`) +); + +CREATE TABLE `zone_category` +( + `zone_category_id` BIGINT NOT NULL AUTO_INCREMENT, + `parent_zone_category_id` BIGINT NULL, + `zone_category_name` VARCHAR(20) NOT NULL, + CONSTRAINT PK_ZONE_CATEGORY PRIMARY KEY (`zone_category_id`), + CONSTRAINT FK_zone_category_TO_zone_category FOREIGN KEY (`parent_zone_category_id`) REFERENCES `zone_category` (`zone_category_id`) +); + +CREATE TABLE `category` +( + `category_id` BIGINT NOT NULL AUTO_INCREMENT, + `parent_category_id` BIGINT NULL, + `category_name` VARCHAR(20) NOT NULL, + CONSTRAINT PK_CATEGORY PRIMARY KEY (`category_id`), + CONSTRAINT FK_category_TO_category FOREIGN KEY (`parent_category_id`) REFERENCES `category` (`category_id`) +); + +CREATE TABLE `gathering_category` +( + `gathering_category_id` BIGINT NOT NULL AUTO_INCREMENT, + `gathering_category_name` VARCHAR(20) NOT NULL, + CONSTRAINT PK_GATHERING_CATEGORY PRIMARY KEY (`gathering_category_id`) +); + +CREATE TABLE `information` +( + `information_id` BIGINT NOT NULL AUTO_INCREMENT, + `category_id` BIGINT NOT NULL, + `zone_category_id` BIGINT NOT NULL, + `user_id` BIGINT NOT NULL, + `place_id` BIGINT NOT NULL, + `information_title` VARCHAR(50) NOT NULL, + `information_address` VARCHAR(50) NOT NULL, + `information_created_date` DATETIME NOT NULL, + `information_view_count` INT NOT NULL DEFAULT 0, + `information_content` TEXT NULL, + `information_tip` TEXT NULL, + CONSTRAINT PK_information PRIMARY KEY (`information_id`), + CONSTRAINT FK_category_TO_information FOREIGN KEY (`category_id`) REFERENCES `category` (`category_id`), + CONSTRAINT FK_zone_category_TO_information FOREIGN KEY (`zone_category_id`) REFERENCES `zone_category` (`zone_category_id`), + CONSTRAINT FK_user_TO_information FOREIGN KEY (`user_id`) REFERENCES `user` (`user_id`), + CONSTRAINT FK_place_TO_information FOREIGN KEY (`place_id`) REFERENCES `place` (`place_id`) +); + +CREATE TABLE `gathering` +( + `gathering_id` BIGINT NOT NULL AUTO_INCREMENT, + `user_id` BIGINT NOT NULL, + `zone_category_id` BIGINT NOT NULL, + `gathering_category_id` BIGINT NOT NULL, + `place_id` BIGINT NOT NULL, + `gathering_title` VARCHAR(50) NULL, + `gathering_content` TEXT NULL, + `gathering_person_count` INT NULL, + `gathering_view_count` INT NULL, + `gathering_created_at` DATETIME NULL, + `gathering_edited_at` DATETIME NULL, + `gathering_schedule_start_date` DATETIME NULL, + `gathering_schedule_end_date` DATETIME NULL, + `gathering_is_finish` BOOLEAN NULL, + `gathering_deadline` DATETIME NULL, + `gathering_allowed_sex` VARCHAR(30) NOT NULL, + `gathering_start_age` INT NOT NULL, + `gathering_end_age` INT NOT NULL, + `gathering_is_deleted` BOOLEAN NOT NULL DEFAULT FALSE, + `gathering_open_chatting_url` VARCHAR(255) NULL, + + CONSTRAINT PK_gathering PRIMARY KEY (`gathering_id`), + CONSTRAINT FK_user_TO_gathering FOREIGN KEY (`user_id`) REFERENCES `user` (`user_id`), + CONSTRAINT FK_gathering_category_TO_information FOREIGN KEY (`gathering_category_id`) REFERENCES `gathering_category` (`gathering_category_id`), + CONSTRAINT FK_zone_category_TO_gathering FOREIGN KEY (`zone_category_id`) REFERENCES `zone_category` (`zone_category_id`), + CONSTRAINT FK_place_TO_gathering FOREIGN KEY (`place_id`) REFERENCES `place` (`place_id`) +); + +CREATE TABLE `gathering_applicants` +( + `gathering_applicants_id` BIGINT NOT NULL AUTO_INCREMENT, + `gathering_id` BIGINT NOT NULL, + `user_id` BIGINT NOT NULL, + `gathering_applicants_state` VARCHAR(20) NOT NULL, + CONSTRAINT PK_GATHERING_APPLICANTS PRIMARY KEY (`gathering_applicants_id`), + CONSTRAINT FK_GATHERING_TO_GATHERING_APPLICANTS FOREIGN KEY (`gathering_id`) REFERENCES `gathering` (`gathering_id`), + CONSTRAINT FK_user_TO_GATHERING_APPLICANTS FOREIGN KEY (`user_id`) REFERENCES `user` (`user_id`) +); + +CREATE TABLE `image` +( + `image_id` BIGINT NOT NULL AUTO_INCREMENT, + `image_status_id` VARCHAR(20) NOT NULL, + `information_id` BIGINT NOT NULL, + `image_address` VARCHAR(200) NOT NULL, + `image_created_date` DATE NOT NULL, + CONSTRAINT PK_image PRIMARY KEY (`image_id`), + CONSTRAINT FK_information_id_TO_image FOREIGN KEY (`information_id`) REFERENCES `information` (`information_id`) +); + +CREATE TABLE `great_information` +( + `great_information_id` BIGINT NOT NULL AUTO_INCREMENT, + `user_id` BIGINT NOT NULL, + `information_id` BIGINT NOT NULL, + CONSTRAINT PK_great_information PRIMARY KEY (`great_information_id`), + CONSTRAINT FK_great_information_TO_user FOREIGN KEY (`user_id`) REFERENCES `user` (`user_id`), + CONSTRAINT FK_great_information_TO_information FOREIGN KEY (`information_id`) REFERENCES `information` (`information_id`), + CONSTRAINT UK_great_information UNIQUE (`user_id`, `information_id`) +); + +CREATE TABLE `great_gathering` +( + `great_gathering_id` BIGINT NOT NULL AUTO_INCREMENT, + `user_id` BIGINT NOT NULL, + `gathering_id` BIGINT NOT NULL, + CONSTRAINT PK_great_gathering PRIMARY KEY (`great_gathering_id`), + CONSTRAINT FK_great_gathering_TO_user FOREIGN KEY (`user_id`) REFERENCES `user` (`user_id`), + CONSTRAINT FK_great_gathering_TO_gathering FOREIGN KEY (`gathering_id`) REFERENCES `gathering` (`gathering_id`), + CONSTRAINT UK_great_gathering UNIQUE (`user_id`, `gathering_id`) +); + +CREATE TABLE `book_mark_information` +( + `book_mark_information_id` BIGINT NOT NULL AUTO_INCREMENT, + `user_id` BIGINT NOT NULL, + `information_id` BIGINT NOT NULL, + CONSTRAINT PK_book_mark_information PRIMARY KEY (`book_mark_information_id`), + CONSTRAINT FK_book_mark_information_TO_user FOREIGN KEY (`user_id`) REFERENCES `user` (`user_id`), + CONSTRAINT FK_book_mark_information_TO_information FOREIGN KEY (`information_id`) REFERENCES `information` (`information_id`), + CONSTRAINT UK_book_mark_information UNIQUE (`user_id`, `information_id`) +); + +CREATE TABLE `book_mark_gathering` +( + `book_mark_gathering_id` BIGINT NOT NULL AUTO_INCREMENT, + `user_id` BIGINT NOT NULL, + `gathering_id` BIGINT NOT NULL, + CONSTRAINT PK_book_mark_gathering PRIMARY KEY (`book_mark_gathering_id`), + CONSTRAINT FK_book_mark_gathering_TO_user FOREIGN KEY (`user_id`) REFERENCES `user` (`user_id`), + CONSTRAINT FK_book_mark_gathering_TO_gathering FOREIGN KEY (`gathering_id`) REFERENCES `gathering` (`gathering_id`), + CONSTRAINT UK_book_mark_gathering UNIQUE (`user_id`, `gathering_id`) +); + +CREATE TABLE `tag` +( + `tag_id` BIGINT NOT NULL AUTO_INCREMENT, + `tag_name` VARCHAR(16) NOT NULL, + CONSTRAINT PK_tag PRIMARY KEY (`tag_id`) +); + +CREATE TABLE `info_tag` +( + `info_tag_id` BIGINT NOT NULL AUTO_INCREMENT, + `tag_id` BIGINT NOT NULL, + `information_id` BIGINT NOT NULL, + CONSTRAINT PK_info_tag PRIMARY KEY (`info_tag_id`), + CONSTRAINT FK_info_tag_TO_tag FOREIGN KEY (`tag_id`) REFERENCES `tag` (`tag_id`), + CONSTRAINT FK_info_tag_TO_information FOREIGN KEY (`information_id`) REFERENCES `information` (`information_id`), + CONSTRAINT UK_info_tag UNIQUE (`tag_id`, `information_id`) +); + +CREATE TABLE `gathering_tag` +( + `gathering_tag_id` BIGINT NOT NULL AUTO_INCREMENT, + `tag_id` BIGINT NOT NULL, + `gathering_id` BIGINT NOT NULL, + CONSTRAINT PK_gathering_tag PRIMARY KEY (`gathering_tag_id`), + CONSTRAINT FK_gathering_tag_TO_tag FOREIGN KEY (`tag_id`) REFERENCES `tag` (`tag_id`), + CONSTRAINT FK_gathering_tag_TO_gathering FOREIGN KEY (`gathering_id`) REFERENCES `gathering` (`gathering_id`), + CONSTRAINT UK_gathering_tag UNIQUE (`tag_id`, `gathering_id`) +); + +CREATE TABLE `banner` +( + `id` BIGINT NOT NULL AUTO_INCREMENT, + `name` VARCHAR(255) NOT NULL, + `url` VARCHAR(255) NOT NULL, + PRIMARY KEY (`id`) +); + +CREATE TABLE `qna` +( + `qna_id` BIGINT NOT NULL AUTO_INCREMENT, + `qna_category_name` VARCHAR(255) DEFAULT NULL, + `qna_created_at` DATETIME DEFAULT NULL, + `qna_status` VARCHAR(255) DEFAULT NULL, + `qna_title` VARCHAR(255) DEFAULT NULL, + `qna_updated_at` DATETIME DEFAULT NULL, + `user_id` BIGINT DEFAULT NULL, + PRIMARY KEY (`qna_id`), + CONSTRAINT FK_qna_user FOREIGN KEY (`user_id`) REFERENCES `user` (`user_id`) +); + +CREATE TABLE `qna_message` +( + `id` BIGINT NOT NULL AUTO_INCREMENT, + `qna_message_content` TEXT DEFAULT NULL, + `qna_message_created_at` DATETIME DEFAULT NULL, + `qna_message_user_id` BIGINT DEFAULT NULL, + `qna_id` BIGINT DEFAULT NULL, + PRIMARY KEY (`id`), + CONSTRAINT FK_qna_message_qna FOREIGN KEY (`qna_id`) REFERENCES `qna` (`qna_id`), + CONSTRAINT FK_qna_message_user FOREIGN KEY (`qna_message_user_id`) REFERENCES `user` (`user_id`) +); + +CREATE TABLE `notice` +( + `notice_id` BIGINT NOT NULL AUTO_INCREMENT, + `notice_category_name` VARCHAR(255) DEFAULT NULL, + `notice_content` TEXT DEFAULT NULL, + `notice_created_at` DATETIME DEFAULT NULL, + `notice_is_deleted` BOOLEAN DEFAULT FALSE, + `notice_title` VARCHAR(255) DEFAULT NULL, + PRIMARY KEY (`notice_id`) +); + +CREATE TABLE `diary` +( + `diary_id` BIGINT NOT NULL AUTO_INCREMENT, + `user_id` BIGINT NOT NULL, + `diary_title` VARCHAR(50) NOT NULL, + `diary_title_image` VARCHAR(200) DEFAULT NULL, + `diary_start_date` DATETIME NOT NULL, + `diary_end_date` DATETIME NOT NULL, + `diary_created_date` DATETIME NOT NULL, + `diary_edited_date` DATETIME DEFAULT NULL, + PRIMARY KEY (`diary_id`) +); + +CREATE TABLE `diary_day_content` +( + `diary_day_content_id` BIGINT NOT NULL AUTO_INCREMENT, + `diary_id` BIGINT NOT NULL, + `diary_day_content_place` VARCHAR(20) NOT NULL, + `diary_day_content_content` TEXT NOT NULL, + `diary_day_content_feeling_status` VARCHAR(20) NOT NULL, + `diary_day_content_image` TEXT DEFAULT NULL, + PRIMARY KEY (`diary_day_content_id`), + CONSTRAINT `FK_diary_day_content_TO_diary` FOREIGN KEY (`diary_id`) REFERENCES `diary` (`diary_id`) +); \ No newline at end of file From 2e6e267dc215b6a926a427409a96f5e19511361f Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Wed, 18 Sep 2024 02:32:26 +0900 Subject: [PATCH 286/371] =?UTF-8?q?docs:=20=EC=B4=88=EB=B0=98=20data.sql?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/resources/category.sql | 22 ++ src/main/resources/gathering_category.sql | 3 + src/main/resources/zone_category.sql | 280 ++++++++++++++++++++++ 3 files changed, 305 insertions(+) create mode 100644 src/main/resources/category.sql create mode 100644 src/main/resources/gathering_category.sql create mode 100644 src/main/resources/zone_category.sql diff --git a/src/main/resources/category.sql b/src/main/resources/category.sql new file mode 100644 index 00000000..24ee1e98 --- /dev/null +++ b/src/main/resources/category.sql @@ -0,0 +1,22 @@ +INSERT INTO `category` (`parent_category_id`, `category_name`) +VALUES (NULL, '맛집'), + (NULL, '숙박'), + (NULL, '액티비티'); + +INSERT INTO `category` (`parent_category_id`, `category_name`) +VALUES (1, '혼카페'), + (1, '혼밥'), + (1, '혼술'); + +INSERT INTO `category` (`parent_category_id`, `category_name`) +VALUES (2, '호텔/펜션'), + (2, '게스트하우스'), + (2, '모텔'), + (2, '홈/빌라'), + (2, '한옥'); + +INSERT INTO `category` (`parent_category_id`, `category_name`) +VALUES (3, '수상레저'), + (3, '관광지'), + (3, '전시'), + (3, '편집/소품샵'); diff --git a/src/main/resources/gathering_category.sql b/src/main/resources/gathering_category.sql new file mode 100644 index 00000000..73bb723f --- /dev/null +++ b/src/main/resources/gathering_category.sql @@ -0,0 +1,3 @@ +INSERT INTO `gathering_category` (`gathering_category_name`) +VALUES ('취미'), + ('활동'); \ No newline at end of file diff --git a/src/main/resources/zone_category.sql b/src/main/resources/zone_category.sql new file mode 100644 index 00000000..a9eaa9a9 --- /dev/null +++ b/src/main/resources/zone_category.sql @@ -0,0 +1,280 @@ +INSERT INTO `zone_category` (`parent_zone_category_id`, `zone_category_name`) +VALUES (NULL, '서울'), + (NULL, '광주'), + (NULL, '인천'), + (NULL, '대전'), + (NULL, '대구'), + (NULL, '전남'), + (NULL, '경북'), + (NULL, '경남'), + (NULL, '부산'), + (NULL, '울산'), + (NULL, '제주'), + (NULL, '경기'), + (NULL, '강원'), + (NULL, '충북'), + (NULL, '충남'), + (NULL, '전북'); + +INSERT INTO `zone_category` (`parent_zone_category_id`, `zone_category_name`) +VALUES (1, '강남구'), + (1, '강동구'), + (1, '강북구'), + (1, '강서구'), + (1, '관악구'), + (1, '광진구'), + (1, '구로구'), + (1, '금천구'), + (1, '노원구'), + (1, '도봉구'), + (1, '동대문구'), + (1, '동작구'), + (1, '마포구'), + (1, '서대문구'), + (1, '서초구'), + (1, '성동구'), + (1, '성북구'), + (1, '송파구'), + (1, '양천구'), + (1, '영등포구'), + (1, '용산구'), + (1, '은평구'), + (1, '종로구'), + (1, '중구'), + (1, '중랑구'); + +INSERT INTO `zone_category` (`parent_zone_category_id`, `zone_category_name`) +VALUES (2, '동구'), + (2, '서구'), + (2, '남구'), + (2, '북구'), + (2, '광산구'); + +INSERT INTO `zone_category` (`parent_zone_category_id`, `zone_category_name`) +VALUES (3, '중구'), + (3, '동구'), + (3, '미추홀구'), + (3, '연수구'), + (3, '남동구'), + (3, '부평구'), + (3, '계양구'), + (3, '서구'), + (3, '강화군'), + (3, '옹진군'); + +INSERT INTO `zone_category` (`parent_zone_category_id`, `zone_category_name`) +VALUES (4, '동구'), + (4, '중구'), + (4, '서구'), + (4, '유성구'), + (4, '대덕구'); + +INSERT INTO `zone_category` (`parent_zone_category_id`, `zone_category_name`) +VALUES (5, '중구'), + (5, '동구'), + (5, '서구'), + (5, '남구'), + (5, '북구'), + (5, '수성구'), + (5, '달서구'), + (5, '달성군'), + (5, '군위군'); + +INSERT INTO `zone_category` (`parent_zone_category_id`, `zone_category_name`) +VALUES (6, '목포시'), + (6, '여수시'), + (6, '순천시'), + (6, '나주시'), + (6, '광양시'), + (6, '담양군'), + (6, '곡성군'), + (6, '구례군'), + (6, '고흥군'), + (6, '보성군'), + (6, '화순군'), + (6, '장흥군'), + (6, '강진군'), + (6, '해남군'), + (6, '영암군'), + (6, '무안군'), + (6, '함평군'), + (6, '영광군'), + (6, '장성군'), + (6, '완도군'), + (6, '진도군'), + (6, '신안군'); + +INSERT INTO `zone_category` (`parent_zone_category_id`, `zone_category_name`) +VALUES (7, '포항시'), + (7, '경주시'), + (7, '김천시'), + (7, '안동시'), + (7, '구미시'), + (7, '영주시'), + (7, '영천시'), + (7, '상주시'), + (7, '문경시'), + (7, '경산시'), + (7, '의성군'), + (7, '청송군'), + (7, '영양군'), + (7, '영덕군'), + (7, '청도군'), + (7, '고령군'), + (7, '성주군'), + (7, '칠곡군'), + (7, '예천군'), + (7, '봉화군'), + (7, '울진군'), + (7, '울릉군'); + +INSERT INTO `zone_category` (`parent_zone_category_id`, `zone_category_name`) +VALUES (8, '창원시'), + (8, '김해시'), + (8, '진주시'), + (8, '양산시'), + (8, '거제시'), + (8, '통영시'), + (8, '사천시'), + (8, '밀양시'), + (8, '함안군'), + (8, '거창군'), + (8, '창녕군'), + (8, '고성군'), + (8, '하동군'), + (8, '합천군'), + (8, '남해군'), + (8, '함양군'), + (8, '산청군'), + (8, '의령군'); + +INSERT INTO `zone_category` (`parent_zone_category_id`, `zone_category_name`) +VALUES (9, '중구'), + (9, '서구'), + (9, '동구'), + (9, '영도구'), + (9, '부산진구'), + (9, '동래구'), + (9, '남구'), + (9, '북구'), + (9, '해운대구'), + (9, '사하구'), + (9, '금정구'), + (9, '강서구'), + (9, '연제구'), + (9, '수영구'), + (9, '사상구'), + (9, '기장군'); + +INSERT INTO `zone_category` (`parent_zone_category_id`, `zone_category_name`) +VALUES (10, '중구'), + (10, '남구'), + (10, '동구'), + (10, '북구'), + (10, '울주군'); + +INSERT INTO `zone_category` (`parent_zone_category_id`, `zone_category_name`) +VALUES (11, '서귀포시'), + (11, '제주시'); + +INSERT INTO `zone_category` (`parent_zone_category_id`, `zone_category_name`) +VALUES (12, '수원시'), + (12, '성남시'), + (12, '용인시'), + (12, '안양시'), + (12, '안산시'), + (12, '과천시'), + (12, '광명시'), + (12, '광주시'), + (12, '군포시'), + (12, '부천시'), + (12, '시흥시'), + (12, '김포시'), + (12, '안성시'), + (12, '오산시'), + (12, '의왕시'), + (12, '이천시'), + (12, '평택시'), + (12, '하남시'), + (12, '화성시'), + (12, '여주시'), + (12, '양평군'), + (12, '고양시'), + (12, '구리시'), + (12, '남양주시'), + (12, '동두천시'), + (12, '양주시'), + (12, '의정부시'), + (12, '파주시'), + (12, '포천시'), + (12, '연천군'), + (12, '가평군'); + +INSERT INTO `zone_category` (`parent_zone_category_id`, `zone_category_name`) +VALUES (13, '원주시'), + (13, '춘천시'), + (13, '강릉시'), + (13, '동해시'), + (13, '속초시'), + (13, '삼척시'), + (13, '태백시'), + (13, '홍천군'), + (13, '철원군'), + (13, '횡성군'), + (13, '평창군'), + (13, '정선군'), + (13, '영월군'), + (13, '인제군'), + (13, '고성군'), + (13, '양양군'), + (13, '화천군'), + (13, '양구군'); + +INSERT INTO `zone_category` (`parent_zone_category_id`, `zone_category_name`) +VALUES (14, '청주시'), + (14, '충주시'), + (14, '제천시'), + (14, '보은군'), + (14, '옥천군'), + (14, '영동군'), + (14, '증평군'), + (14, '진천군'), + (14, '괴산군'), + (14, '음성군'), + (14, '단양군'); + +INSERT INTO `zone_category` (`parent_zone_category_id`, `zone_category_name`) +VALUES (15, '천안시'), + (15, '공주시'), + (15, '보령시'), + (15, '아산시'), + (15, '서산시'), + (15, '논산시'), + (15, '계룡시'), + (15, '당진시'), + (15, '금산군'), + (15, '부여군'), + (15, '서천군'), + (15, '청양군'), + (15, '홍성군'), + (15, '예산군'), + (15, '태안군'); + +INSERT INTO `zone_category` (`parent_zone_category_id`, `zone_category_name`) +VALUES (16, '전주시'), + (16, '익산시'), + (16, '군산시'), + (16, '정읍시'), + (16, '김제시'), + (16, '남원시'), + (16, '완주군'), + (16, '고창군'), + (16, '부안군'), + (16, '임실군'), + (16, '순창군'), + (16, '진안군'), + (16, '무주군'), + (16, '장수군'); + +# INSERT INTO `zone_category` (`parent_zone_category_id`, `zone_category_name`) +# VALUES (17, '세종'); \ No newline at end of file From 2a492ec8777ece8680cc306f5dc69da2f1de6a49 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Wed, 18 Sep 2024 02:32:51 +0900 Subject: [PATCH 287/371] =?UTF-8?q?docs:=20git=20actions=20yml=ED=8C=8C?= =?UTF-8?q?=EC=9D=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/deploy.yml | 66 ++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 .github/workflows/deploy.yml diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml new file mode 100644 index 00000000..43cdc177 --- /dev/null +++ b/.github/workflows/deploy.yml @@ -0,0 +1,66 @@ +name: Docker Image CI + +on: + push: + branches: [ "main", "dev" ] + pull_request: + branches: [ "main", "dev" ] + +jobs: + build: + runs-on: ubuntu-latest + steps: + - name: Github Repository 에 올린 파일들을 볼러오기 + uses: actions/checkout@v4 + + - name: JDK 17 버전 설치 + uses: actions/setup-java@v4 + with: + distribution: temurin + java-version: 17 + + - name: application.yml 파일 만들기 + run: | + echo "${{ secrets.APPLICATION_YML }}" > ./src/main/resources/application.yml + echo "${{ secrets.APPLICATION_DEV }}" > ./src/main/resources/application-dev.yml + echo "${{ secrets.APPLICATION_PROD }}" > ./src/main/resources/application-prod.yml + echo "${{ secrets.APPLICATION_LOCAL }}" > ./src/main/resources/application-local.yml + +# - name: sql 파일 만들기 +# run: | +# echo "${{ secrets.SCHEMA }}" > ./src/main/resources/schema.sql +# echo "${{ secrets.CATEGORY }}" > ./src/main/resources/category.sql +# echo "${{ secrets.GATHERING_CATEGORY }}" > ./src/main/resources/gathering_category.sql +# echo "${{ secrets.ZONE_CATEGORY }}" > ./src/main/resources/zone_category.sql + + - name: 테스트 및 빌드하기 + run: ./gradlew clean build + + - name: 빌드된 파일 이름 변경 + run: mv ./build/libs/*SNAPSHOT.jar ./project.jar + + - name: SCP로 EC2에 빌드된 파일 전송 + uses: appleboy/scp-action@v0.1.7 + with: + host: ${{ secrets.EC2_HOST }} + username: ${{ secrets.EC2_USERNAME }} + key: ${{ secrets.EC2_PRIVATE_KEY }} + source: project.jar + target: /home/ubuntu/solitour-server/tobe + + - name: SSH로 EC2 접속 + uses: appleboy/ssh-action@v1.0.3 + with: + host: ${{ secrets.EC2_HOST }} + username: ${{ secrets.EC2_USERNAME }} + key: ${{ secrets.EC2_PRIVATE_KEY }} + script_stop: true + script: | + rm -rf /home/ubuntu/solitour-server/current + mkdir /home/ubuntu/solitour-server/current + mv /home/ubuntu/solitour-server/tobe/project.jar /home/ubuntu/solitour-server/current/project.jar + cd /home/ubuntu/solitour-server/current + sudo fuser -k -n tcp 8080 || true + nohup java -jar project.jar > ./output.log 2>&1 & + rm -rf /home/ubuntu/solitour-server/tobe + From 97606e81977dc050c8b5fd59f13163619fcbc812 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Wed, 18 Sep 2024 02:45:04 +0900 Subject: [PATCH 288/371] =?UTF-8?q?docs:=20git=20actions=20yml=20=ED=8C=8C?= =?UTF-8?q?=EC=9D=BC=20=EB=B3=80=EA=B2=BD=20-=20=EB=B8=8C=EB=9E=9C?= =?UTF-8?q?=EC=B9=98=20=EB=B3=84=EB=A1=9C=20application.yml=20=ED=8C=8C?= =?UTF-8?q?=EC=9D=BC=20=EB=8B=A4=EB=A5=B4=EA=B2=8C=20=EC=84=A4=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/deploy.yml | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 43cdc177..c83b6ec2 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -2,9 +2,9 @@ name: Docker Image CI on: push: - branches: [ "main", "dev" ] + branches: [ "main", "develop" ] pull_request: - branches: [ "main", "dev" ] + branches: [ "main", "develop" ] jobs: build: @@ -33,8 +33,13 @@ jobs: # echo "${{ secrets.GATHERING_CATEGORY }}" > ./src/main/resources/gathering_category.sql # echo "${{ secrets.ZONE_CATEGORY }}" > ./src/main/resources/zone_category.sql - - name: 테스트 및 빌드하기 - run: ./gradlew clean build + - name: 테스트 및 빌드하기 (main 브랜치) + if: github.ref == 'refs/heads/main' + run: ./gradlew clean build --args='--spring.profiles.active=prod' + + - name: 테스트 및 빌드하기 (develop 브랜치) + if: github.ref == 'refs/heads/develop' + run: ./gradlew clean build --args='--spring.profiles.active=dev' - name: 빌드된 파일 이름 변경 run: mv ./build/libs/*SNAPSHOT.jar ./project.jar From 44c68133edc8d60200a9862306a302554783966f Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Wed, 18 Sep 2024 02:47:23 +0900 Subject: [PATCH 289/371] =?UTF-8?q?docs:=20git=20actions=20yml=20=ED=8C=8C?= =?UTF-8?q?=EC=9D=BC=20=EB=B3=80=EA=B2=BD=20-=20gradlew=20=EC=8B=A4?= =?UTF-8?q?=ED=96=89=20=EA=B6=8C=ED=95=9C=20=EB=B6=80=EC=97=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/deploy.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index c83b6ec2..2913bf06 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -33,6 +33,9 @@ jobs: # echo "${{ secrets.GATHERING_CATEGORY }}" > ./src/main/resources/gathering_category.sql # echo "${{ secrets.ZONE_CATEGORY }}" > ./src/main/resources/zone_category.sql + - name: gradlew 실행 권한 부여 + run: chmod +x ./gradlew + - name: 테스트 및 빌드하기 (main 브랜치) if: github.ref == 'refs/heads/main' run: ./gradlew clean build --args='--spring.profiles.active=prod' From ec5cc99af815889bf5a157e5d3a321470d456e51 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Wed, 18 Sep 2024 02:54:45 +0900 Subject: [PATCH 290/371] =?UTF-8?q?docs:=20git=20actions=20yml=20=ED=8C=8C?= =?UTF-8?q?=EC=9D=BC=20=EB=B3=80=EA=B2=BD=20-=20gradlew=20=EC=8B=A4?= =?UTF-8?q?=ED=96=89=20gradle9.0=20=EB=B2=84=EC=A0=84=EC=97=90=20=EB=A7=9E?= =?UTF-8?q?=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 --- .github/workflows/deploy.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 2913bf06..1e7a6a13 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -38,11 +38,11 @@ jobs: - name: 테스트 및 빌드하기 (main 브랜치) if: github.ref == 'refs/heads/main' - run: ./gradlew clean build --args='--spring.profiles.active=prod' + run: ./gradlew clean build -PspringProfile=prod - name: 테스트 및 빌드하기 (develop 브랜치) if: github.ref == 'refs/heads/develop' - run: ./gradlew clean build --args='--spring.profiles.active=dev' + run: ./gradlew clean build -PspringProfile=dev - name: 빌드된 파일 이름 변경 run: mv ./build/libs/*SNAPSHOT.jar ./project.jar From 81f2e3b3edad6b3a1c3813fc34abbded271c3aaa Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Wed, 18 Sep 2024 03:00:16 +0900 Subject: [PATCH 291/371] =?UTF-8?q?docs:=20git=20actions=20yml=20=ED=8C=8C?= =?UTF-8?q?=EC=9D=BC=20=EB=B3=80=EA=B2=BD=20-=20gradlew=20=EC=8B=A4?= =?UTF-8?q?=ED=96=89=20=EC=8B=9C=20=EC=98=A4=EB=A5=98=EA=B0=80=20=EB=82=A0?= =?UTF-8?q?=20=EA=B2=BD=EC=9A=B0=20=EC=96=B4=EB=96=A4=20=EC=98=A4=EB=A5=98?= =?UTF-8?q?=EC=9D=B8=EC=A7=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/deploy.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 1e7a6a13..fa6c69ab 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -38,11 +38,11 @@ jobs: - name: 테스트 및 빌드하기 (main 브랜치) if: github.ref == 'refs/heads/main' - run: ./gradlew clean build -PspringProfile=prod + run: ./gradlew clean build -PspringProfile=prod --warning-mode all - name: 테스트 및 빌드하기 (develop 브랜치) if: github.ref == 'refs/heads/develop' - run: ./gradlew clean build -PspringProfile=dev + run: ./gradlew clean build -PspringProfile=dev --warning-mode all - name: 빌드된 파일 이름 변경 run: mv ./build/libs/*SNAPSHOT.jar ./project.jar From d797f1012071d2b10fb8d685122efc4b323bb58b Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Wed, 18 Sep 2024 03:04:52 +0900 Subject: [PATCH 292/371] =?UTF-8?q?docs:=20git=20actions=20yml=20=ED=8C=8C?= =?UTF-8?q?=EC=9D=BC=20=EB=B3=80=EA=B2=BD=20-=20gradlew=20=EC=8B=A4?= =?UTF-8?q?=ED=96=89=20=EC=8B=9C=20=EC=98=A4=EB=A5=98=EA=B0=80=20=EB=82=A0?= =?UTF-8?q?=20=EA=B2=BD=EC=9A=B0=20=EC=96=B4=EB=96=A4=20=EC=98=A4=EB=A5=98?= =?UTF-8?q?=EC=9D=B8=EC=A7=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/deploy.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index fa6c69ab..5e8e24f4 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -38,11 +38,11 @@ jobs: - name: 테스트 및 빌드하기 (main 브랜치) if: github.ref == 'refs/heads/main' - run: ./gradlew clean build -PspringProfile=prod --warning-mode all + run: ./gradlew clean build -PspringProfile=prod --warning-mode all --scan - name: 테스트 및 빌드하기 (develop 브랜치) if: github.ref == 'refs/heads/develop' - run: ./gradlew clean build -PspringProfile=dev --warning-mode all + run: ./gradlew clean build -PspringProfile=dev --warning-mode all --scan - name: 빌드된 파일 이름 변경 run: mv ./build/libs/*SNAPSHOT.jar ./project.jar From 71f5788c369ffefc6989b63b97aec5477401e8f1 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Wed, 18 Sep 2024 03:25:01 +0900 Subject: [PATCH 293/371] =?UTF-8?q?docs:=20git=20actions=20yml=20=ED=8C=8C?= =?UTF-8?q?=EC=9D=BC=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/deploy.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 5e8e24f4..55abbf60 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -38,11 +38,11 @@ jobs: - name: 테스트 및 빌드하기 (main 브랜치) if: github.ref == 'refs/heads/main' - run: ./gradlew clean build -PspringProfile=prod --warning-mode all --scan + run: ./gradlew clean bootJar -PspringProfile=prod --warning-mode all --scan - name: 테스트 및 빌드하기 (develop 브랜치) if: github.ref == 'refs/heads/develop' - run: ./gradlew clean build -PspringProfile=dev --warning-mode all --scan + run: ./gradlew clean bootJar -PspringProfile=dev --warning-mode all --scan - name: 빌드된 파일 이름 변경 run: mv ./build/libs/*SNAPSHOT.jar ./project.jar From 747cdeea66351152c585c393bbcd8ad6ac72511d Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Wed, 18 Sep 2024 05:08:19 +0900 Subject: [PATCH 294/371] =?UTF-8?q?docs:=20git=20actions=20yml=20=ED=8C=8C?= =?UTF-8?q?=EC=9D=BC=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/deploy.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 55abbf60..5e8e24f4 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -38,11 +38,11 @@ jobs: - name: 테스트 및 빌드하기 (main 브랜치) if: github.ref == 'refs/heads/main' - run: ./gradlew clean bootJar -PspringProfile=prod --warning-mode all --scan + run: ./gradlew clean build -PspringProfile=prod --warning-mode all --scan - name: 테스트 및 빌드하기 (develop 브랜치) if: github.ref == 'refs/heads/develop' - run: ./gradlew clean bootJar -PspringProfile=dev --warning-mode all --scan + run: ./gradlew clean build -PspringProfile=dev --warning-mode all --scan - name: 빌드된 파일 이름 변경 run: mv ./build/libs/*SNAPSHOT.jar ./project.jar From 1ddcc416434634c2717588f69109f132b970c718 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Wed, 18 Sep 2024 13:32:24 +0900 Subject: [PATCH 295/371] =?UTF-8?q?docs:=20git=20actions=20yml=20=ED=8C=8C?= =?UTF-8?q?=EC=9D=BC=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/deploy.yml | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 5e8e24f4..5d56c368 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -21,10 +21,11 @@ jobs: - name: application.yml 파일 만들기 run: | - echo "${{ secrets.APPLICATION_YML }}" > ./src/main/resources/application.yml - echo "${{ secrets.APPLICATION_DEV }}" > ./src/main/resources/application-dev.yml - echo "${{ secrets.APPLICATION_PROD }}" > ./src/main/resources/application-prod.yml - echo "${{ secrets.APPLICATION_LOCAL }}" > ./src/main/resources/application-local.yml + mkdir -p ./src/main/resources + echo "${{ secrets.APPLICATION_YML }}" | base64 --decode > ./src/main/resources/application.yml + echo "${{ secrets.APPLICATION_DEV }}" | base64 --decode > ./src/main/resources/application-dev.yml + echo "${{ secrets.APPLICATION_PROD }}" | base64 --decode > ./src/main/resources/application-prod.yml + echo "${{ secrets.APPLICATION_LOCAL }}" | base64 --decode > ./src/main/resources/application-local.yml # - name: sql 파일 만들기 # run: | From 34fcfa9a1e8e4a37f70d5ab527dfe80f7c4dbb1e Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Wed, 18 Sep 2024 13:33:42 +0900 Subject: [PATCH 296/371] =?UTF-8?q?docs:=20git=20actions=20yml=20=ED=8C=8C?= =?UTF-8?q?=EC=9D=BC=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/deploy.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 5d56c368..b6266064 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -22,10 +22,10 @@ jobs: - name: application.yml 파일 만들기 run: | mkdir -p ./src/main/resources - echo "${{ secrets.APPLICATION_YML }}" | base64 --decode > ./src/main/resources/application.yml - echo "${{ secrets.APPLICATION_DEV }}" | base64 --decode > ./src/main/resources/application-dev.yml - echo "${{ secrets.APPLICATION_PROD }}" | base64 --decode > ./src/main/resources/application-prod.yml - echo "${{ secrets.APPLICATION_LOCAL }}" | base64 --decode > ./src/main/resources/application-local.yml + echo "${{ secrets.APPLICATION_YML }}" > ./src/main/resources/application.yml + echo "${{ secrets.APPLICATION_DEV }}" > ./src/main/resources/application-dev.yml + echo "${{ secrets.APPLICATION_PROD }}" > ./src/main/resources/application-prod.yml + echo "${{ secrets.APPLICATION_LOCAL }}" > ./src/main/resources/application-local.yml # - name: sql 파일 만들기 # run: | From 3d1269c01daed778ecc707034a0c1c9d8f1874cb Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Wed, 18 Sep 2024 13:53:11 +0900 Subject: [PATCH 297/371] =?UTF-8?q?fix:=20=EB=AA=A8=EC=A7=91=20=EC=A4=91?= =?UTF-8?q?=20=EC=B2=B4=ED=81=AC=20=ED=95=B4=EC=A0=9C=ED=96=88=EC=9D=84=20?= =?UTF-8?q?=EB=95=8C=20=EB=A7=88=EA=B0=90=20=EC=9D=BC=EC=9D=B4=20=EC=A7=80?= =?UTF-8?q?=EB=82=9C=20=EA=B2=83=EC=9D=B4=20=EB=B3=B4=EC=9D=B4=EC=A7=80=20?= =?UTF-8?q?=EC=95=8A=EB=8A=94=20=EC=98=A4=EB=A5=98=20=EC=88=98=EC=A0=95?= =?UTF-8?q?=ED=95=98=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../gathering/repository/GatheringRepositoryImpl.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryImpl.java b/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryImpl.java index d7151223..61d7b28a 100644 --- a/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryImpl.java +++ b/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryImpl.java @@ -279,8 +279,8 @@ public List getGatheringLikeCountFromCreatedIn3(Long use private BooleanBuilder makeWhereSQL(GatheringPageRequest gatheringPageRequest) { BooleanBuilder whereClause = new BooleanBuilder(); - whereClause.and(gathering.isDeleted.eq(Boolean.FALSE).and(gathering.deadline.after(LocalDateTime.now()))); - + whereClause.and(gathering.isDeleted.eq(Boolean.FALSE)); +// whereClause.and(gathering.deadline.after(LocalDateTime.now())); if (Objects.nonNull(gatheringPageRequest.getCategory())) { whereClause.and(gathering.gatheringCategory.id.eq(gatheringPageRequest.getCategory())); } From 4ece6fed9f45200bdf227ace38c104c4e9bc4634 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Wed, 18 Sep 2024 13:53:33 +0900 Subject: [PATCH 298/371] =?UTF-8?q?fix:=20=EC=A2=8B=EC=95=84=EC=9A=94=20?= =?UTF-8?q?=EB=A1=9C=EC=A7=81=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../information/repository/InformationRepositoryImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/solitour_backend/solitour/information/repository/InformationRepositoryImpl.java b/src/main/java/solitour_backend/solitour/information/repository/InformationRepositoryImpl.java index e1e083a0..a19e228f 100644 --- a/src/main/java/solitour_backend/solitour/information/repository/InformationRepositoryImpl.java +++ b/src/main/java/solitour_backend/solitour/information/repository/InformationRepositoryImpl.java @@ -286,7 +286,7 @@ private BooleanExpression isUserGreatInformation(Long userId) { .when(JPAExpressions.selectOne() .from(greatInformation) .where(greatInformation.information.id.eq(information.id) - .and(greatInformation.information.id.eq(userId))) + .and(greatInformation.user.id.eq(userId))) .exists()) .then(true) .otherwise(false); From 4ea0329f0cb5d46d2fdf56548515019f68228a09 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Wed, 18 Sep 2024 13:53:49 +0900 Subject: [PATCH 299/371] =?UTF-8?q?fix:=20=EC=9E=91=EC=84=B1=EC=9E=90=20?= =?UTF-8?q?=EC=9D=B4=EB=A6=84=EC=9D=B4=20=EC=95=84=EB=8B=88=EB=9D=BC=20?= =?UTF-8?q?=EB=8B=89=EB=84=A4=EC=9E=84=EC=9C=BC=EB=A1=9C=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 --- .../solitour_backend/solitour/user/dto/UserPostingResponse.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/solitour_backend/solitour/user/dto/UserPostingResponse.java b/src/main/java/solitour_backend/solitour/user/dto/UserPostingResponse.java index b6ca355d..55324267 100644 --- a/src/main/java/solitour_backend/solitour/user/dto/UserPostingResponse.java +++ b/src/main/java/solitour_backend/solitour/user/dto/UserPostingResponse.java @@ -8,5 +8,5 @@ public class UserPostingResponse { private Long id; - private String name; + private String nickname; } From ad6d5908818359545f4345ee1f96e7163f4056bb Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Wed, 18 Sep 2024 14:16:52 +0900 Subject: [PATCH 300/371] =?UTF-8?q?docs:=20ci/cd=20yml=20=ED=8C=8C?= =?UTF-8?q?=EC=9D=BC=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/deploy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index b6266064..8ae5f58f 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -43,7 +43,7 @@ jobs: - name: 테스트 및 빌드하기 (develop 브랜치) if: github.ref == 'refs/heads/develop' - run: ./gradlew clean build -PspringProfile=dev --warning-mode all --scan + run: ./gradlew clean bootJar -PspringProfile=dev --warning-mode all --scan - name: 빌드된 파일 이름 변경 run: mv ./build/libs/*SNAPSHOT.jar ./project.jar From 9bea1dfb84e7e0ceb148232792a2d9b6c98efd63 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Wed, 18 Sep 2024 14:30:16 +0900 Subject: [PATCH 301/371] =?UTF-8?q?docs:=20ci/cd=20yml=20=ED=8C=8C?= =?UTF-8?q?=EC=9D=BC=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/deploy.yml | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 8ae5f58f..7f5fc232 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -58,6 +58,7 @@ jobs: target: /home/ubuntu/solitour-server/tobe - name: SSH로 EC2 접속 + if: github.ref == 'refs/heads/main' uses: appleboy/ssh-action@v1.0.3 with: host: ${{ secrets.EC2_HOST }} @@ -70,6 +71,22 @@ jobs: mv /home/ubuntu/solitour-server/tobe/project.jar /home/ubuntu/solitour-server/current/project.jar cd /home/ubuntu/solitour-server/current sudo fuser -k -n tcp 8080 || true - nohup java -jar project.jar > ./output.log 2>&1 & + nohup java -jar -Dspring.profiles.active=prod project.jar & > ./output.log 2>&1 & rm -rf /home/ubuntu/solitour-server/tobe + - name: SSH로 EC2 접속 + if: github.ref == 'refs/heads/develop' + uses: appleboy/ssh-action@v1.0.3 + with: + host: ${{ secrets.EC2_HOST }} + username: ${{ secrets.EC2_USERNAME }} + key: ${{ secrets.EC2_PRIVATE_KEY }} + script_stop: true + script: | + rm -rf /home/ubuntu/solitour-server/current + mkdir /home/ubuntu/solitour-server/current + mv /home/ubuntu/solitour-server/tobe/project.jar /home/ubuntu/solitour-server/current/project.jar + cd /home/ubuntu/solitour-server/current + sudo fuser -k -n tcp 8080 || true + nohup java -jar -Dspring.profiles.active=dev project.jar & > ./output.log 2>&1 & + rm -rf /home/ubuntu/solitour-server/tobe From 681fff4fc143eb36a1a748e51aaf74eb3df25bad Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Wed, 18 Sep 2024 14:37:19 +0900 Subject: [PATCH 302/371] =?UTF-8?q?docs:=20ci/cd=20yml=20=ED=8C=8C?= =?UTF-8?q?=EC=9D=BC=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/deploy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 7f5fc232..9aff7d61 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -88,5 +88,5 @@ jobs: mv /home/ubuntu/solitour-server/tobe/project.jar /home/ubuntu/solitour-server/current/project.jar cd /home/ubuntu/solitour-server/current sudo fuser -k -n tcp 8080 || true - nohup java -jar -Dspring.profiles.active=dev project.jar & > ./output.log 2>&1 & + nohup java -jar -Dspring.profiles.active=dev project.jar > ./output.log 2>&1 & rm -rf /home/ubuntu/solitour-server/tobe From b39abf9c3473cc217fde01b3fd473fb57c37ff77 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Wed, 18 Sep 2024 14:39:21 +0900 Subject: [PATCH 303/371] =?UTF-8?q?docs:=20ci/cd=20yml=20=ED=8C=8C?= =?UTF-8?q?=EC=9D=BC=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/deploy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 9aff7d61..b031a4ab 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -43,7 +43,7 @@ jobs: - name: 테스트 및 빌드하기 (develop 브랜치) if: github.ref == 'refs/heads/develop' - run: ./gradlew clean bootJar -PspringProfile=dev --warning-mode all --scan + run: ./gradlew clean build -PspringProfile=dev --warning-mode all --scan - name: 빌드된 파일 이름 변경 run: mv ./build/libs/*SNAPSHOT.jar ./project.jar From 3abb20ded9e6738e4f25e6791555c598361e0d04 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Wed, 18 Sep 2024 14:40:56 +0900 Subject: [PATCH 304/371] =?UTF-8?q?docs:=20ci/cd=20yml=20=ED=8C=8C?= =?UTF-8?q?=EC=9D=BC=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/deploy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index b031a4ab..c63b8f14 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -43,7 +43,7 @@ jobs: - name: 테스트 및 빌드하기 (develop 브랜치) if: github.ref == 'refs/heads/develop' - run: ./gradlew clean build -PspringProfile=dev --warning-mode all --scan + run: ./gradlew clean build --warning-mode all --scan - name: 빌드된 파일 이름 변경 run: mv ./build/libs/*SNAPSHOT.jar ./project.jar From df44c0d44025b4674ee91467d0edba2f3cade8fd Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Wed, 18 Sep 2024 14:51:55 +0900 Subject: [PATCH 305/371] =?UTF-8?q?docs:=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20h?= =?UTF-8?q?2=20=EB=8D=B0=EC=9D=B4=ED=84=B0=EB=B2=A0=EC=9D=B4=EC=8A=A4=20?= =?UTF-8?q?=EC=84=A4=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/deploy.yml | 3 ++- build.gradle | 2 ++ .../solitour_backend/solitour/SolitourApplicationTests.java | 2 ++ 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index c63b8f14..98b4f76f 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -26,6 +26,7 @@ jobs: echo "${{ secrets.APPLICATION_DEV }}" > ./src/main/resources/application-dev.yml echo "${{ secrets.APPLICATION_PROD }}" > ./src/main/resources/application-prod.yml echo "${{ secrets.APPLICATION_LOCAL }}" > ./src/main/resources/application-local.yml + echo "${{ secrets.APPLICATION_TEST }}" > ./src/main/resources/application-test.yml # - name: sql 파일 만들기 # run: | @@ -43,7 +44,7 @@ jobs: - name: 테스트 및 빌드하기 (develop 브랜치) if: github.ref == 'refs/heads/develop' - run: ./gradlew clean build --warning-mode all --scan + run: ./gradlew clean build -PspringProfile=dev --warning-mode all --scan - name: 빌드된 파일 이름 변경 run: mv ./build/libs/*SNAPSHOT.jar ./project.jar diff --git a/build.gradle b/build.gradle index 55c7b001..b9e77600 100644 --- a/build.gradle +++ b/build.gradle @@ -54,6 +54,8 @@ dependencies { annotationProcessor "jakarta.persistence:jakarta.persistence-api" runtimeOnly 'com.mysql:mysql-connector-j' + testCompileOnly 'com.h2database:h2' + testImplementation 'com.h2database:h2' testImplementation 'org.springframework.boot:spring-boot-starter-test' diff --git a/src/test/java/solitour_backend/solitour/SolitourApplicationTests.java b/src/test/java/solitour_backend/solitour/SolitourApplicationTests.java index eaf5bafa..aac74b18 100644 --- a/src/test/java/solitour_backend/solitour/SolitourApplicationTests.java +++ b/src/test/java/solitour_backend/solitour/SolitourApplicationTests.java @@ -2,8 +2,10 @@ import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.ActiveProfiles; @SpringBootTest +@ActiveProfiles("test") class SolitourApplicationTests { @Test From 29703ae88dcfc5d21aa705b5454509db36694a61 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Wed, 18 Sep 2024 15:00:21 +0900 Subject: [PATCH 306/371] =?UTF-8?q?docs:=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20h?= =?UTF-8?q?2=20=EB=8D=B0=EC=9D=B4=ED=84=B0=EB=B2=A0=EC=9D=B4=EC=8A=A4=20?= =?UTF-8?q?=EC=84=A4=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index b9e77600..8f0f5cec 100644 --- a/build.gradle +++ b/build.gradle @@ -54,7 +54,7 @@ dependencies { annotationProcessor "jakarta.persistence:jakarta.persistence-api" runtimeOnly 'com.mysql:mysql-connector-j' - testCompileOnly 'com.h2database:h2' + testImplementation 'com.h2database:h2' testImplementation 'org.springframework.boot:spring-boot-starter-test' From 84dfad0b3accd6e67ee3534e4904e677107b3a9c Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Wed, 18 Sep 2024 15:06:19 +0900 Subject: [PATCH 307/371] =?UTF-8?q?docs:=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20h?= =?UTF-8?q?2=20=EB=8D=B0=EC=9D=B4=ED=84=B0=EB=B2=A0=EC=9D=B4=EC=8A=A4=20?= =?UTF-8?q?=EC=84=A4=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 3 --- 1 file changed, 3 deletions(-) diff --git a/build.gradle b/build.gradle index 8f0f5cec..af903924 100644 --- a/build.gradle +++ b/build.gradle @@ -56,11 +56,8 @@ dependencies { runtimeOnly 'com.mysql:mysql-connector-j' testImplementation 'com.h2database:h2' - testImplementation 'org.springframework.boot:spring-boot-starter-test' - testImplementation 'org.springframework.restdocs:spring-restdocs-mockmvc' - testRuntimeOnly 'org.junit.platform:junit-platform-launcher' } From 82aed7d08a64aea358646b8d10d9ed5bcf036338 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Wed, 18 Sep 2024 15:12:09 +0900 Subject: [PATCH 308/371] =?UTF-8?q?docs:=20test=20=EC=99=80=20build=20?= =?UTF-8?q?=EB=B6=84=EB=A6=AC=20=EC=84=A4=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/deploy.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 98b4f76f..f209a875 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -44,7 +44,11 @@ jobs: - name: 테스트 및 빌드하기 (develop 브랜치) if: github.ref == 'refs/heads/develop' - run: ./gradlew clean build -PspringProfile=dev --warning-mode all --scan + run: | + ./gradlew clean test -DspringProfile=test + ./gradlew build -x test -DspringProfile=dev --warning-mode all --scan + + - name: 빌드된 파일 이름 변경 run: mv ./build/libs/*SNAPSHOT.jar ./project.jar From ef8cc3ee5dd2ac393bbd16eaee68d82a1e6f5594 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Wed, 18 Sep 2024 15:20:58 +0900 Subject: [PATCH 309/371] docs: test schema.sql --- src/main/resources/schema_test.sql | 254 +++++++++++++++++++++++++++++ 1 file changed, 254 insertions(+) create mode 100644 src/main/resources/schema_test.sql diff --git a/src/main/resources/schema_test.sql b/src/main/resources/schema_test.sql new file mode 100644 index 00000000..b015300e --- /dev/null +++ b/src/main/resources/schema_test.sql @@ -0,0 +1,254 @@ +DROP TABLE IF EXISTS great_information; +DROP TABLE IF EXISTS great_gathering; +DROP TABLE IF EXISTS book_mark_information; +DROP TABLE IF EXISTS book_mark_gathering; +DROP TABLE IF EXISTS info_tag; +DROP TABLE IF EXISTS gathering_tag; +DROP TABLE IF EXISTS comment; +DROP TABLE IF EXISTS image; +DROP TABLE IF EXISTS information; +DROP TABLE IF EXISTS gathering_applicants; +DROP TABLE IF EXISTS gathering; +DROP TABLE IF EXISTS tag; +DROP TABLE IF EXISTS category; +DROP TABLE IF EXISTS gathering_category; +DROP TABLE IF EXISTS zone_category; +DROP TABLE IF EXISTS place; +DROP TABLE IF EXISTS token; +DROP TABLE IF EXISTS banner; +DROP TABLE IF EXISTS notice; +DROP TABLE IF EXISTS qna_message; +DROP TABLE IF EXISTS qna; +DROP TABLE IF EXISTS user; +DROP TABLE IF EXISTS user_image; +DROP TABLE IF EXISTS diary_day_content; +DROP TABLE IF EXISTS diary; + +CREATE TABLE user_image ( + user_image_id BIGINT NOT NULL IDENTITY PRIMARY KEY, + user_image_address VARCHAR(200) NOT NULL, + user_image_created_date DATE NOT NULL +); + +CREATE TABLE user ( + user_id BIGINT NOT NULL IDENTITY PRIMARY KEY, + user_image_id BIGINT NOT NULL, + user_status_id VARCHAR(20) NOT NULL, + user_oauth_id VARCHAR(100), + provider VARCHAR(10), + user_nickname VARCHAR(30), + user_name VARCHAR(20), + user_age INT, + user_sex VARCHAR(10), + user_email VARCHAR(30), + user_phone_number VARCHAR(13), + is_admin BOOLEAN NOT NULL, + user_latest_login_at DATETIME, + user_created_at DATETIME NOT NULL, + user_deleted_at DATETIME, + FOREIGN KEY (user_image_id) REFERENCES user_image (user_image_id) +); + +CREATE TABLE token ( + token_id BIGINT NOT NULL IDENTITY PRIMARY KEY, + user_id BIGINT NOT NULL, + refresh_token VARCHAR(250) NOT NULL, + FOREIGN KEY (user_id) REFERENCES user (user_id) +); + +CREATE TABLE place ( + place_id BIGINT NOT NULL IDENTITY PRIMARY KEY, + place_search_id VARCHAR(30), + place_name VARCHAR(30) NOT NULL, + place_x_axis DECIMAL(10, 7) NOT NULL, + place_y_axis DECIMAL(10, 7) NOT NULL, + place_address VARCHAR(50) NOT NULL +); + +CREATE TABLE zone_category ( + zone_category_id BIGINT NOT NULL IDENTITY PRIMARY KEY, + parent_zone_category_id BIGINT, + zone_category_name VARCHAR(20) NOT NULL, + FOREIGN KEY (parent_zone_category_id) REFERENCES zone_category (zone_category_id) +); + +CREATE TABLE category ( + category_id BIGINT NOT NULL IDENTITY PRIMARY KEY, + parent_category_id BIGINT, + category_name VARCHAR(20) NOT NULL, + FOREIGN KEY (parent_category_id) REFERENCES category (category_id) +); + +CREATE TABLE gathering_category ( + gathering_category_id BIGINT NOT NULL IDENTITY PRIMARY KEY, + gathering_category_name VARCHAR(20) NOT NULL +); + +CREATE TABLE information ( + information_id BIGINT NOT NULL IDENTITY PRIMARY KEY, + category_id BIGINT NOT NULL, + zone_category_id BIGINT NOT NULL, + user_id BIGINT NOT NULL, + place_id BIGINT NOT NULL, + information_title VARCHAR(50) NOT NULL, + information_address VARCHAR(50) NOT NULL, + information_created_date DATETIME NOT NULL, + information_view_count INT NOT NULL DEFAULT 0, + information_content TEXT, + information_tip TEXT, + FOREIGN KEY (category_id) REFERENCES category (category_id), + FOREIGN KEY (zone_category_id) REFERENCES zone_category (zone_category_id), + FOREIGN KEY (user_id) REFERENCES user (user_id), + FOREIGN KEY (place_id) REFERENCES place (place_id) +); + +CREATE TABLE gathering ( + gathering_id BIGINT NOT NULL IDENTITY PRIMARY KEY, + user_id BIGINT NOT NULL, + zone_category_id BIGINT NOT NULL, + gathering_category_id BIGINT NOT NULL, + place_id BIGINT NOT NULL, + gathering_title VARCHAR(50), + gathering_content TEXT, + gathering_person_count INT, + gathering_view_count INT, + gathering_created_at DATETIME, + gathering_edited_at DATETIME, + gathering_schedule_start_date DATETIME, + gathering_schedule_end_date DATETIME, + gathering_is_finish BOOLEAN, + gathering_deadline DATETIME, + gathering_allowed_sex VARCHAR(30) NOT NULL, + gathering_start_age INT NOT NULL, + gathering_end_age INT NOT NULL, + gathering_is_deleted BOOLEAN NOT NULL DEFAULT FALSE, + gathering_open_chatting_url VARCHAR(255), + FOREIGN KEY (user_id) REFERENCES user (user_id), + FOREIGN KEY (gathering_category_id) REFERENCES gathering_category (gathering_category_id), + FOREIGN KEY (zone_category_id) REFERENCES zone_category (zone_category_id), + FOREIGN KEY (place_id) REFERENCES place (place_id) +); + +CREATE TABLE gathering_applicants ( + gathering_applicants_id BIGINT NOT NULL IDENTITY PRIMARY KEY, + gathering_id BIGINT NOT NULL, + user_id BIGINT NOT NULL, + gathering_applicants_state VARCHAR(20) NOT NULL, + FOREIGN KEY (gathering_id) REFERENCES gathering (gathering_id), + FOREIGN KEY (user_id) REFERENCES user (user_id) +); + +CREATE TABLE image ( + image_id BIGINT NOT NULL IDENTITY PRIMARY KEY, + image_status_id VARCHAR(20) NOT NULL, + information_id BIGINT NOT NULL, + image_address VARCHAR(200) NOT NULL, + image_created_date DATE NOT NULL, + FOREIGN KEY (information_id) REFERENCES information (information_id) +); + +CREATE TABLE great_information ( + great_information_id BIGINT NOT NULL IDENTITY PRIMARY KEY, + user_id BIGINT NOT NULL, + information_id BIGINT NOT NULL, + FOREIGN KEY (user_id) REFERENCES user (user_id), + FOREIGN KEY (information_id) REFERENCES information (information_id), + UNIQUE (user_id, information_id) +); + +CREATE TABLE great_gathering ( + great_gathering_id BIGINT NOT NULL IDENTITY PRIMARY KEY, + user_id BIGINT NOT NULL, + gathering_id BIGINT NOT NULL, + FOREIGN KEY (user_id) REFERENCES user (user_id), + FOREIGN KEY (gathering_id) REFERENCES gathering (gathering_id), + UNIQUE (user_id, gathering_id) +); + +CREATE TABLE book_mark_information ( + book_mark_information_id BIGINT NOT NULL IDENTITY PRIMARY KEY, + user_id BIGINT NOT NULL, + information_id BIGINT NOT NULL, + FOREIGN KEY (user_id) REFERENCES user (user_id), + FOREIGN KEY (information_id) REFERENCES information (information_id), + UNIQUE (user_id, information_id) +); + +CREATE TABLE book_mark_gathering ( + book_mark_gathering_id BIGINT NOT NULL IDENTITY PRIMARY KEY, + user_id BIGINT NOT NULL, + gathering_id BIGINT NOT NULL, + FOREIGN KEY (user_id) REFERENCES user (user_id), + FOREIGN KEY (gathering_id) REFERENCES gathering (gathering_id), + UNIQUE (user_id, gathering_id) +); + +CREATE TABLE tag ( + tag_id BIGINT NOT NULL IDENTITY PRIMARY KEY, + tag_name VARCHAR(16) NOT NULL +); + +CREATE TABLE info_tag ( + info_tag_id BIGINT NOT NULL IDENTITY PRIMARY KEY, + tag_id BIGINT NOT NULL, + information_id BIGINT NOT NULL, + FOREIGN KEY (tag_id) REFERENCES tag (tag_id), + FOREIGN KEY (information_id) REFERENCES information (information_id), + UNIQUE (tag_id, information_id) +); + +CREATE TABLE gathering_tag ( + gathering_tag_id BIGINT NOT NULL IDENTITY PRIMARY KEY, + tag_id BIGINT NOT NULL, + gathering_id BIGINT NOT NULL, + FOREIGN KEY (tag_id) REFERENCES tag (tag_id), + FOREIGN KEY (gathering_id) REFERENCES gathering (gathering_id), + UNIQUE (tag_id, gathering_id) +); + +CREATE TABLE banner ( + id BIGINT NOT NULL IDENTITY PRIMARY KEY, + name VARCHAR(255) NOT NULL, + url VARCHAR(255) NOT NULL +); + +CREATE TABLE qna ( + qna_id BIGINT NOT NULL IDENTITY PRIMARY KEY, + qna_category_name VARCHAR(255), + qna_created_at DATETIME, + qna_status VARCHAR(255), + qna_title VARCHAR(255), + qna_updated_at DATETIME, + user_id BIGINT, + FOREIGN KEY (user_id) REFERENCES user (user_id) +); + +CREATE TABLE qna_message ( + id BIGINT NOT NULL IDENTITY PRIMARY KEY, + qna_message_content TEXT, + qna_message_created_at DATETIME, + qna_message_user_id BIGINT, + qna_id BIGINT, + FOREIGN KEY (qna_id) REFERENCES qna (qna_id), + FOREIGN KEY (qna_message_user_id) REFERENCES user (user_id) +); + +CREATE TABLE notice ( + notice_id BIGINT NOT NULL IDENTITY PRIMARY KEY, + notice_category_name VARCHAR(255), + notice_content TEXT, + notice_created_at DATETIME, + notice_is_deleted BOOLEAN DEFAULT FALSE, + notice_title VARCHAR(255) +); + +CREATE TABLE diary ( + diary_id BIGINT NOT NULL IDENTITY PRIMARY KEY, + user_id BIGINT NOT NULL, + diary_title VARCHAR(50) NOT NULL, + diary_title_image VARCHAR(200) DEFAULT NULL, + diary_start_date DATETIME NOT NULL, + diary_end_date DATETIME NOT NULL, + diary_created_date DATETIME NOT NULL, + diary_edited_date DATETIME DEFAULT NULL +); \ No newline at end of file From ef91ecb7235bf06720f5956b4a5ff094c0116a94 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Wed, 18 Sep 2024 15:23:30 +0900 Subject: [PATCH 310/371] docs: yml --- .github/workflows/deploy.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index f209a875..9d82c3ff 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -47,6 +47,7 @@ jobs: run: | ./gradlew clean test -DspringProfile=test ./gradlew build -x test -DspringProfile=dev --warning-mode all --scan + From 16f9d8b5e2f4434625b8ad3bbfe6412b95ace7f7 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Wed, 18 Sep 2024 15:25:46 +0900 Subject: [PATCH 311/371] docs: yml --- .github/workflows/deploy.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 9d82c3ff..43fb946d 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -45,8 +45,8 @@ jobs: - name: 테스트 및 빌드하기 (develop 브랜치) if: github.ref == 'refs/heads/develop' run: | - ./gradlew clean test -DspringProfile=test - ./gradlew build -x test -DspringProfile=dev --warning-mode all --scan + ./gradlew clean test -PspringProfile=test --warning-mode all --scan + ./gradlew build -x test -PspringProfile=dev --warning-mode all --scan From 6cc2c1d78ebce0bf9160966c64b5b2c01e214c64 Mon Sep 17 00:00:00 2001 From: Donghun Won Date: Wed, 18 Sep 2024 15:30:41 +0900 Subject: [PATCH 312/371] =?UTF-8?q?Fix=20:=20test=20schema=20=ED=8C=8C?= =?UTF-8?q?=EC=9D=BC=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/deploy.yml | 6 +++--- .../solitour_backend/solitour/SolitourApplicationTests.java | 2 ++ 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index f209a875..58937946 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -28,9 +28,9 @@ jobs: echo "${{ secrets.APPLICATION_LOCAL }}" > ./src/main/resources/application-local.yml echo "${{ secrets.APPLICATION_TEST }}" > ./src/main/resources/application-test.yml -# - name: sql 파일 만들기 -# run: | -# echo "${{ secrets.SCHEMA }}" > ./src/main/resources/schema.sql + - name: sql 파일 만들기 + run: | + echo "${{ secrets.TEST_SCHEMA }}" > ./src/main/resources/test_schema.sql # echo "${{ secrets.CATEGORY }}" > ./src/main/resources/category.sql # echo "${{ secrets.GATHERING_CATEGORY }}" > ./src/main/resources/gathering_category.sql # echo "${{ secrets.ZONE_CATEGORY }}" > ./src/main/resources/zone_category.sql diff --git a/src/test/java/solitour_backend/solitour/SolitourApplicationTests.java b/src/test/java/solitour_backend/solitour/SolitourApplicationTests.java index aac74b18..b8fbd10d 100644 --- a/src/test/java/solitour_backend/solitour/SolitourApplicationTests.java +++ b/src/test/java/solitour_backend/solitour/SolitourApplicationTests.java @@ -1,10 +1,12 @@ package solitour_backend.solitour; import org.junit.jupiter.api.Test; +import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.ActiveProfiles; @SpringBootTest +@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.ANY) @ActiveProfiles("test") class SolitourApplicationTests { From 0f96c30f9ea052cea6078094eff023dc0bd1341d Mon Sep 17 00:00:00 2001 From: Donghun Won Date: Wed, 18 Sep 2024 15:32:24 +0900 Subject: [PATCH 313/371] =?UTF-8?q?Fix=20:=20=ED=85=8C=EC=8A=A4=ED=8A=B8?= =?UTF-8?q?=20=EC=8A=A4=ED=82=A4=EB=A7=88=20=EC=97=85=EB=A1=9C=EB=93=9C=20?= =?UTF-8?q?=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/deploy.yml | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 3cc84dc4..f209a875 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -28,9 +28,9 @@ jobs: echo "${{ secrets.APPLICATION_LOCAL }}" > ./src/main/resources/application-local.yml echo "${{ secrets.APPLICATION_TEST }}" > ./src/main/resources/application-test.yml - - name: sql 파일 만들기 - run: | - echo "${{ secrets.TEST_SCHEMA }}" > ./src/main/resources/test_schema.sql +# - name: sql 파일 만들기 +# run: | +# echo "${{ secrets.SCHEMA }}" > ./src/main/resources/schema.sql # echo "${{ secrets.CATEGORY }}" > ./src/main/resources/category.sql # echo "${{ secrets.GATHERING_CATEGORY }}" > ./src/main/resources/gathering_category.sql # echo "${{ secrets.ZONE_CATEGORY }}" > ./src/main/resources/zone_category.sql @@ -45,9 +45,8 @@ jobs: - name: 테스트 및 빌드하기 (develop 브랜치) if: github.ref == 'refs/heads/develop' run: | - ./gradlew clean test -PspringProfile=test --warning-mode all --scan - ./gradlew build -x test -PspringProfile=dev --warning-mode all --scan - + ./gradlew clean test -DspringProfile=test + ./gradlew build -x test -DspringProfile=dev --warning-mode all --scan From 6abf284b45f01797c931a0d9497f5f8e02d3f1f9 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Wed, 18 Sep 2024 15:36:05 +0900 Subject: [PATCH 314/371] =?UTF-8?q?docs:=20h2=20schema.sql=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 --- .github/workflows/deploy.yml | 4 +- gradlew | 249 --------- src/main/resources/schema_test.sql | 507 +++++++++--------- .../solitour/SolitourApplicationTests.java | 2 +- 4 files changed, 257 insertions(+), 505 deletions(-) delete mode 100644 gradlew diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index f209a875..de6f56c7 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -45,8 +45,8 @@ jobs: - name: 테스트 및 빌드하기 (develop 브랜치) if: github.ref == 'refs/heads/develop' run: | - ./gradlew clean test -DspringProfile=test - ./gradlew build -x test -DspringProfile=dev --warning-mode all --scan + ./gradlew clean test -PspringProfile=test + ./gradlew build -x test -PspringProfile=dev --warning-mode all --scan diff --git a/gradlew b/gradlew deleted file mode 100644 index b740cf13..00000000 --- a/gradlew +++ /dev/null @@ -1,249 +0,0 @@ -#!/bin/sh - -# -# Copyright © 2015-2021 the original authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -############################################################################## -# -# Gradle start up script for POSIX generated by Gradle. -# -# Important for running: -# -# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is -# noncompliant, but you have some other compliant shell such as ksh or -# bash, then to run this script, type that shell name before the whole -# command line, like: -# -# ksh Gradle -# -# Busybox and similar reduced shells will NOT work, because this script -# requires all of these POSIX shell features: -# * functions; -# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», -# «${var#prefix}», «${var%suffix}», and «$( cmd )»; -# * compound commands having a testable exit status, especially «case»; -# * various built-in commands including «command», «set», and «ulimit». -# -# Important for patching: -# -# (2) This script targets any POSIX shell, so it avoids extensions provided -# by Bash, Ksh, etc; in particular arrays are avoided. -# -# The "traditional" practice of packing multiple parameters into a -# space-separated string is a well documented source of bugs and security -# problems, so this is (mostly) avoided, by progressively accumulating -# options in "$@", and eventually passing that to Java. -# -# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, -# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; -# see the in-line comments for details. -# -# There are tweaks for specific operating systems such as AIX, CygWin, -# Darwin, MinGW, and NonStop. -# -# (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt -# within the Gradle project. -# -# You can find Gradle at https://github.com/gradle/gradle/. -# -############################################################################## - -# Attempt to set APP_HOME - -# Resolve links: $0 may be a link -app_path=$0 - -# Need this for daisy-chained symlinks. -while - APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path - [ -h "$app_path" ] -do - ls=$( ls -ld "$app_path" ) - link=${ls#*' -> '} - case $link in #( - /*) app_path=$link ;; #( - *) app_path=$APP_HOME$link ;; - esac -done - -# This is normally unused -# shellcheck disable=SC2034 -APP_BASE_NAME=${0##*/} -# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit - -# Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD=maximum - -warn () { - echo "$*" -} >&2 - -die () { - echo - echo "$*" - echo - exit 1 -} >&2 - -# OS specific support (must be 'true' or 'false'). -cygwin=false -msys=false -darwin=false -nonstop=false -case "$( uname )" in #( - CYGWIN* ) cygwin=true ;; #( - Darwin* ) darwin=true ;; #( - MSYS* | MINGW* ) msys=true ;; #( - NONSTOP* ) nonstop=true ;; -esac - -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar - - -# Determine the Java command to use to start the JVM. -if [ -n "$JAVA_HOME" ] ; then - if [ -x "$JAVA_HOME/jre/sh/java" ] ; then - # IBM's JDK on AIX uses strange locations for the executables - JAVACMD=$JAVA_HOME/jre/sh/java - else - JAVACMD=$JAVA_HOME/bin/java - fi - if [ ! -x "$JAVACMD" ] ; then - die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -else - JAVACMD=java - if ! command -v java >/dev/null 2>&1 - then - die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -fi - -# Increase the maximum file descriptors if we can. -if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then - case $MAX_FD in #( - max*) - # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC2039,SC3045 - MAX_FD=$( ulimit -H -n ) || - warn "Could not query maximum file descriptor limit" - esac - case $MAX_FD in #( - '' | soft) :;; #( - *) - # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC2039,SC3045 - ulimit -n "$MAX_FD" || - warn "Could not set maximum file descriptor limit to $MAX_FD" - esac -fi - -# Collect all arguments for the java command, stacking in reverse order: -# * args from the command line -# * the main class name -# * -classpath -# * -D...appname settings -# * --module-path (only if needed) -# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. - -# For Cygwin or MSYS, switch paths to Windows format before running java -if "$cygwin" || "$msys" ; then - APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) - - JAVACMD=$( cygpath --unix "$JAVACMD" ) - - # Now convert the arguments - kludge to limit ourselves to /bin/sh - for arg do - if - case $arg in #( - -*) false ;; # don't mess with options #( - /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath - [ -e "$t" ] ;; #( - *) false ;; - esac - then - arg=$( cygpath --path --ignore --mixed "$arg" ) - fi - # Roll the args list around exactly as many times as the number of - # args, so each arg winds up back in the position where it started, but - # possibly modified. - # - # NB: a `for` loop captures its iteration list before it begins, so - # changing the positional parameters here affects neither the number of - # iterations, nor the values presented in `arg`. - shift # remove old arg - set -- "$@" "$arg" # push replacement arg - done -fi - - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' - -# Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, -# and any embedded shellness will be escaped. -# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be -# treated as '${Hostname}' itself on the command line. - -set -- \ - "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ - "$@" - -# Stop when "xargs" is not available. -if ! command -v xargs >/dev/null 2>&1 -then - die "xargs is not available" -fi - -# Use "xargs" to parse quoted args. -# -# With -n1 it outputs one arg per line, with the quotes and backslashes removed. -# -# In Bash we could simply go: -# -# readarray ARGS < <( xargs -n1 <<<"$var" ) && -# set -- "${ARGS[@]}" "$@" -# -# but POSIX shell has neither arrays nor command substitution, so instead we -# post-process each arg (as a line of input to sed) to backslash-escape any -# character that might be a shell metacharacter, then use eval to reverse -# that process (while maintaining the separation between arguments), and wrap -# the whole thing up as a single "set" statement. -# -# This will of course break if any of these variables contains a newline or -# an unmatched quote. -# - -eval "set -- $( - printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | - xargs -n1 | - sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | - tr '\n' ' ' - )" '"$@"' - -exec "$JAVACMD" "$@" diff --git a/src/main/resources/schema_test.sql b/src/main/resources/schema_test.sql index b015300e..b1b35768 100644 --- a/src/main/resources/schema_test.sql +++ b/src/main/resources/schema_test.sql @@ -1,254 +1,255 @@ -DROP TABLE IF EXISTS great_information; -DROP TABLE IF EXISTS great_gathering; -DROP TABLE IF EXISTS book_mark_information; -DROP TABLE IF EXISTS book_mark_gathering; -DROP TABLE IF EXISTS info_tag; -DROP TABLE IF EXISTS gathering_tag; -DROP TABLE IF EXISTS comment; -DROP TABLE IF EXISTS image; -DROP TABLE IF EXISTS information; -DROP TABLE IF EXISTS gathering_applicants; -DROP TABLE IF EXISTS gathering; -DROP TABLE IF EXISTS tag; -DROP TABLE IF EXISTS category; -DROP TABLE IF EXISTS gathering_category; -DROP TABLE IF EXISTS zone_category; -DROP TABLE IF EXISTS place; -DROP TABLE IF EXISTS token; -DROP TABLE IF EXISTS banner; -DROP TABLE IF EXISTS notice; -DROP TABLE IF EXISTS qna_message; -DROP TABLE IF EXISTS qna; -DROP TABLE IF EXISTS user; -DROP TABLE IF EXISTS user_image; -DROP TABLE IF EXISTS diary_day_content; -DROP TABLE IF EXISTS diary; - -CREATE TABLE user_image ( - user_image_id BIGINT NOT NULL IDENTITY PRIMARY KEY, - user_image_address VARCHAR(200) NOT NULL, - user_image_created_date DATE NOT NULL -); - -CREATE TABLE user ( - user_id BIGINT NOT NULL IDENTITY PRIMARY KEY, - user_image_id BIGINT NOT NULL, - user_status_id VARCHAR(20) NOT NULL, - user_oauth_id VARCHAR(100), - provider VARCHAR(10), - user_nickname VARCHAR(30), - user_name VARCHAR(20), - user_age INT, - user_sex VARCHAR(10), - user_email VARCHAR(30), - user_phone_number VARCHAR(13), - is_admin BOOLEAN NOT NULL, - user_latest_login_at DATETIME, - user_created_at DATETIME NOT NULL, - user_deleted_at DATETIME, - FOREIGN KEY (user_image_id) REFERENCES user_image (user_image_id) -); - -CREATE TABLE token ( - token_id BIGINT NOT NULL IDENTITY PRIMARY KEY, - user_id BIGINT NOT NULL, - refresh_token VARCHAR(250) NOT NULL, - FOREIGN KEY (user_id) REFERENCES user (user_id) -); - -CREATE TABLE place ( - place_id BIGINT NOT NULL IDENTITY PRIMARY KEY, - place_search_id VARCHAR(30), - place_name VARCHAR(30) NOT NULL, - place_x_axis DECIMAL(10, 7) NOT NULL, - place_y_axis DECIMAL(10, 7) NOT NULL, - place_address VARCHAR(50) NOT NULL -); - -CREATE TABLE zone_category ( - zone_category_id BIGINT NOT NULL IDENTITY PRIMARY KEY, - parent_zone_category_id BIGINT, - zone_category_name VARCHAR(20) NOT NULL, - FOREIGN KEY (parent_zone_category_id) REFERENCES zone_category (zone_category_id) -); - -CREATE TABLE category ( - category_id BIGINT NOT NULL IDENTITY PRIMARY KEY, - parent_category_id BIGINT, - category_name VARCHAR(20) NOT NULL, - FOREIGN KEY (parent_category_id) REFERENCES category (category_id) -); - -CREATE TABLE gathering_category ( - gathering_category_id BIGINT NOT NULL IDENTITY PRIMARY KEY, - gathering_category_name VARCHAR(20) NOT NULL -); - -CREATE TABLE information ( - information_id BIGINT NOT NULL IDENTITY PRIMARY KEY, - category_id BIGINT NOT NULL, - zone_category_id BIGINT NOT NULL, - user_id BIGINT NOT NULL, - place_id BIGINT NOT NULL, - information_title VARCHAR(50) NOT NULL, - information_address VARCHAR(50) NOT NULL, - information_created_date DATETIME NOT NULL, - information_view_count INT NOT NULL DEFAULT 0, - information_content TEXT, - information_tip TEXT, - FOREIGN KEY (category_id) REFERENCES category (category_id), - FOREIGN KEY (zone_category_id) REFERENCES zone_category (zone_category_id), - FOREIGN KEY (user_id) REFERENCES user (user_id), - FOREIGN KEY (place_id) REFERENCES place (place_id) -); - -CREATE TABLE gathering ( - gathering_id BIGINT NOT NULL IDENTITY PRIMARY KEY, - user_id BIGINT NOT NULL, - zone_category_id BIGINT NOT NULL, - gathering_category_id BIGINT NOT NULL, - place_id BIGINT NOT NULL, - gathering_title VARCHAR(50), - gathering_content TEXT, - gathering_person_count INT, - gathering_view_count INT, - gathering_created_at DATETIME, - gathering_edited_at DATETIME, - gathering_schedule_start_date DATETIME, - gathering_schedule_end_date DATETIME, - gathering_is_finish BOOLEAN, - gathering_deadline DATETIME, - gathering_allowed_sex VARCHAR(30) NOT NULL, - gathering_start_age INT NOT NULL, - gathering_end_age INT NOT NULL, - gathering_is_deleted BOOLEAN NOT NULL DEFAULT FALSE, - gathering_open_chatting_url VARCHAR(255), - FOREIGN KEY (user_id) REFERENCES user (user_id), - FOREIGN KEY (gathering_category_id) REFERENCES gathering_category (gathering_category_id), - FOREIGN KEY (zone_category_id) REFERENCES zone_category (zone_category_id), - FOREIGN KEY (place_id) REFERENCES place (place_id) -); - -CREATE TABLE gathering_applicants ( - gathering_applicants_id BIGINT NOT NULL IDENTITY PRIMARY KEY, - gathering_id BIGINT NOT NULL, - user_id BIGINT NOT NULL, - gathering_applicants_state VARCHAR(20) NOT NULL, - FOREIGN KEY (gathering_id) REFERENCES gathering (gathering_id), - FOREIGN KEY (user_id) REFERENCES user (user_id) -); - -CREATE TABLE image ( - image_id BIGINT NOT NULL IDENTITY PRIMARY KEY, - image_status_id VARCHAR(20) NOT NULL, - information_id BIGINT NOT NULL, - image_address VARCHAR(200) NOT NULL, - image_created_date DATE NOT NULL, - FOREIGN KEY (information_id) REFERENCES information (information_id) -); - -CREATE TABLE great_information ( - great_information_id BIGINT NOT NULL IDENTITY PRIMARY KEY, - user_id BIGINT NOT NULL, - information_id BIGINT NOT NULL, - FOREIGN KEY (user_id) REFERENCES user (user_id), - FOREIGN KEY (information_id) REFERENCES information (information_id), - UNIQUE (user_id, information_id) -); - -CREATE TABLE great_gathering ( - great_gathering_id BIGINT NOT NULL IDENTITY PRIMARY KEY, - user_id BIGINT NOT NULL, - gathering_id BIGINT NOT NULL, - FOREIGN KEY (user_id) REFERENCES user (user_id), - FOREIGN KEY (gathering_id) REFERENCES gathering (gathering_id), - UNIQUE (user_id, gathering_id) -); - -CREATE TABLE book_mark_information ( - book_mark_information_id BIGINT NOT NULL IDENTITY PRIMARY KEY, - user_id BIGINT NOT NULL, - information_id BIGINT NOT NULL, - FOREIGN KEY (user_id) REFERENCES user (user_id), - FOREIGN KEY (information_id) REFERENCES information (information_id), - UNIQUE (user_id, information_id) -); - -CREATE TABLE book_mark_gathering ( - book_mark_gathering_id BIGINT NOT NULL IDENTITY PRIMARY KEY, - user_id BIGINT NOT NULL, - gathering_id BIGINT NOT NULL, - FOREIGN KEY (user_id) REFERENCES user (user_id), - FOREIGN KEY (gathering_id) REFERENCES gathering (gathering_id), - UNIQUE (user_id, gathering_id) -); - -CREATE TABLE tag ( - tag_id BIGINT NOT NULL IDENTITY PRIMARY KEY, - tag_name VARCHAR(16) NOT NULL -); - -CREATE TABLE info_tag ( - info_tag_id BIGINT NOT NULL IDENTITY PRIMARY KEY, - tag_id BIGINT NOT NULL, - information_id BIGINT NOT NULL, - FOREIGN KEY (tag_id) REFERENCES tag (tag_id), - FOREIGN KEY (information_id) REFERENCES information (information_id), - UNIQUE (tag_id, information_id) -); - -CREATE TABLE gathering_tag ( - gathering_tag_id BIGINT NOT NULL IDENTITY PRIMARY KEY, - tag_id BIGINT NOT NULL, - gathering_id BIGINT NOT NULL, - FOREIGN KEY (tag_id) REFERENCES tag (tag_id), - FOREIGN KEY (gathering_id) REFERENCES gathering (gathering_id), - UNIQUE (tag_id, gathering_id) -); - -CREATE TABLE banner ( - id BIGINT NOT NULL IDENTITY PRIMARY KEY, - name VARCHAR(255) NOT NULL, - url VARCHAR(255) NOT NULL -); - -CREATE TABLE qna ( - qna_id BIGINT NOT NULL IDENTITY PRIMARY KEY, - qna_category_name VARCHAR(255), - qna_created_at DATETIME, - qna_status VARCHAR(255), - qna_title VARCHAR(255), - qna_updated_at DATETIME, - user_id BIGINT, - FOREIGN KEY (user_id) REFERENCES user (user_id) -); - -CREATE TABLE qna_message ( - id BIGINT NOT NULL IDENTITY PRIMARY KEY, - qna_message_content TEXT, - qna_message_created_at DATETIME, - qna_message_user_id BIGINT, - qna_id BIGINT, - FOREIGN KEY (qna_id) REFERENCES qna (qna_id), - FOREIGN KEY (qna_message_user_id) REFERENCES user (user_id) -); - -CREATE TABLE notice ( - notice_id BIGINT NOT NULL IDENTITY PRIMARY KEY, - notice_category_name VARCHAR(255), - notice_content TEXT, - notice_created_at DATETIME, - notice_is_deleted BOOLEAN DEFAULT FALSE, - notice_title VARCHAR(255) -); - -CREATE TABLE diary ( - diary_id BIGINT NOT NULL IDENTITY PRIMARY KEY, - user_id BIGINT NOT NULL, - diary_title VARCHAR(50) NOT NULL, - diary_title_image VARCHAR(200) DEFAULT NULL, - diary_start_date DATETIME NOT NULL, - diary_end_date DATETIME NOT NULL, - diary_created_date DATETIME NOT NULL, - diary_edited_date DATETIME DEFAULT NULL +-- 기존 테이블 삭제 +DROP TABLE IF EXISTS "user_image"; +DROP TABLE IF EXISTS "user"; +DROP TABLE IF EXISTS "token"; +DROP TABLE IF EXISTS "place"; +DROP TABLE IF EXISTS "zone_category"; +DROP TABLE IF EXISTS "category"; +DROP TABLE IF EXISTS "gathering_category"; +DROP TABLE IF EXISTS "information"; +DROP TABLE IF EXISTS "gathering"; +DROP TABLE IF EXISTS "gathering_applicants"; +DROP TABLE IF EXISTS "image"; +DROP TABLE IF EXISTS "great_information"; +DROP TABLE IF EXISTS "great_gathering"; +DROP TABLE IF EXISTS "book_mark_information"; +DROP TABLE IF EXISTS "book_mark_gathering"; +DROP TABLE IF EXISTS "tag"; +DROP TABLE IF EXISTS "info_tag"; +DROP TABLE IF EXISTS "gathering_tag"; +DROP TABLE IF EXISTS "banner"; +DROP TABLE IF EXISTS "qna"; +DROP TABLE IF EXISTS "qna_message"; +DROP TABLE IF EXISTS "notice"; +DROP TABLE IF EXISTS "diary"; +DROP TABLE IF EXISTS "diary_day_content"; + +-- 테이블 생성 +CREATE TABLE "user_image" ( + "user_image_id" BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY, + "user_image_address" VARCHAR(200) NOT NULL, + "user_image_created_date" DATE NOT NULL +); + +CREATE TABLE "user" ( + "user_id" BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY, + "user_image_id" BIGINT NOT NULL, + "user_status_id" VARCHAR(20) NOT NULL, + "user_oauth_id" VARCHAR(100), + "provider" VARCHAR(10), + "user_nickname" VARCHAR(30), + "user_name" VARCHAR(20), + "user_age" INT, + "user_sex" VARCHAR(10), + "user_email" VARCHAR(30), + "user_phone_number" VARCHAR(13), + "is_admin" BOOLEAN NOT NULL, + "user_latest_login_at" DATETIME, + "user_created_at" DATETIME NOT NULL, + "user_deleted_at" DATETIME, + FOREIGN KEY ("user_image_id") REFERENCES "user_image" ("user_image_id") +); + +CREATE TABLE "token" ( + "token_id" BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY, + "user_id" BIGINT NOT NULL, + "refresh_token" VARCHAR(250) NOT NULL, + FOREIGN KEY ("user_id") REFERENCES "user" ("user_id") +); + +CREATE TABLE "place" ( + "place_id" BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY, + "place_search_id" VARCHAR(30), + "place_name" VARCHAR(30) NOT NULL, + "place_x_axis" DECIMAL(10, 7) NOT NULL, + "place_y_axis" DECIMAL(10, 7) NOT NULL, + "place_address" VARCHAR(50) NOT NULL +); + +CREATE TABLE "zone_category" ( + "zone_category_id" BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY, + "parent_zone_category_id" BIGINT, + "zone_category_name" VARCHAR(20) NOT NULL, + FOREIGN KEY ("parent_zone_category_id") REFERENCES "zone_category" ("zone_category_id") +); + +CREATE TABLE "category" ( + "category_id" BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY, + "parent_category_id" BIGINT, + "category_name" VARCHAR(20) NOT NULL, + FOREIGN KEY ("parent_category_id") REFERENCES "category" ("category_id") +); + +CREATE TABLE "gathering_category" ( + "gathering_category_id" BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY, + "gathering_category_name" VARCHAR(20) NOT NULL +); + +CREATE TABLE "information" ( + "information_id" BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY, + "category_id" BIGINT NOT NULL, + "zone_category_id" BIGINT NOT NULL, + "user_id" BIGINT NOT NULL, + "place_id" BIGINT NOT NULL, + "information_title" VARCHAR(50) NOT NULL, + "information_address" VARCHAR(50) NOT NULL, + "information_created_date" DATETIME NOT NULL, + "information_view_count" INT NOT NULL DEFAULT 0, + "information_content" TEXT, + "information_tip" TEXT, + FOREIGN KEY ("category_id") REFERENCES "category" ("category_id"), + FOREIGN KEY ("zone_category_id") REFERENCES "zone_category" ("zone_category_id"), + FOREIGN KEY ("user_id") REFERENCES "user" ("user_id"), + FOREIGN KEY ("place_id") REFERENCES "place" ("place_id") +); + +CREATE TABLE "gathering" ( + "gathering_id" BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY, + "user_id" BIGINT NOT NULL, + "zone_category_id" BIGINT NOT NULL, + "gathering_category_id" BIGINT NOT NULL, + "place_id" BIGINT NOT NULL, + "gathering_title" VARCHAR(50), + "gathering_content" TEXT, + "gathering_person_count" INT, + "gathering_view_count" INT, + "gathering_created_at" DATETIME, + "gathering_edited_at" DATETIME, + "gathering_schedule_start_date" DATETIME, + "gathering_schedule_end_date" DATETIME, + "gathering_is_finish" BOOLEAN, + "gathering_deadline" DATETIME, + "gathering_allowed_sex" VARCHAR(30) NOT NULL, + "gathering_start_age" INT NOT NULL, + "gathering_end_age" INT NOT NULL, + "gathering_is_deleted" BOOLEAN NOT NULL DEFAULT FALSE, + "gathering_open_chatting_url" VARCHAR(255), + FOREIGN KEY ("user_id") REFERENCES "user" ("user_id"), + FOREIGN KEY ("gathering_category_id") REFERENCES "gathering_category" ("gathering_category_id"), + FOREIGN KEY ("zone_category_id") REFERENCES "zone_category" ("zone_category_id"), + FOREIGN KEY ("place_id") REFERENCES "place" ("place_id") +); + +CREATE TABLE "gathering_applicants" ( + "gathering_applicants_id" BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY, + "gathering_id" BIGINT NOT NULL, + "user_id" BIGINT NOT NULL, + "gathering_applicants_state" VARCHAR(20) NOT NULL, + FOREIGN KEY ("gathering_id") REFERENCES "gathering" ("gathering_id"), + FOREIGN KEY ("user_id") REFERENCES "user" ("user_id") +); + +CREATE TABLE "image" ( + "image_id" BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY, + "image_status_id" VARCHAR(20) NOT NULL, + "information_id" BIGINT NOT NULL, + "image_address" VARCHAR(200) NOT NULL, + "image_created_date" DATE NOT NULL, + FOREIGN KEY ("information_id") REFERENCES "information" ("information_id") +); + +CREATE TABLE "great_information" ( + "great_information_id" BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY, + "user_id" BIGINT NOT NULL, + "information_id" BIGINT NOT NULL, + FOREIGN KEY ("user_id") REFERENCES "user" ("user_id"), + FOREIGN KEY ("information_id") REFERENCES "information" ("information_id"), + UNIQUE ("user_id", "information_id") +); + +CREATE TABLE "great_gathering" ( + "great_gathering_id" BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY, + "user_id" BIGINT NOT NULL, + "gathering_id" BIGINT NOT NULL, + FOREIGN KEY ("user_id") REFERENCES "user" ("user_id"), + FOREIGN KEY ("gathering_id") REFERENCES "gathering" ("gathering_id"), + UNIQUE ("user_id", "gathering_id") +); + +CREATE TABLE "book_mark_information" ( + "book_mark_information_id" BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY, + "user_id" BIGINT NOT NULL, + "information_id" BIGINT NOT NULL, + FOREIGN KEY ("user_id") REFERENCES "user" ("user_id"), + FOREIGN KEY ("information_id") REFERENCES "information" ("information_id"), + UNIQUE ("user_id", "information_id") +); + +CREATE TABLE "book_mark_gathering" ( + "book_mark_gathering_id" BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY, + "user_id" BIGINT NOT NULL, + "gathering_id" BIGINT NOT NULL, + FOREIGN KEY ("user_id") REFERENCES "user" ("user_id"), + FOREIGN KEY ("gathering_id") REFERENCES "gathering" ("gathering_id"), + UNIQUE ("user_id", "gathering_id") +); + +CREATE TABLE "tag" ( + "tag_id" BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY, + "tag_name" VARCHAR(16) NOT NULL +); + +CREATE TABLE "info_tag" ( + "info_tag_id" BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY, + "tag_id" BIGINT NOT NULL, + "information_id" BIGINT NOT NULL, + FOREIGN KEY ("tag_id") REFERENCES "tag" ("tag_id"), + FOREIGN KEY ("information_id") REFERENCES "information" ("information_id"), + UNIQUE ("tag_id", "information_id") +); + +CREATE TABLE "gathering_tag" ( + "gathering_tag_id" BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY, + "tag_id" BIGINT NOT NULL, + "gathering_id" BIGINT NOT NULL, + FOREIGN KEY ("tag_id") REFERENCES "tag" ("tag_id"), + FOREIGN KEY ("gathering_id") REFERENCES "gathering" ("gathering_id"), + UNIQUE ("tag_id", "gathering_id") +); + +CREATE TABLE "banner" ( + "id" BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY, + "name" VARCHAR(255) NOT NULL, + "url" VARCHAR(255) NOT NULL +); + +CREATE TABLE "qna" ( + "qna_id" BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY, + "qna_category_name" VARCHAR(255), + "qna_created_at" DATETIME, + "qna_status" VARCHAR(255), + "qna_title" VARCHAR(255), + "qna_updated_at" DATETIME, + "user_id" BIGINT, + FOREIGN KEY ("user_id") REFERENCES "user" ("user_id") +); + +CREATE TABLE "qna_message" ( + "id" BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY, + "qna_message_content" TEXT, + "qna_message_created_at" DATETIME, + "qna_message_user_id" BIGINT, + "qna_id" BIGINT, + FOREIGN KEY ("qna_id") REFERENCES "qna" ("qna_id"), + FOREIGN KEY ("qna_message_user_id") REFERENCES "user" ("user_id") +); + +CREATE TABLE "notice" ( + "notice_id" BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY, + "notice_category_name" VARCHAR(255), + "notice_content" TEXT, + "notice_created_at" DATETIME, + "notice_is_deleted" BOOLEAN DEFAULT FALSE, + "notice_title" VARCHAR(255) +); + +CREATE TABLE "diary" ( + "diary_id" BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY, + "user_id" BIGINT NOT NULL, + "diary_title" VARCHAR(50) NOT NULL, + "diary_title_image" VARCHAR(200) DEFAULT NULL, + "diary_start_date" DATETIME NOT NULL, + "diary_end_date" DATETIME NOT NULL, + "diary_created_date" DATETIME NOT NULL, + "diary_edited_date" DATETIME DEFAULT NULL ); \ No newline at end of file diff --git a/src/test/java/solitour_backend/solitour/SolitourApplicationTests.java b/src/test/java/solitour_backend/solitour/SolitourApplicationTests.java index b8fbd10d..61dcb196 100644 --- a/src/test/java/solitour_backend/solitour/SolitourApplicationTests.java +++ b/src/test/java/solitour_backend/solitour/SolitourApplicationTests.java @@ -6,7 +6,7 @@ import org.springframework.test.context.ActiveProfiles; @SpringBootTest -@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.ANY) +//@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.ANY) @ActiveProfiles("test") class SolitourApplicationTests { From 4388b136e5c22bcb70e6cdc9c06bea75b9b08f75 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Wed, 18 Sep 2024 15:42:05 +0900 Subject: [PATCH 315/371] =?UTF-8?q?fix:=20=EC=B6=A9=EB=8F=8C=20=ED=95=B4?= =?UTF-8?q?=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/deploy.yml | 2 -- .../solitour_backend/solitour/SolitourApplicationTests.java | 2 -- 2 files changed, 4 deletions(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index de6f56c7..3ab74785 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -47,8 +47,6 @@ jobs: run: | ./gradlew clean test -PspringProfile=test ./gradlew build -x test -PspringProfile=dev --warning-mode all --scan - - - name: 빌드된 파일 이름 변경 run: mv ./build/libs/*SNAPSHOT.jar ./project.jar diff --git a/src/test/java/solitour_backend/solitour/SolitourApplicationTests.java b/src/test/java/solitour_backend/solitour/SolitourApplicationTests.java index 61dcb196..aac74b18 100644 --- a/src/test/java/solitour_backend/solitour/SolitourApplicationTests.java +++ b/src/test/java/solitour_backend/solitour/SolitourApplicationTests.java @@ -1,12 +1,10 @@ package solitour_backend.solitour; import org.junit.jupiter.api.Test; -import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.ActiveProfiles; @SpringBootTest -//@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.ANY) @ActiveProfiles("test") class SolitourApplicationTests { From 2f2c66901f743cfae8d696fbe62cbeaf3c2e28a5 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Wed, 18 Sep 2024 15:41:03 +0900 Subject: [PATCH 316/371] docs: yml --- gradlew | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100755 gradlew diff --git a/gradlew b/gradlew new file mode 100755 index 00000000..e69de29b From b1c9838ddd0bb1e3df78aa0682203d5467d930d5 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Wed, 18 Sep 2024 15:55:29 +0900 Subject: [PATCH 317/371] =?UTF-8?q?fix:=20=EC=B6=A9=EB=8F=8C=EB=A1=9C=20?= =?UTF-8?q?=EC=9D=B8=ED=95=9C=20=EB=AC=B8=EC=A0=9C=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- gradle/wrapper/gradle-wrapper.jar | Bin 43453 -> 43583 bytes gradle/wrapper/gradle-wrapper.properties | 2 +- gradlew | 252 +++++++++++++++++++++++ gradlew.bat | 2 + 4 files changed, 255 insertions(+), 1 deletion(-) diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index e6441136f3d4ba8a0da8d277868979cfbc8ad796..a4b76b9530d66f5e68d973ea569d8e19de379189 100644 GIT binary patch delta 12612 zcmY+pRa6|n(lttO3GVLh?(Xh3xVuAe26uONcL=V5;I6?T_zdn2`Oi5I_gl9gx~lft zRjVKRp?B~8Wyrx5$mS3|py!Njy{0Wt4i%@s8v88pK z6fPNA45)|*9+*w5kcg$o)}2g}%JfXe6l9ig4T8ia3Hlw#3f^fAKW63%<~GZJd-0YA z9YjleCs~#Y?V+`#nr+49hhsr$K$k!lg}AZDw@>2j=f7t~5IW6#K|lAX7|^N}lJ)I!km`nrwx> z))1Es16__aXGVzQM0EC8xH+O!nqTFBg9Ci{NwRK*CP<6s`Gq(~#lqb(zOlh6ZDBK* zr$|NDj^s6VanrKa+QC;5>twePaexqRI%RO~OY075y?NN90I|f^(P# zF=b>fZ73b5JzD`#GC3lTQ_B3lMeBWgQUGYnFw*HQC}^z{$6G4j(n4y-pRxPT(d2Wgb%vCH(?+t&Pj z)QM`zc`U`+<~D+9E{4Uj2kc#*6eZMU$4Oj6QMfA^K!rbl`iBix=2sPrs7j@aqIrE zTaZJ2M09>rp$mgyUZ!r2$UK{+DGqgl`n;*qFF~M(r#eh`T{MO?2&j?xgr8FU$u3-` zhRDc_I23LL4)K&xg$^&l-W=!Jp-P(_Ie07q>Je;QLxi8LaEc%;WIacJD_T69egF?7 z;I_Sg_!+qrur8$Hq4grigaiVF>U7uWJ@Hkd&%kmFnQN-P^fq0gB1|uRt!U#X;DnlV zo?yHWTw7g5B;#xxY`adhi4yZn@f(7-Xa(J6S=#d@&rlFw!qfvholE>MEb|VWn^g}G zMSrK&zQ^vDId&ojL!{%{o7?s{7;{+u%L{|tar(gp?Uxq3p?xAysB>0E$eG#$tvkk9 z2Q2gEP17{U6@UD*v({5MP-CTZfvWMItVjb4c;i~WLq&{?Q1(koX&vt7+$z}10{^Id z{KDjGi0JpD7@;~odF__0m|p;5rIrHidOP9^mwKe#-&JX-X@acc)06G{LO1Wu)#gvZ za~y9(fhA%UwkDOVU1LBJ`0ROE z4&)dJKK%mG@+CIm?+wt9f~@xIMr8}UH*K1j| z0pppo{7gv3v{URwxVMeg>Ps!L5IKxm zjac2egjgb0vH5i75$s|sY_RYec#>faqJk|AGgV;v=^%BM(^p{p;(^SVt-88G9f!q; z>p}9E4^f0=01S2pQBE4}9YqE%TV)*hlU^8k9{&=K76+*Ax^r=AkBb%OCP^P2nm0Ri z;D-|Zk?gGeU<12ti2CnPVNA(Pb)02+r|&yTWW-OJO7 zNLb0pps6aN?A~NJp5kj{{IOlf!5KWMleV@-hYLift)D>-7K+tgs=7Ake}oBnIy-y1 z(Hn@Hjw=_(x>dO5ysQsrnE%A*bk0K<-j{1Yqz@#n#jOL^AzCr#wR|WYzqk6i7v)Lf zkXdKxzuu20aP{Tbg$(+9&oh7cd(Uoqqf<#ujb$q4sZ~gxFbQfS zS)kNklyL*{2AELgjZ(LBu*>S(oH5AaJ;YiB@;l@=O%F6B?oanzoYRM^fQ9-<~^=3$H0g^JPMLQo@SZ@QuNvy)tyJ)LSj`+()#fy?{aV4Yg^7dlQ7AQM^3GLCR2dAFR zJjtfKiVqF`l-H_fz0HD|9g>)pOxn}k!vdZ=DO!7Sikm{Z%P6BrRkBS6W?ZB5W&7rT z@uYpf@M@a!z7H&o@-yrcCL^Ff3e7p3T`R9p?@o-acXmbTSa0>ZANzCSgovsd%;i$| zVus`not!oL#(W`L-!9w0jdaECaG4hk{V7IOs676ZquZH~0TX5hDq|)x z6T497l|E?f4)LA>j=S8}b$0LS=I4h|hUFJYJODT8Li@#6kF$k0)@*l{RnM1HQ%?VT ze-Pqlc!~t(oumVC*?5fwR;P6u{tHaZ~*LlD;B)4f? z?lpWfa2P@)g57flVl83Ej%P`2)gGyaPjhvD(%i~{`2b>#3!+y&` z!2nuwHMFA-zUY}f1^0B8<`N)Gr=A4TS@b1qykmd0Pq{?r)+1^^+D(=xasb^Tf!oK9 zBLL+*p6M_#ufgLzgq1zcSwZsZnQWFLC3`Yxdg-2=*tT`J9nrfYt)RF)YryBf8_gW{ zvKbB+oZLehfT)S#<|y1)E0hW^?+AnqPXq9Hu;v3dsMGdr{SVyF63;K<8VcgI#~}1i zLYSBL0K;RTT(;>2x=*!1Di9w0mwr;`CN}kM65|Ay{~z}_^JKOsRaN<~#9O^iiW<5P zYN7r~HV!#Nz~IZU`P>1Xe%4f~K}KcF#X&5kO*G}-)74S*tQ8CietdPcA1Yl;S=Mr# z`#MYY!{s^uo=jn7;k6O%(}fN+*0cWMpt~#n9DR<3NyU?+3D^AgI}S)Cu-Tljg`VY} zX1=fq$?8$DtOeGxE6f8lbS_6Q3C4+LDTO$}_IpM$Xv<|QSC%+Oll^q$y`7o@jD{dp zNDl|&X)r7wETa-#h*d`KXntxI(Y{vLha{$0i7@G8xx^m=c<{lJ9?p-i!^W{%j7-oo z0W^SzZ^(Wkyz*We{lEn%Yhu-ycUOHtrRiVJL4~&S91*D0MrLu}Q>v-Mc?GcWfpyz% zX|UvcN@krFO#@v|CtYM}g|=L3%aMo$E5<@CM%c*;?u>LOTz00@+dt1{yg1y=$h+{|D17U}$*^fE^H&8b431EUE z<9tv0V_#%#&1N#j7AKCj!tTK@J%oFW*ESW<(#Gl#Xs%v<@AitI?s92nLzm<)w3Wkkom1f$gcdUi%g_*jofy&}N#luL<$GVIe{iQkQ)sIHVy zBgItnPBFamrv6Kb{eE($Q(f`ZPeW!Hm%Y@F*OF1sKB{Yy|C>WEv_mfvv-N-jh)B-5 z4a!1WcT@9a+hGaBrc~sz=>G?Q!*Zp^JFRUvBMyNR1;`)j$RhH$6gEyVKhd$&K-CFT zXaWC-Y=fyOnqT84iMn9o5oLEOI(_3fk!W^8-74|q1QhQ|CmT0i=b;6Z3u?E{p7V{? z;f#Q-33!L+4&QQcZ~GAqu$NS{M;u%`+#9=7^Oa5PKvCCCWNG_~l(CidS!+xr-*gg{ z$UQ`_1tLT_9jB=Hckkwu>G{s0b0F4bnR7GibmHo?>TR&<3?D;5Fb#gd8*wYa$$~ar z7epl1qM)L{kwiNjQk}?)CFpNTd?0wAOUZ|gC{Ub|c-7h~+Rm(JbdoRe!RNVBQi!M8 z+~U6E2X&KSA*T6KJvsqwqZl#1&==Dm(#b^&VAKQ>7ygv*Fyr;)q9*^F@dCTg2g!w~ z%hg)UXAUyIpIbLXJv1nZX+a_C)BOH2hUim|>=JHCRf(!dtTidb&*~I!JrfRe+PO>w z@ox$G2a3i9d_N9J=|2$y2m-P&#PTNwe!oLBZFs;z|F5kXvBDn<)WwE0E3$ow=zg3R zK(9;sf0t;VEV3@gAg7jRtnj%-6O@!Hvg*;XcUAw}!=2*aErvB(eQIm(-UGmq^J=XN zTqJo$Y|WKo^HlBF3BXJrA#}7ZLg=r*w`I*~Ix`o&2k8^(0mt8Rp=A>F`&gehhp@Jy z^e^#B2!~$LvNCKugg)8)-G%&THdk~kfextilegP9?#C#()F59U$&eo(h|5>ceo*Em z{PEE79T$YP|Kr7K`WBHbtQwyxFkCl6xX&+oUf90B5xoi3_5KHHCyEE*oPbOQkfMz& z6^hT8_NXd2iWk{q9IKae1{_7hMPH8I7_BMtVOM4 z6jm?E0QJOn$qrgsJ`9w##GB9?G})-GXSQo6(tYS(Q0-Ct$co?Zzl0?NHsDRron?;_ zZZgQg)%XW>P?8_&zoGuF(>Och2kEJXsu1_X&~w87x!b z>~h!a>e7{`p@+#hXF88wI*JeWRZ;J4ev4<}HWf|Z;(7$E!S5l9wzBHFe>^I{2`a;a)QnAwa2xv1e(bq$<}!8o^ofGvYpk7dBR+`*%iE;hUY5 zaHF}OjGO9r*{%lmcK^uFiTHgoUD`^9Nx@~;Bg!V* zuuJ&ti{DQiq7RyJAR94wem{}cPK1J(Yxnn_{=>?USqz-~&QXRStS^s-7TksZ$AEI! z#og36s3JGtGU{CnDHRFtipFqvrE*gw7_K@NN0h+ItTq@4fqN!HeQU1y7*X?9+IfZT4Vxebpt z%#VzgdDK~-&+=Z*#>=n#XUhNvBZp3=Cr41jMqwJkHLf3L7Vm~V#GgJ(Jpii~PmJ#s zA7Ft!{xD@z>9DUb4JbiUBdNEcU4BO$651iN*mp*f)HbRRM`Cx5cR?5IfEcU{IZWwf zz(M6CDv)>xa3x}K6%tP^i15P1&&DOLK=k~+jNR$UK3frSl+|PjSC-dBItvD~LL! z>_g(YYdO4k(5EbPOw+v+;G7~jYm>F@Ai|o`gs%F)F8tDz$dl7Q%aCe|v|$UkAul_R zNlA-beBX^IJU?kgS`E$it7nF4DaI!SJAGq)2P&Few(-|tp z?K+%D3e4{pfkayrcbm0ftu6Ol2ZzdKM+4i!hNP3NRL`EvvZJ3yvNr2MV%igZ4kj``Qrdb_OI$7jWP z;l0DYf&0(-*QcP5zrP`HVznW+SbH63Qx$7_9~NjRNg7eKqI!UJ=XH`g^=t8GiFTu( z?2L{JKEu%jJx&XjNzU(*!ZNmL1@RlJA0G$2_LrAb_7lmjil(GSlSM zwTes`m+3R;3#N~Xg#9owh3ycXV8@ZlaY_16kpPFA={721b~URO4HD3sp%fmkZM}k) zZB0#)kP=RkNB~R-MCk8aljG_bagt4vIb~8)BV%(b8_;)&Kf9GX+%O_cNG|(D$!3&D zL(I8}*LqN5NntipFlN13=`D>6!{D@CFMBH0kW3=HccJV+xW~|$qeFR5i-2{X+iWMu zI2$gepQ)H_B%ip_BlWOQ*|pErXs|4ir{IHccgaIJ84irE{?+$KDABXr&f`jB^V-c% z$$u`uU1YB^{<+UN2cNg#7&0bz@yF?5>j|;)5&IV3wIQp58X#OE-M^$HdyvL|Um5t? zhZlAG!Mz%XkUe3t471JM*Yur}o30vzu6RN7gJyNcf!IItsDO730mcJ*O!~V``y5=3 zNJGp34DZ}wd1H6V`Uuy%es>BiO_aE-S8jzir#$& zyk)@2a5tP$@g%jW^b^JGdo)X@Q%sE`^lDQmY9m%uDFpPX`w9%=yQ+nneMm#OaXcD` z9}{tn5A2b2z9783vL2_jSao?uxJhWJoq%47*RafM4o0@gY(p)F>qT4^XM5GLzV#6j zC+HoGhAne7o_w{WUo(B++z7lU3Y0k1rYv9|TSv0vR-Du(5=VakbbelgZTeDn+a_Wv zq_j-^+Qz1WAl;Zg>ahX|CERbX1V%B!hTKN?M}fGoA07M(WU&NfT&TmN`P@56U2 z^)vLDs|Ln~0iTtn-?KTeQl@T&bskJFuTUS!m+$CS9vnd}8(UMO|Kv6TCfGN9NUu&4 zL{)GTxPq>fwsJ~aU=4Qhuq8*RzDsP(LZh$BHezq&9gK$IS<|DYbm})$QTGCS6T;Dr zEkLct!b+#<1r9OKG@P!f1wm8>=Nz!7OzJm!g<+`?N3;YaA3(P@EL=(sTaRMDD!c8=-XN^4BXp(eVkj$NmEMYPP>YJ4bJ3yUud z<3BeJAJ$6z^TuywnfH5lv#$lgwraNw{IV=tIznPH1DT`v-5yS=!)J<}xxl}uZf9azA2A97Haf!;<3y01hlw?dWNEv@TLi1s-mO4vmIT%O_42nS z$VRWrs9NngqRRkWAnWkn%`Rw@?wH|)7XL`EL5EZu$qyJW31&CB^T_)qwIv!{;E_6 zo-9XAryQRlk-O0>o#-SZO>|6OYq;}<*>Wu1AsVRiXY4f8qb;+sItv3AyS!4Ry+q}) zA!pAB|BmC;=RIOk^^vlsEH(!Q!7_1FK~ZB2err*o!+b(r=m1b?$6d!%zmN+69LXnT z&gRmM+n_R-F@sT*IYv0_mGPvur!u`iWbQO7SqiGFLeY&yga zf`lM&B74FA2C?N@8_z652fjhBEoDUKbP8hL{0{HAF%qDo7)o3=3rg#6)T7%%5^wl% z9R0*S*<~>nzYOdQk2l`9h#t+gJy_xujw6xjV(8S<_DbVg61&pT%Hi42l%D73G?adn znB%UdNM0p}lEF-P2%TAMam2zpQev71e>a$$%i+r~b+D9G9pF|oY_*(-u*89oKsXLY+UIbqq)MQ%(GYS{(*n_S_*RN$*~`zUtab%0aKwhx znc)Yo?{xq1sJCgQD)TeTci1ucvbez9q=A72H(-SB18Kl&6^vHV8^i!p@>iF!DIw17 z+8Q)TNisB7>pwyww4y)yJx*wX6SJO78eLBC-ar1+k$Z9fy;wBD|3kzI{<+l*>PSY^ z_?nLOZaeWbU@C3hfK?X;Di*8CHCPkx2qco6(ZyJdqSzp^TJ_5Lpa0UP{Gy+!b0Lr% z@xYxSjUKoY6L#>$qx~KD$-0=|OF7zhVP~ntMgEALYPIfhj@+ z!;JJ7te>CcovruwHsJH6Lta$nm|%^C@=V-rmhU{+I~0(|XHQ9jt@L7pb{gx#{4r!) zg($FyFTslcgu(~6lYr$nW?)%*l#VJ=R-jxK(x=t1bWlu(nL66T#qj%3aZ@uVhy}Co zDU_q61DD5FqqJ*#c|(M5tV)XBN?Ac^12*q)VN4yKPJ|#==S_`_QD9|0ls!`2)SwuHDRA_OfXQDq3%qW&MZB}Z!=k-9xqev8jHz(H z{^D@cIB~QiK>~wa)A&^Ll^Wi6QgCzU;iv-BHsLBs zH7=jN%|>0S`SjP%M&AF1PNVDp_FZ?2Bm@7`DC&v(pYrw!!yD#4 z6+<=HS0Ln6MhoKxF<%~H`y20{vf#pxh=;j{zY381gvAFekgG|>G1zo8$&az{V=;JR zy_puF4$L$?EMhT?;TpQoR*j16ll`#AS4e96C}yp_aGKkBe?1H|k_;gG-~Xorc<;lI zkB}fB{$c-D2mGA&{rm<*@F5)c3X+6??g~XoEwuzSuch0D@W~P5(2I8v8F$c2$Vw51 zP#YLSBDqtWW^EYBl^QYHF+MA7am6f4DOhwnJM=W9$uvMOsZ%_~?)2C#wb?CkI$7{K zEi)=#|5pFvg^){zK5kpBLjB2kZ+$ZB|L=W|aNwyyb(gC2l7bcpx{E-H@)q6@D6N^xh`{1E%ItF2$eeB_SjI@b2WgTpS1thwg&n`jiIzw^TtXUyB{00($GIq>vbj|}bav}}Q_~wp3>k8!E@hVC;OMUTu|= zAy#vXH*GrUHu7^cNZWe1>y;2(51js9wbu+R3Aa*(wzH9+X0dIsf&gc_x|_LP z>~CF^?(~U}+l~ehe|i>?4eo!xkq&Lk+RR-1duNP#o~>@1x)s&i&u zRaYL@+D&_M|JLI6fHbEr_`U;HgPTh#E3?sB)A$*gqyBgg*ql|a-m*TX5rACbWKCE6 zdeQ`v8m6>g^ugv`p|HY^#1QZrGGUj0^HVDc@{?Q0yhalbBEV{+|HzC^-{&e{5K%z9 z6Bxtnfu1!@Mp+Q&*&~;FOg&*Vm<@4b;{FG0-!UUXX!|)1w}op!B_|7_s~d(+=9Gba zKp8`LaB4D(H=cGcspJ_TjYaOwMb=sGn^gtUVhK!UI~2KKYEE-NC}F>+BEY7IVvy%KRvm00tg!Q`y=er}wpEetX}K@;}(}{s9AzV#q2@ zBy7}->|N?13POrs`;U?(qAG(I$~Gt+Rgw%aNZ_0fs_utVvRJT-7z4!@x36v@=NBX=IqkK{#Kg0w48de@?#Yb4M(Svj5=T+<ONr8-oh7l?Cji@+erqur zFhZ=9|Lk=$`c}v4u`)-!!UI=!9Jo@h&7p4RlS#u! zZ7-prn75JkV?VjptX;@$#`U`{vB!=Z?V`T*FBF>J?vsML7e6@2GbUteMFfX-TUu{2 zLNIG*;dV)8GV8gAgEf#)X3A>p3^CRka1v?~8x^anBhQ=L=LsOl=&pcOYHo98m##ye z34MtGCDK!`ptl?taGMr5q{!zVc? zG00e){TV?`YA9eB;(lA3lXI?RrB4BYQGk?vOmTIUJED=(`_*gtn2DB-t4WW54as*W zb2kD-lWX>lb$+W!VFakki>B^Vc+u$?NLF>)!U%b@Y}gYJ>m2H=^x0=nsE0TF^Yu0h ztgH8-o1%+jCk(+&`|)tTfEVHq0cMeFa{Uz)X$;fCq%Y=SOWML6bYfeP8j5hktL`KK z(18`XrUn&WN9PtFxh&dX`y~YBsmdhi7Kw%tKzM%^VEhdD<_XkulW-x=JN6OPbFI4@ zzDDRN+f=@{0h*MswwOqG6gJ?{NuHx(y-|FUGsxyZ*x0~$MW(eY>vqq4Fh#t7uzw=- zKB?|!0N~!h^AMdLa)oR!Ca#HZ9&Zf)ghuO<^RN)4twRlygHnQG(BE{cDc5E}OF4;xss6gYyV~EcJvJkX)xNWb=@yw!uq0v-sf^rvkp-;?DPWK@*SEw|V;IH=7 zfQqEV_>DjOPT~8X*J|H8=&RnzK4~S7ML~nLX^%s-Vqc^aWy7N$y57qciZGcqy#=zU zs8hcHiI=D$+RB{|62{ohCTiaML6FI4Uhzo5D{Jik@poCs0w7F)*w}F4r0sJ~#u-72 z5bK=ANt=M$Dh5NKnxGsg9NRR?WD-x|FhTwBjd zD<-K>44DB~i%frJOfnzh1R>PRY34kw!6~p3M$JLaD1r@`=h)~Ngks-(gdXh^Q?BTP zZ^Zj5w1AwtuR2$~E7s9iZdF}z%pv1em^V2rM{1tLUY@-+Sc0(9jA|iZWml1;v13=U zHf?y@#mb--7z6$ue>`qjhE~brk$AY-RG90~5wcBbDReXR2)pKg{L>;H(DI`U!MLNQ zY9rFJP@ZQ}jlcMh%WSCo%vf+nd0Gmd*F%KMIe>slCUh)8Ma|;M_I+v#;|ueg9oLg; zq2HtZX%&#F7vdpNlkX?}(C7dGC^y#NB#m4%69RzTNrk%4ol~hSI%>2r6B|*ZkW(*P z;u#s;+faHo{tfy+1L^RzWDi*^JR0iY(zJDB36y_QJ+|E-2x+cY z!V8uLNktH~q>WQZuY!Ap66WP|E!0PA1jK~)^8oJVGbspJs6QL!!-5Qm7 zHYI|_`Actg?vDzdg5{86w@GS$G6ANzff7->6i5pB$T4O}`fZ_;{217Om0gN5zTr12 z5mW{hCzCE-QubjxN$TAE-XgI-8dTY@OZmq`y+y_>dk*(qXF0{nam|q@~i}Utp*k{yurq(DW54hkDT4bbg z=_etM?Nf5W^o-HEu9_?&xEqPg^P^mTxLH8n%u$!mWvFG|{&)jtnU&6|5-`~eaNz0%D1BDo`{ zS1N5(KW5v^2eLdd_%`uaRndF@h0Uo6=M|8?b~KbOLZk{HXEnGmtgZXf2inI*1r%n! zQ3&%RI4r{f&dwW~HwH0Ked9b!k6{>_19H z_Ai>5IChDMY(FfMyG%;30?SQ{iV9KyGru62+Y)~qSQ91}b~}w<&*}R&1c#$O`H@~c z5)2S_eXx}M#N{MuGeQS9@#UJB@;W_j50b}jIhxMPloEFQZdvwxiU^RYycTzgK)-vl3LT&$L8~@68$C8~5_U{cR$E#w*x65(qw&eoL@>%ZHvj zWnEMlSh*(o&oy|J7eJ5OD`ssy%F?*Vp?`Cq;FShyl{ZoKCG5g{y}>usznni#8ki(i zO{w@n{iAj1_ooX@+s*!uW60WcH~*bNOT6z%0jVML5};wVrQp~`Uss_{cO2oud_nNA8^B$?07fJ6?iI)Q zuo9G)O-z)DqstrBqf>B%S05hf-wep0@$BFHKSrkZ{za3D)yVzRz)2{wf8(Wp+xyAM z$rtyx$gi3A=V~V!`Q3;BM0$>*VVtxEM|xDL^gew7ydy3Q6YzD&THRz*q33Ms_D;M- zbCx1Ft#UNB)V3bf`~{ImI72OTp^|bF8?G8#FRj+Biy8ET5#rA3sd|0FR@U(LAJ%w8 zS1%n8Z=Amhw)92rIsof=YVWF4jw&F*j1LG@-`+cR0-~2LqXRH8(Ccne{y#MCPncF64U`0uO zWmi$dlii~1D0rLR{qc|_2M!C$t8^=G7xQY)9!#Y331A|>N)EhmyVdLWL9I3YLJ`7? zZmpqUJB>Ni9oiL)^1IK1UoMyhWE{$9M2M6Xi zPKk7GpMsA6vjZbU7~i+u|J6Nk|Ci!Y3UMUT2|`M;JsNQACdJ%ooo9Yt{?A+0hMpxi znEa~~sxC>rKrU6bd=WRb;%wsH>A#j4{({&1GYSNR57Gama(3)2A;SM>qop}l>Jk2* zn1+C$fIxuwzg3mCU#SOqb-wOCb6mBcYlA5+mt<&_J~sBxc(GQtBFINUO~Mr7<-uu($>P HJ4oML2Lo<@i8BwbL^1~GkG`E7C$SEa_ zF^}Ea+#Je`Xy6;#D0FPnSrR%Y!QGA~NA^{oWmW8C<3dr{x6wWQ{4+bzemqV5W$i5~ z=J0jXZ>uZb>DT@0Ks?4QJ{`z?8JWl3$y;2pj#$XP*pv$>$g(z43{YH9KmmR6<#sIn zA`#=0#sgycaBQ^&}Xba!|KaZ8~b30v~nLt z9%#gz_*=~KD{3t^X~l>480*}PhKN=??g`RV|4Ud{Gyyl187MJ}r(#e+H$GEdI+p1s zq_25h;fV)$EPK%Dw-(G=f`yHB-_tttsC!?k7*#!|4a>`Ahj8nm?&n>NRs%jkZW^3-0P_yMP5&*6a26{MRj1&TPF zyE#|c)5uUHzMWx=rMKpuPih*V=S;W3MzIZTw2uTbr}8`p2bm+Z6Sa%vvWAWSf4H)p(+ zSQ8;EvUa#wqWV+9vmIio(%7wukK2SwjUS8Yl%Rq%=~PU)2$Tvm6`1!r3H@U#_|bB0 zmlT1PS3wPB(b&^+@YY7Y$n4l3mV3-X0$>z|gZp6O*Lhzn&?Gad2ZCF;+#95-Y?#y+ z?*l@Yf=a4w{Px=o!N|3~_XKfk&G;fN>Ps&dp2FpA~qD=0~=!NOS@B#XAKKkND>Y{4>rqxrViKD7;?>j8`R` z&G)3FN|dfsxnaI^!d1G%=>AbTTxZWo;n-DLrQ!sj=f~VAOe5zhGS(dgx|!ls62fbX zV@<7Ck^!}R=`Swr?(7w1rY6Nmq~sfXJ?TiKJLn=&SQdEt9$@0 zA+h1Wbwbri0s-stc8yVq;mRa6@kEf8^KXUz&jcic!+avDvvJFa>k0ioWug=T3oPw; zyj4it&0@>_*uI@2=^+T7sL1_!^aJW@Xfo8aC#3^WtQC7fET8b9C} z*u^ue6Ojn z7@(eskJ2+cNnH9~VyfIh<-|7!je~vGy*odz(sk-u$~SrYF3glruZ*W`{sqnS+9=;Z zh{D@MSG91%lr&ua8%$sJF%y1I<|e;EdfJykY8#D$Hc_81n5`$7;1N|b0tvvPLzSg& zn7!5x?T*@rQUKcUhTIjV(rw*5oQYlm5DbEO?60#mohHfbR$3_x#+PZoYi@Vd4`#YgKyTd^!4n{fN~WZDY61sAOm6 zl!d^i*a01QxpWM9Pcl?&{RgO}uq%ErOk5WpECvnfEh!*YP&1Sl)uTN4hg??Vqs~i5 zYsfufz3?{TtwuBN=`0~Qg1PlWH#OGG$ zLLWU17$v``)CE1cds_7kj8mJ{-+l8{DS|zAQ&3|qpOY=!J|kXUhXue9|H>4gqk|n) z-i34GmxLFj8asb3D#D&=ya*a5`C<=o?G;Ev^LV%;l#nH#O=7Nh@z1Do>j6Q;I5S2P zhg|AZbC&|c7}uSJt57s2IK#rSWuararn-02dkptTjo*R{c5o(bWV}_k3BBnKcE|6l zrHl&ezUyw^DmaMdDFVn<8ZY=7_{u{uW&*F<7Al6};lD(u;SB=RpIwI)PTyL=e25h* zGi{lRT}snjbMK~IUx|EGonH+w;iC2Ws)x>=5_{5$m?K z5(*1jMn%u0V1Y%m@`YS3kskt~`1p(rA4uk;Cs!w^KL$w>MH)+cP6|XKr4FfHIATJH z!EGAK4N>1yFR`-zW|w%ByRe#=&kA&#WyUldDGpt!wf-8SFWiSi!5QZL+l7*CE?u!NW1T$<1rdLJ9y3u{_zvHaM?#Rm4 zFk}^1!ffcrB|XK3gsO-s=wr*sUe&^$yN|KxrA)uW00Gu60%pw_+DcUjW`oW<35OC8 zq2{j8SgC}W$?10pvFU83(SL$%C?Kctu3*cs0aa%q!fjn1%xD*Jrm!F3HGR9-C{b?- zHp(cL;ezXMpL@0-1v0DMWddSDNZ5h?q50cOZyVi#bU3&PWE=(hpVn|M4_KYG5h9LffKNRsfhr^=SYiKg?#r&HNMi2@cd4aYL9lw(5_IvQJ zcB*DD()hUSAD^PdA0y|QrVnqwgI@pUXZXjHq3lG2OU&7sPOxxU$Y3&ytj6Qb=2#cC z;{d-{k|xI*bu+Vy&N+}{i(+1me!M;nshY_*&ZQLTGG*xNw#{RpI`3^eGfHck+*38NRgiGahkFethtVY=czJs#)VVc{T65rhU#3Vf?X)8f0)X{w!J3J{z|Sq|%?)nA+zo?$>L9@o`Kc|*7sJo4UjIqu0Ir~S5k^vEH};6K?-dZ0h*m%-1L zf!VC%YbM1~sZOG5zu&Sh>R;(md*_)kGHP)<;OA44W?y53PI%{&@MEN}9TOiqu+1a3AGetBr$c)Ao3OX>iGxmA;^^_alwS818r4Pn&uYe^;z6dh z)68T|AN=hjNdGpF7n>y+RTAZc9&opTXf zqWfK_dUv=mW{p_vN>|(cIkd(+Jy}qnK{IW%X*3!l`^H~FbAHwof+vLZ0C2ZXN1$v7 zgN&R9c8IO`fkR{6U%ERq8FN<1DQYbAN0-pH7EfcA{A&nhT!Be>jj>J!bNRw4NF|}! z1c70_#fkk!VQ!q1h2ff@`yDyrI1`np>*e#D4-Z~*!T^8#o*$V~!8bWQaie?P@KGBb z8rXc!YDL!$3ZgZZ%;-%~0Kn<+d+{xJ$stQbtN8GWV?MCJvzPU|(E(1z;rFw{&6vy) z3*@y%7Tx8rH-p$boS>bLyod?OKRE8v`QSBvGfY6f}_{Zo1q85xoyOF16n~yHx2W ziydUoYLkJmzq|n&2S(O!ZmLdP1(o1Jsq88cX)x3V-BK5eF&0e_0G!5?U7&3KN0`mc zH&Lt)q8!d_VgzxyL^(@xrbp2y)Hmr^V48));RSfE=*Ly0uh9!$3dv-vMZr2URf@l5zdwLjGZB zugY>7_fd_vbV*Qv1?H~>Z%RD%nEeFSI$n$$Lrpc6g>i4+XdBB!%zM$Bhrz5Swzyg? z$~I~n@~-wTBY3-T&pr+|gC+OHDoR?I(eLWa{Z#Rsh>lc~%u0!&R|s0pA*w<7QZ}{i z*AFr~0F3y~f$MGh_HDL7J_1?SxKL}fWIk!$G}`^{)xh*dZ5kK>xGL9>V`WZZg_ z)^Vm)EQK`yfh5KiR(vb&aHvhich z_5o+{d~0+4BEBqYJXyXBIEb1UgVDs;a!N2$9WA>CbfrWryqT25)S4E4)QXBd*3jN} z?phkAt`1rKW?xoLzEm!*IfkH|P>BtECVr0l8-IGk_`UjE#IWkUGqvyS+dMrCnFl<7RCgSMX^qn|Ld_4iYRldO zY&cHhv)GDo8nKvKwAbfyLR%t?9gG?R7~PSD#4D-;?F&!kV59O}neYut5AGbKwy-(U zqyBi=&Mgj|VIo>$u!DHM`R7O?W8-idbePuxiJMH``6c_5L-chKd}=rGC5Gfrc{f!* zWFEBm?l@_b7kzY7%1RQQbG5V<4=ZlkZ%sF74Q|mKOc7Ak7dP2#quiGcZ0_J%7Q?j{ zv9{WFw;n5G-Mn%r#0R;{jLt{yy}9J6rQ(>X9pJ`7Xy?Zv z=lNit#qXaq?CnElK^zF~sG}U5oCpR0T>FH=ZX}Prju$);?;VOhFH8L3I><9P_A|C+ z{;>~dk%9rrq(snjsEm}oUz2FQ21MCG*e?g)?{!&|eg7PX@I+Q0!hL6C7ZVY|g2E>i zr!Ri2@OfEu$)d52+>+cpgh6Z;cLYCZ&EMR0i<^~4&wEu_bdo;y^6}+U2GIQgW$|Od z_jg{O=pU>0-H$P-EOlWyQy#W0r@@_uT}Lg+!d5NxMii7aT1=|qm6BRaWOf{Pws54v zTu=}LR!V(JzI07>QR;;px0+zq=(s+XH-0~rVbmGp8<)7G+Jf)UYs<$Dd>-K+4}CsD zS}KYLmkbRvjwBO3PB%2@j(vOpm)!JABH_E7X^f#V-bzifSaKtE)|QrczC1$sC<<*Y z$hY*3E10fYk`2W09gM_U<2>+r^+ro$Bqh-O7uSa)cfPE_<#^O) zF+5V;-8LaCLKdIh3UB@idQZL`0Vx8`OE#6*1<;8(zi&E7MWB1S%~HAm%axyIHN2vd zA(pJGm_PraB0Aat3~?obWBs?iSc*NhM!{-l_WNCx4@F7I?)5&oI|z{o@JKd1HZ}zf*#}JjK3$ z-;3V*WJZvUcKvSOBH4c7C{fl8oRw8-vfgKQjNiR|KhQ%k6hWNEke(k8w-Ro| z7Y3)FsY-?7%;VT64vRM)l0%&HI~BXkSAOV#F3Bf#|3QLZM%6C{paqLTb3MU-_)`{R zRdfVQ)uX90VCa3ja$8m;cdtxQ*(tNjIfVb%#TCJWeH?o4RY#LWpyZBJHR| z6G-!4W5O^Z8U}e5GfZ!_M{B``ve{r0Z#CXV0x@~X#Pc;}{{ClY_uw^=wWurj0RKnoFzeY` z;gS!PCLCo*c}-hLc?C&wv&>P1hH75=p#;D3{Q8UZ0ctX!b)_@Ur=WCMEuz>pTs$@s z#7bIutL9Pm2FDb~d+H}uBI#pu6R}T{nzpz9U0XLb9lu@=9bTY&PEyFwhHHtXFX~6C zrcg|qqTk(|MIM%KQ<@j=DOjt|V)+8K26wE_CBNnZTg+Z+s}AU|jp6CFoIptG1{J*# z7Ne~l;ba*=bSwAMQ|Vq#fW~+je4PXA91YFzBubNF?ovIOw-$C-8=Ehed{lGD0}(Id zRe4sh8L>&T%{>8o))he}eE;5_ zxoXk3wX?MyNl-xF!q1d$G?=wp^`@09(jU&X zOqZIBI#dN`2PJNdATR3ivtub|nO$dulSaP|e4)WXF1YAGN1pDQIbIjXFG!oC85Mt; zW$eteoL{y^5t4TMRwP$jNPjZFpGsWnGe=jMMqKtcZm9Y9PFZLi*1p@qoKKub^T@2+ zk$@*KYdQ?Z`}<%4ALwk*Yc{(WTf@#u;as(fvE^9{Gk)lWbJP*SjttWofV0s?AB({~l zZI1hZVWFT~W-T?nfMMcnCS4-#6H-MU7H$KxD;yaM46K4Kc@~Q>xzB+QnD_I`b_l3m zo9pRx46b!p?a^&zCDwygqqV3epjs(s0NQI6ARA1n!Yy-qduipxQ& zUAlqRpNjBS+y-ZheD(!R;F}&^V_}b_gqH%tVZ5%%ziO7k^w=es+wZtK^i*vmrWNLMs{oWu_CIov|s1raZiS)>38>pYu;i+-t zI_DiNe6aA4KTZ2P09qPj(0~K4nUq^0+f(2$g`229zkG4jLzRvJUWE0oF1XHL4t3UN zDH466G56sy9hTZoAJB!C3;@F;ONxEk5u6Mv%zdo}Rq`=* zw1n7MOhfNSV48TS989ArIcj`C%Gk8~93~u>)!Yt2b4ZriKj9x2d`H2HQNJ=I>hkDlcZn zqRj>!;oRMTIOu zx|Zfsu~v76T{z7AC(jxj^c@tnJHZtGPsq$DE!8kqvkDx5W?KUJPL+!Ffpwfa+|5z5 zKPCiOPqZZrAG;2%OH0T$W|`C@C*!Z`@Wkop{CTjB&Tk`+{XPnt`ND`Haz;xV`H^RS zyXYtw@WlqTvToi;=mq1<-|IQ(gcOpU%)b#_46|IuWL#4$oYLbqwuk6=Q@xZaJSKVF zZcHs~ZBl;&lF3=+nK; zF`4gSCeZXlwmC_t4I`#PUNQ*)Uv&oGxMALip|sxv^lyVV73tKI7)+QY5=tEMas{vTD-BaTJ^*Y6gq~PU;F5X!sxqiq$iFCo+Uv7m%1w((=e}Vf*=dtds|6 zbX}91!G?C*KG03eHoN}RZS9DJxa&8YwNCT8?JxMXyZqZr13NA|GB{+vG`08C{V(yy zf*Lw$+tYSU_+dI`3n{bMrPdDb`A=Mkg!O=k>1|*3MC8j~- zXL79J4E=U^H=iBLTeHE_OKzE&dws8RNynsSJ!d;`zK?P92U{f)xvD7VQVosrXZrL+ z6lMVdD1YgL;%(1cq{#bS6yXmp|DS@nax#AqqlZhtUQdh<^2vr5`EpAO

LGYq)sa(w9^3-f}NHy=GR4v%t2YZly3m1G@5y`xBh_HGrD%f z>;|Ty?9FiJAc&UVD(StT4I` zfVQwxhE9bXE6r2mKO8Ag7{L^jCyqQb0QqKDPE=RAgqn8q1O^>(z7h5kE(6va%QqRZ zkIOmp(})rLSS(2{=C12e&@!W2=Jel-^_R``0xHO^+t!(oXbcv5yhD4g*$t_F)_5Dl zSVCgesW%;DtYPCFs{G;GX_o?1J3;QQPPv)rWw;>} zJ&KwnUqwNXloNXlK_+pNDfI~hON#SokVJb&ilg8d7^NWo2ZQymCqQMnjfi>ePibjr z-Z@q!?RGN$Mj}Nk){X_vaj6?Mj$>ACR*z|6MsXy3VZ^PFn@yHkPo(>m(iWepn8SC@ z>D2;R4m+gDRZ=SIX!b+CP(qE=JDIUkn=D$aUu+Ihn9-+k1LS3PreQg0N5eWIG@x${nC3v^7caS>1!PKNAY9J z#}E}Q9w#SP>(GY7Hbj&z4$Li6o5taBO|4+F`yS9zq*LJ<38wy4I>HA9(&GYrk4dLajKGww))BWli6Ln1A^Lda@N~p+snkb9C z@OthI+<##vp8!HVQT4Wk(=@zQ{OvZ$EKWS73+JHb)eYLGD-cqi6^|vd$<+IHuc?Nq zW7JertT~3))4?J|28n$I@nAD0c1%9C&IVhEZX~mUsf{efyS(XNG%ch;!N~d7S(Ri7 zb&=BuON95aVA&kLn6&MVU|x}xPMp7xwWxNU1wS+F6#y}1@^wQZB*(&ecT?RnQcI}Y z2*z!^!D?gDUhc@;M^OpLs4mq>C&p{}OWVv<)S9KMars@0JQ{c_ScGsFo3BJ)Irg++ zAWwypJdTO-_{Uh8m(Z!3KL7K{ZZzKHj;{M8I$mV>k znTM?sa0);^=X^cglL`uC+^J)M7nEa$w=VwFULg~%DJllw+7dJAj3{qnP5i3@wr7%y zjXp?Wl2%Th=my&3u?Q$RV6N5tzKMSPTsc#J+-cDDp~qFB6bL2C8AS7Y3PKtVhdhl) zIaLqH5+OnWPWSt(lQCgkN8lczc-V%_iZ{>#1%Z$N*>lu#S;0MZ$T2Y8Kg!U;hAZj> z6S#%$DQ_`Ic%Zr@?}GgjRXg@qTj^17n`65oJ@Wj0u1X8&+UVd|Xs?J+i_^GZ94m6= zUc96~Q`OJvlKB_Lr15*Yw_PUPEr?f?H&00b^-W%26mD)(n(rGGNfK9~2h=C>p-7BZ zFd&*&Msdu{w~(eyFOglwCPH^Rb}O(N7LtS+nnEwDx*pGD?|&9Si~M43a+*L(b0$5A zv`T`(G3xO;I_sx;FwTP21ZlfDpz zOo?}Vlgf~fo{YWm@n_JyD*frOg{XsvBA~|Tn4V6hu>Gd>89-rblfVJUaGvj6X%NZ} z$tFF9sx=4_$*c~G`9iPLGh@=sV+O{D2-t*K@J7H=`V+oVt}8?04WwU3h1BgS!f%1P zFak-T#7`TtLcR=Yz>g0R!ZQrH!YiZOQN=_V-UyncN1Rc18?KY?#O`v#JK+pq0K$~H z3D@v9DZF42R)b9#BBX{^$DOMlJ!g)Gc za{o-1e%F6NvgKq9tC8pV+9S$;9*zNv{J*)n&dmf~anP1)4~N%~h#c(=B#3*KgzhCKhFdgDoWi2IDog{RVyzK|Y`rCUs3T~pJMmdZJy4?b z&s5G=zhf**(t7Y^oC_mcTsE-{^}wiaoUu&?kojLKs>SJPxjcP>{a5CbXCx92AcBE) zHtqP}LjZ{W>PH?Tu(E0X=%{PBMW@F_?#7b&#!^q`<-5$ur+-q6 z{dn=(^UZw6*3-XM_(=@<1_*i&XM4=0t5u!gm6 z{UlmNGPKgO_;e;q9|#esq~Sq`<}%d{+sRmhvsA{5i*91=tub>OZZ%)xUA#4q$dDyy z1`w4%?OPLg3JeZb#cqSMO?*Xn%|-FCcuH2i2fn_{IFusub6;NQdN|7TD1N?%E8*g? z$apAt@cEe!I%jB=*q$p_3=t_5R0ph%{qaq+QDg!c99Y!Xa!&oDZOeis_ot)gNXr{l zdY$|So2Qed2Y7KMNBrS^E169kG%h<+z{Z_p_;shB!uY)>yAVcK=&!bg`lVg)4T1|7 z0}7FpfydVH4F87K@c!nEG+WGKm{Ouo)Slpl;#qcEIQ0zdMfLA#;dBxYw;p;KoVv6| z3_D5&7rJdG12CnDSvZUW?$UC6^UVSW^|vw|o-_4bz)(w5(3AiVhpeT(|=f#x_}E?s#qHZF#xA6AF_ujl$G z-jHD%q(d2}v2PhXx&6YWps~m(^+RXl91Q#xRRJBhjKl$FG4bk);|ag;ieUZ&!Ii3$ z(iGz1+0m7#g5>ASldBbNZL=ZHh=tmmJt$!71; zIML2GhEz1pg@1rQN(M^_691wAGkJ@Pga_05WuQ6! zG5RkGY2^`@(H~pp7&Ga+Pwh3L!Njj!-rc;^bTIfo5hP@H##1X8xUZJckrx>id`bAd3QUx9GuomqBYZ!uN1-&o zvTxC?;p8vL67&fW8fw(YOqt>L@bdLrEF*3OgYe$4n4{ zEB40LiU#6-0@5jdN`0w}N0qi@c0~oT2FP z)LNk&a82my?jv(tQpiMi$TK_L@lub#lsM$R{Dk?Ya@%%%huZkct~tSWM714c!45k}-ZLVA-bVM`>|_ZBbW_m-7| z3U%xrAhi}n?T(2F{_n4EZ10inkIFl#y09?7$uwBoJgqY8vylwev)fDOn;>0R!aEnV zBz%j0Mqpx~EZU3q@%+oV7;}|vt7$~ou@faEIq{p?FY$XXg&6*K)b_LP=}gi9`Bij3 zN`zEo|B6*|-;>S`rNa^BKRDbDAk>X#MsR`EvL>6bqU@SaDDs z8>bu@3YdRaWs*Te@G-UHjU%F~kTHw5(0PVJ+pwh#ha2u;DB+UMo@A5UYIl#5rtBV- zGX_hIpw}3C@H*Us(Cc-d#-gNrG#w$(9+S=GxO>3SR`SE2fHZ2KrDc#_C^$jI>Y}#; zMwY=R6@+dWi~0RXw(c@3GZ&%~9K(q&ee0Zw;pwL`E_tZak-#8^_b)Dpyi73^he?xV zXJ08&wh5-M&}qy4f7!D&=E)puDD(Nmg1d_(j`4LvxM5x_huNg-pGG%9rYqO6mImyJ@}*3Y>^3OvcnTG%EV1) zq_Ap?Z!Iw__7#D=pOWnQN$gB!Mr0!9yx|g<4icJh{cFOu3B8}&RiYm+Mb;VEK``LK zL(NcpcTiGieOIssSjr?ob}^``nNf&UcJhXyncO9m{6gD$kqSD`S69(aF8dkWz5>!9 zBLe4Sib7Hs2x_L2Ls6Ish$MGVKrGt5+_2zCyP1byaCg3upo+-I}R4&$m)8 zQ7|jc1Z^VWggpuQj*cP;>Zo9LS!VSzrqmZczaf;u`d0J(f%Z9r%An@s!e>n9%y=n!IZ_tVGu{Jmsbp}Fk%HJIU?a+-~bjfLTuH|JExA8EROowzr zqW9{YyZhR0a4clRK>1I4Ncx&WER~{iE;F^$T7K%X@3PGOA%6#Z%p3TS^&M;Dnjw@i z^o!$9nhcsmcHcY4?4j9+ofL_CWsZ4Hcch(rjsGfGD(nsH>w}^ERqGnz%iGj0j{g}h z7wMkJ-2Z2~eS>2!i}0~B63i;>SyFJU2+>VCS^AxaDOx%g6-t0eM^P<3+*z`ztvOqrG3)&#$K?& z_Y0wbWID47@cU`E1A6A&!`aZk0ZE@z-h#l1NqX2#`$Uev2gepW`rf8*!=rD5&;Jb{ zl08rU>dPo=K%-1Ao1~G-@4ve~y5#9E8x;TE0k5d^TC(=Zc>mwjW^c=+U-<9}b0ku~}gj z3sbW>R2M6DR!g#NUP;nxo>)@7*=RP{U18SDop6b2&PHce^&h97@xx3t+VK+!keE#} z;(Uf&89as9k8{$nkLbuB!-d7TP`_VJpL^Xs8OKB~ri$YUbW8fch64}7|0EWoT(TRj{ z*GT<7Y<7DsrCi79ZsM)z#c(!nNOGySOCkY1fAuQOq12&iUVC!a`#O;dBLf=d?&4*B zI~LgAO7E0qxK(uRTM;IgJ}+z^gD+bi-6I!3x{r9`l~%8TRP%UE0V8E*Sz>Nl1NVG<<7(wDHZ+HcOkQm$O&k+vyx)y)x{Pz!U8hS$*m zByc0h6BUI*BOpuL==P+H|Hx%`>7!W+1H!l9vi&)`V zyn2o9{z=lc+VX*!Vh~SF=)L}Z40XeG>LF6cP^b+R$NxSeUqbK^Q*UTalKzP8X%{9@RSCXm_NhF>{=S2 zi}ezam_^P`S!!-cyEW9y7DBbK93roz@Raccy*v}?mKXScU9E_4g;hBU7}zSofAFda zKYEe?{{I54 diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index a4413138..0aaefbca 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.8-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.1-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/gradlew b/gradlew index e69de29b..f5feea6d 100755 --- a/gradlew +++ b/gradlew @@ -0,0 +1,252 @@ +#!/bin/sh + +# +# Copyright © 2015-2021 the original authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# SPDX-License-Identifier: Apache-2.0 +# + +############################################################################## +# +# Gradle start up script for POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh Gradle +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# Darwin, MinGW, and NonStop. +# +# (3) This script is generated from the Groovy template +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# +############################################################################## + +# Attempt to set APP_HOME + +# Resolve links: $0 may be a link +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac +done + +# This is normally unused +# shellcheck disable=SC2034 +APP_BASE_NAME=${0##*/} +# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s +' "$PWD" ) || exit + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD=maximum + +warn () { + echo "$*" +} >&2 + +die () { + echo + echo "$*" + echo + exit 1 +} >&2 + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD=$JAVA_HOME/jre/sh/java + else + JAVACMD=$JAVA_HOME/bin/java + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD=java + if ! command -v java >/dev/null 2>&1 + then + die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +fi + +# Increase the maximum file descriptors if we can. +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac +fi + +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. + +# For Cygwin or MSYS, switch paths to Windows format before running java +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + + # Now convert the arguments - kludge to limit ourselves to /bin/sh + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) + fi + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg + done +fi + + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Collect all arguments for the java command: +# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# and any embedded shellness will be escaped. +# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be +# treated as '${Hostname}' itself on the command line. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$CLASSPATH" \ + org.gradle.wrapper.GradleWrapperMain \ + "$@" + +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' + +exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat index 25da30db..9d21a218 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## From 52282a8530460db153f97d0d187105ec1d1f0398 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Thu, 19 Sep 2024 21:25:03 +0900 Subject: [PATCH 318/371] =?UTF-8?q?fix:=20gathering=20=ED=8E=98=EC=9D=B4?= =?UTF-8?q?=EC=A7=80=EB=84=A4=EC=9D=B4=EC=85=98=20=EB=AA=A8=EC=9E=84=20?= =?UTF-8?q?=EC=88=AB=EC=9E=90=20=EC=98=A4=EB=A5=98,=20home=20=EC=97=90?= =?UTF-8?q?=EC=84=9C=20=EC=A2=8B=EC=95=84=EC=9A=94=20=ED=96=88=EB=8A=94?= =?UTF-8?q?=EC=A7=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../gathering/repository/GatheringRepositoryImpl.java | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryImpl.java b/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryImpl.java index 61d7b28a..bc9a1d9f 100644 --- a/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryImpl.java +++ b/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryImpl.java @@ -112,9 +112,10 @@ public Page getGatheringPageFilterAndOrder(Pageable page .on(bookMarkGathering.gathering.id.eq(gathering.id).and(bookMarkGathering.user.id.eq(userId))) .leftJoin(gatheringApplicants).on(gatheringApplicants.gathering.id.eq(gathering.id)) .where(booleanBuilder) - .select(gathering.id.count()).fetchCount(); + .select(gathering.id.countDistinct()).fetchCount(); List content = from(gathering) + .distinct() .join(zoneCategoryChild).on(zoneCategoryChild.id.eq(gathering.zoneCategory.id)) .leftJoin(zoneCategoryParent).on(zoneCategoryParent.id.eq(zoneCategoryChild.parentZoneCategory.id)) .leftJoin(bookMarkGathering) @@ -236,10 +237,10 @@ public List getGatheringRankList() { public List getGatheringLikeCountFromCreatedIn3(Long userId) { NumberExpression likeCount = countGreatGatheringByGatheringById(); return from(gathering) + .distinct() .join(zoneCategoryChild).on(zoneCategoryChild.id.eq(gathering.zoneCategory.id)) .leftJoin(zoneCategoryParent).on(zoneCategoryParent.id.eq(zoneCategoryChild.parentZoneCategory.id)) - .leftJoin(bookMarkGathering) - .on(bookMarkGathering.gathering.id.eq(gathering.id).and(bookMarkGathering.user.id.eq(userId))) + .leftJoin(bookMarkGathering).on(bookMarkGathering.gathering.id.eq(gathering.id).and(bookMarkGathering.user.id.eq(userId))) .leftJoin(category).on(category.id.eq(gathering.gatheringCategory.id)) .leftJoin(gatheringApplicants).on(gatheringApplicants.gathering.id.eq(gathering.id).and(gatheringApplicants.gatheringStatus.eq(GatheringStatus.CONSENT))) .where(gathering.isFinish.eq(Boolean.FALSE) @@ -261,7 +262,7 @@ public List getGatheringLikeCountFromCreatedIn3(Long use gathering.viewCount, bookMarkGathering.user.id.isNotNull(), likeCount, - category.name, + gathering.gatheringCategory.name, gathering.user.name, gathering.scheduleStartDate, gathering.scheduleEndDate, @@ -280,7 +281,6 @@ private BooleanBuilder makeWhereSQL(GatheringPageRequest gatheringPageRequest) { BooleanBuilder whereClause = new BooleanBuilder(); whereClause.and(gathering.isDeleted.eq(Boolean.FALSE)); -// whereClause.and(gathering.deadline.after(LocalDateTime.now())); if (Objects.nonNull(gatheringPageRequest.getCategory())) { whereClause.and(gathering.gatheringCategory.id.eq(gatheringPageRequest.getCategory())); } @@ -308,6 +308,7 @@ private BooleanBuilder makeWhereSQL(GatheringPageRequest gatheringPageRequest) { if (Objects.isNull(gatheringPageRequest.getIsExclude())) { whereClause.and(gathering.isFinish.eq(Boolean.FALSE)); + whereClause.and(gathering.deadline.after(LocalDateTime.now())); } if (Objects.nonNull(gatheringPageRequest.getSearch())) { From 398a6e9677513458fe493be104a0090ac859c149 Mon Sep 17 00:00:00 2001 From: Donghun Won Date: Thu, 19 Sep 2024 22:27:50 +0900 Subject: [PATCH 319/371] =?UTF-8?q?Fix=20:=20oauth=20=EB=A1=9C=EA=B7=B8?= =?UTF-8?q?=EC=9D=B8=20=EC=88=98=EC=A0=95,=20=EB=A7=88=EC=9D=B4=ED=8E=98?= =?UTF-8?q?=EC=9D=B4=EC=A7=80=20=EB=AA=A8=EC=9E=84=20=EC=98=A4=EB=A5=98=20?= =?UTF-8?q?=EC=88=98=EC=A0=95=20(#183)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 마이페이지 모임 조회 안되는 문제 수정 마이페이지 모임 인원수 계산 안되는 문제 수정 --- .gitignore | 1 + .../solitour/auth/service/OauthService.java | 3 +- .../solitour/auth/service/TokenService.java | 5 ++- .../dto/response/GatheringMypageResponse.java | 35 +++++++++++++++ .../user/controller/UserController.java | 9 ++-- .../user/repository/UserRepositoryCustom.java | 5 ++- .../user/repository/UserRepositoryImpl.java | 45 ++++++++++++------- .../solitour/user/service/UserService.java | 5 ++- src/main/resources/schema.sql | 3 +- 9 files changed, 84 insertions(+), 27 deletions(-) create mode 100644 src/main/java/solitour_backend/solitour/gathering/dto/response/GatheringMypageResponse.java diff --git a/.gitignore b/.gitignore index 0678df47..9bf4c60f 100644 --- a/.gitignore +++ b/.gitignore @@ -181,3 +181,4 @@ Temporary Items # 설정 파일 /src/main/resources/**.yml +/src/main/resources diff --git a/src/main/java/solitour_backend/solitour/auth/service/OauthService.java b/src/main/java/solitour_backend/solitour/auth/service/OauthService.java index ca47091e..60b77235 100644 --- a/src/main/java/solitour_backend/solitour/auth/service/OauthService.java +++ b/src/main/java/solitour_backend/solitour/auth/service/OauthService.java @@ -99,7 +99,8 @@ private User checkAndSaveUser(String type, String code, String redirectUrl) { User user = userRepository.findByOauthId(id) .orElseGet(() -> saveKakaoUser(kakaoUserResponse)); - tokenService.saveToken(tokenResponse, user); + Token token = tokenRepository.findByUserId(user.getId()) + .orElseGet(() -> tokenService.saveToken(tokenResponse, user)); return user; } diff --git a/src/main/java/solitour_backend/solitour/auth/service/TokenService.java b/src/main/java/solitour_backend/solitour/auth/service/TokenService.java index f6cc983c..99eebc6b 100644 --- a/src/main/java/solitour_backend/solitour/auth/service/TokenService.java +++ b/src/main/java/solitour_backend/solitour/auth/service/TokenService.java @@ -30,13 +30,14 @@ public void deleteByMemberId(Long memberId) { } @Transactional - public void saveToken(KakaoTokenResponse tokenResponse, User user) { + public Token saveToken(KakaoTokenResponse tokenResponse, User user) { Token token = Token.builder() .user(user) .oauthToken(tokenResponse.getRefreshToken()) - .refreshToken("test") .build(); tokenRepository.save(token); + + return token; } } diff --git a/src/main/java/solitour_backend/solitour/gathering/dto/response/GatheringMypageResponse.java b/src/main/java/solitour_backend/solitour/gathering/dto/response/GatheringMypageResponse.java new file mode 100644 index 00000000..ae28a0e3 --- /dev/null +++ b/src/main/java/solitour_backend/solitour/gathering/dto/response/GatheringMypageResponse.java @@ -0,0 +1,35 @@ +package solitour_backend.solitour.gathering.dto.response; + +import java.time.LocalDateTime; +import lombok.AllArgsConstructor; +import lombok.Getter; +import solitour_backend.solitour.gathering.entity.AllowedSex; + +@Getter +@AllArgsConstructor +public class GatheringMypageResponse { + private Long gatheringId; + private String title; + private String zoneCategoryParentName; + private String zoneCategoryChildName; + private Integer viewCount; + private Boolean isBookMark; + private Integer likeCount; + + private String gatheringCategoryName; + private String userName; + + private LocalDateTime scheduleStartDate; + private LocalDateTime scheduleEndDate; + + private LocalDateTime deadline; + + private AllowedSex allowedSex; + + private Integer startAge; + private Integer endAge; + private Integer personCount; + private Integer nowPersonCount; + private Boolean isLike; + private Boolean isFinish; +} diff --git a/src/main/java/solitour_backend/solitour/user/controller/UserController.java b/src/main/java/solitour_backend/solitour/user/controller/UserController.java index 73796131..9f0207f0 100644 --- a/src/main/java/solitour_backend/solitour/user/controller/UserController.java +++ b/src/main/java/solitour_backend/solitour/user/controller/UserController.java @@ -24,6 +24,7 @@ import solitour_backend.solitour.auth.support.kakao.KakaoConnector; import solitour_backend.solitour.gathering.dto.response.GatheringApplicantResponse; import solitour_backend.solitour.gathering.dto.response.GatheringBriefResponse; +import solitour_backend.solitour.gathering.dto.response.GatheringMypageResponse; import solitour_backend.solitour.information.dto.response.InformationBriefResponse; import solitour_backend.solitour.user.dto.UpdateAgeAndSex; import solitour_backend.solitour.user.dto.UpdateNicknameRequest; @@ -111,22 +112,22 @@ public ResponseEntity> retrieveInformationBookmar } @GetMapping("/mypage/gathering/host") - public ResponseEntity> retrieveGatheringHost( + public ResponseEntity> retrieveGatheringHost( @RequestParam(defaultValue = "0") int page, @AuthenticationPrincipal Long userId) { Pageable pageable = PageRequest.of(page, PAGE_SIZE); - Page response = userService.retrieveGatheringHost(pageable, userId); + Page response = userService.retrieveGatheringHost(pageable, userId); return ResponseEntity.ok(response); } @GetMapping("/mypage/gathering/bookmark") - public ResponseEntity> retrieveGatheringBookmark( + public ResponseEntity> retrieveGatheringBookmark( @RequestParam(defaultValue = "0") int page, @AuthenticationPrincipal Long userId) { Pageable pageable = PageRequest.of(page, PAGE_SIZE); - Page response = userService.retrieveGatheringBookmark(pageable, + Page response = userService.retrieveGatheringBookmark(pageable, userId); return ResponseEntity.ok(response); diff --git a/src/main/java/solitour_backend/solitour/user/repository/UserRepositoryCustom.java b/src/main/java/solitour_backend/solitour/user/repository/UserRepositoryCustom.java index 4d98c1ea..1ae4a264 100644 --- a/src/main/java/solitour_backend/solitour/user/repository/UserRepositoryCustom.java +++ b/src/main/java/solitour_backend/solitour/user/repository/UserRepositoryCustom.java @@ -5,6 +5,7 @@ import org.springframework.data.repository.NoRepositoryBean; import solitour_backend.solitour.gathering.dto.response.GatheringApplicantResponse; import solitour_backend.solitour.gathering.dto.response.GatheringBriefResponse; +import solitour_backend.solitour.gathering.dto.response.GatheringMypageResponse; import solitour_backend.solitour.information.dto.response.InformationBriefResponse; @@ -15,9 +16,9 @@ public interface UserRepositoryCustom { Page retrieveInformationBookmark(Pageable pageable, Long userId); - Page retrieveGatheringHost(Pageable pageable, Long userId); + Page retrieveGatheringHost(Pageable pageable, Long userId); - Page retrieveGatheringBookmark(Pageable pageable, Long userId); + Page retrieveGatheringBookmark(Pageable pageable, Long userId); Page retrieveGatheringApplicant(Pageable pageable, Long userId); diff --git a/src/main/java/solitour_backend/solitour/user/repository/UserRepositoryImpl.java b/src/main/java/solitour_backend/solitour/user/repository/UserRepositoryImpl.java index b2eade67..165203f4 100644 --- a/src/main/java/solitour_backend/solitour/user/repository/UserRepositoryImpl.java +++ b/src/main/java/solitour_backend/solitour/user/repository/UserRepositoryImpl.java @@ -19,7 +19,8 @@ import solitour_backend.solitour.book_mark_gathering.entity.QBookMarkGathering; import solitour_backend.solitour.book_mark_information.entity.QBookMarkInformation; import solitour_backend.solitour.gathering.dto.response.GatheringApplicantResponse; -import solitour_backend.solitour.gathering.dto.response.GatheringBriefResponse; +import solitour_backend.solitour.gathering.dto.response.GatheringMypageResponse; +import solitour_backend.solitour.gathering.dto.response.GatheringMypageResponse; import solitour_backend.solitour.gathering.entity.Gathering; import solitour_backend.solitour.gathering.entity.QGathering; import solitour_backend.solitour.gathering_applicants.entity.GatheringStatus; @@ -108,7 +109,7 @@ public Page retrieveInformationBookmark(Pageable pagea .leftJoin(image).on(image.information.id.eq(information.id) .and(image.imageStatus.eq(ImageStatus.THUMBNAIL))) .leftJoin(greatInformation).on(greatInformation.information.id.eq(information.id)) - .where(information.user.id.eq(userId).and(bookMarkInformation.user.id.eq(userId))); + .where(bookMarkInformation.user.id.eq(userId)); List list = query .groupBy(information.id, zoneCategoryParent.id, zoneCategoryChild.id, @@ -136,7 +137,7 @@ public Page retrieveInformationBookmark(Pageable pagea } @Override - public Page retrieveGatheringHost(Pageable pageable, Long userId) { + public Page retrieveGatheringHost(Pageable pageable, Long userId) { NumberExpression likeCount = countGreatGatheringByGatheringById(); BooleanExpression isBookMark = isGatheringBookmark(userId); @@ -150,11 +151,11 @@ public Page retrieveGatheringHost(Pageable pageable, Lon .orderBy(gathering.createdAt.desc()) .where(gathering.user.id.eq(userId)); - List list = query + List list = query .groupBy(gathering.id, zoneCategoryParent.id, zoneCategoryChild.id, gatheringCategory.id) .select(Projections.constructor( - GatheringBriefResponse.class, + GatheringMypageResponse.class, gathering.id, gathering.title, zoneCategoryParent.name, @@ -172,7 +173,8 @@ public Page retrieveGatheringHost(Pageable pageable, Lon gathering.endAge, gathering.personCount, gatheringApplicants.count().coalesce(0L).intValue(), - isUserGreatGathering(userId) + isUserGreatGathering(userId), + gathering.isFinish )) .offset(pageable.getOffset()) .limit(pageable.getPageSize()) @@ -183,7 +185,7 @@ public Page retrieveGatheringHost(Pageable pageable, Lon } @Override - public Page retrieveGatheringBookmark(Pageable pageable, Long userId) { + public Page retrieveGatheringBookmark(Pageable pageable, Long userId) { NumberExpression likeCount = countGreatGatheringByGatheringById(); BooleanExpression isBookMark = isGatheringBookmark(userId); @@ -199,11 +201,11 @@ public Page retrieveGatheringBookmark(Pageable pageable, .orderBy(gathering.createdAt.desc()) .where(bookMarkGathering.user.id.eq(userId)); - List list = query + List list = query .groupBy(gathering.id, zoneCategoryParent.id, zoneCategoryChild.id, gatheringCategory.id) .select(Projections.constructor( - GatheringBriefResponse.class, + GatheringMypageResponse.class, gathering.id, gathering.title, zoneCategoryParent.name, @@ -221,7 +223,8 @@ public Page retrieveGatheringBookmark(Pageable pageable, gathering.endAge, gathering.personCount, gatheringApplicants.count().coalesce(0L).intValue(), - isUserGreatGathering(userId) + isUserGreatGathering(userId), + gathering.isFinish )) .offset(pageable.getOffset()) .limit(pageable.getPageSize()) @@ -236,6 +239,8 @@ public Page retrieveGatheringApplicant(Pageable page NumberExpression likeCount = countGreatGatheringByGatheringById(); BooleanExpression isBookMark = isGatheringBookmark(userId); StringExpression gatheringStatus = getGatheringStatus(); + NumberExpression gatheringApplicantCount = countGatheringApplicant(userId); + JPQLQuery query = from(gathering) .leftJoin(zoneCategoryParent) @@ -243,15 +248,13 @@ public Page retrieveGatheringApplicant(Pageable page .leftJoin(gatheringCategory) .on(gatheringCategory.id.eq(gathering.gatheringCategory.id)) .leftJoin(gatheringApplicants) - .on(gatheringApplicants.gathering.id.eq(gathering.id).and(gatheringApplicants.gatheringStatus.eq(GatheringStatus.CONSENT))) - .leftJoin(gatheringApplicants) .on(gatheringApplicants.gathering.id.eq(gathering.id)) .orderBy(gathering.createdAt.desc()) .where(gatheringApplicants.user.id.eq(userId).and(gathering.user.id.eq(userId).not())); List list = query .groupBy(gathering.id, zoneCategoryParent.id, zoneCategoryChild.id, - gatheringCategory.id, gatheringApplicants.id) + gatheringCategory.id, gatheringApplicants.id) .select(Projections.constructor( GatheringApplicantResponse.class, gathering.id, @@ -270,8 +273,7 @@ public Page retrieveGatheringApplicant(Pageable page gathering.startAge, gathering.endAge, gathering.personCount, - gatheringApplicants.count().coalesce(0L).intValue(), - isUserGreatGathering(userId), + gatheringApplicantCount, isUserGreatGathering(userId), gatheringStatus, gathering.isFinish )) @@ -283,6 +285,19 @@ public Page retrieveGatheringApplicant(Pageable page return new PageImpl<>(list, pageable, total); } + private NumberExpression countGatheringApplicant(Long userId) { + QGatheringApplicants gatheringApplicants = QGatheringApplicants.gatheringApplicants; + + JPQLQuery countApplicant = JPAExpressions + .select(gatheringApplicants.count()) + .from(gatheringApplicants) + .where(gatheringApplicants.user.id.eq(userId).and(gatheringApplicants.gatheringStatus.eq(GatheringStatus.CONSENT))); + + return Expressions.numberTemplate(Long.class, "{0}", countApplicant) + .coalesce(0L) + .intValue(); + } + @Override public String getProfileUrl(String gender) { if ("male".equalsIgnoreCase(gender)) { diff --git a/src/main/java/solitour_backend/solitour/user/service/UserService.java b/src/main/java/solitour_backend/solitour/user/service/UserService.java index a8dc03ad..d0b5b0b2 100644 --- a/src/main/java/solitour_backend/solitour/user/service/UserService.java +++ b/src/main/java/solitour_backend/solitour/user/service/UserService.java @@ -9,6 +9,7 @@ import org.springframework.web.multipart.MultipartFile; import solitour_backend.solitour.gathering.dto.response.GatheringApplicantResponse; import solitour_backend.solitour.gathering.dto.response.GatheringBriefResponse; +import solitour_backend.solitour.gathering.dto.response.GatheringMypageResponse; import solitour_backend.solitour.image.s3.S3Uploader; import solitour_backend.solitour.information.dto.response.InformationBriefResponse; import solitour_backend.solitour.user.entity.User; @@ -64,11 +65,11 @@ public void updateUserProfile(Long userId, MultipartFile userProfile) { user.updateUserImage(response.getImageUrl()); } - public Page retrieveGatheringHost(Pageable pageable, Long userId) { + public Page retrieveGatheringHost(Pageable pageable, Long userId) { return userRepository.retrieveGatheringHost(pageable, userId); } - public Page retrieveGatheringBookmark(Pageable pageable, Long userId) { + public Page retrieveGatheringBookmark(Pageable pageable, Long userId) { return userRepository.retrieveGatheringBookmark(pageable, userId); } diff --git a/src/main/resources/schema.sql b/src/main/resources/schema.sql index 32ea927d..d9b1a94d 100644 --- a/src/main/resources/schema.sql +++ b/src/main/resources/schema.sql @@ -57,7 +57,8 @@ CREATE TABLE `token` ( `token_id` BIGINT NOT NULL AUTO_INCREMENT, `user_id` BIGINT NOT NULL, - `refresh_token` VARCHAR(250) NOT NULL, + `refresh_token` VARCHAR(250) NULL, + `oauth_token` VARCHAR(250) NULL, CONSTRAINT PK_TOKEN PRIMARY KEY (`token_id`), CONSTRAINT FK_USER_TO_TOKEN FOREIGN KEY (`user_id`) REFERENCES `user` (`user_id`) ); From d060ef43c89c54697dc93474ce534d8b5a28ce17 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Fri, 20 Sep 2024 01:54:21 +0900 Subject: [PATCH 320/371] =?UTF-8?q?fix:=20left=20join=20=EC=8B=9C=20?= =?UTF-8?q?=EC=A4=91=EB=B3=B5=20=EB=AC=B8=EC=A0=9C=20=ED=95=B4=EA=B2=B0=20?= =?UTF-8?q?->=20=EC=9D=BC=EB=B6=80=20=EC=84=9C=EB=B8=8C=20=EC=BF=BC?= =?UTF-8?q?=EB=A6=AC=EB=A1=9C=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../repository/GatheringRepositoryImpl.java | 62 +++++++++++-------- 1 file changed, 35 insertions(+), 27 deletions(-) diff --git a/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryImpl.java b/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryImpl.java index bc9a1d9f..340508ca 100644 --- a/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryImpl.java +++ b/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryImpl.java @@ -51,14 +51,11 @@ public GatheringRepositoryImpl() { @Override public List getGatheringRecommend(Long gatheringId, Long gatheringCategoryId, Long userId) { - + NumberExpression likeCount = countGreatGatheringByGatheringById(); + NumberExpression applicantsCount = applicantsCountNowConsent(); return from(gathering) .join(zoneCategoryChild).on(zoneCategoryChild.id.eq(gathering.zoneCategory.id)) .leftJoin(zoneCategoryParent).on(zoneCategoryParent.id.eq(zoneCategoryChild.parentZoneCategory.id)) - .leftJoin(bookMarkGathering) - .on(bookMarkGathering.gathering.id.eq(gathering.id).and(bookMarkGathering.user.id.eq(userId))) - .leftJoin(category).on(category.id.eq(gathering.gatheringCategory.id)) - .leftJoin(gatheringApplicants).on(gatheringApplicants.gathering.id.eq(gathering.id).and(gatheringApplicants.gatheringStatus.eq(GatheringStatus.CONSENT))) .where(gathering.isFinish.eq(Boolean.FALSE) .and(gathering.gatheringCategory.id.eq(gatheringCategoryId)) .and(gathering.id.ne(gatheringId)) @@ -78,9 +75,9 @@ public List getGatheringRecommend(Long gatheringId, Long zoneCategoryParent.name, zoneCategoryChild.name, gathering.viewCount, - bookMarkGathering.user.id.isNotNull(), - countGreatGatheringByGatheringById(), - category.name, + isGatheringBookmark(userId), + likeCount, + gathering.gatheringCategory.name, gathering.user.name, gathering.scheduleStartDate, gathering.scheduleEndDate, @@ -89,7 +86,7 @@ public List getGatheringRecommend(Long gatheringId, Long gathering.startAge, gathering.endAge, gathering.personCount, - gatheringApplicants.count().coalesce(0L).intValue(), + applicantsCount, isUserGreatGathering(userId) )).limit(3L).fetch(); } @@ -104,23 +101,15 @@ public Page getGatheringPageFilterAndOrder(Pageable page OrderSpecifier orderSpecifier = getOrderSpecifier(gatheringPageRequest.getSort()); NumberExpression countGreatGathering = countGreatGatheringByGatheringById(); + NumberExpression applicantsCount = applicantsCountNowConsent(); long total = from(gathering) - .join(zoneCategoryChild).on(zoneCategoryChild.id.eq(gathering.zoneCategory.id)) - .leftJoin(zoneCategoryParent).on(zoneCategoryParent.id.eq(zoneCategoryChild.parentZoneCategory.id)) - .leftJoin(bookMarkGathering) - .on(bookMarkGathering.gathering.id.eq(gathering.id).and(bookMarkGathering.user.id.eq(userId))) - .leftJoin(gatheringApplicants).on(gatheringApplicants.gathering.id.eq(gathering.id)) .where(booleanBuilder) - .select(gathering.id.countDistinct()).fetchCount(); + .select(gathering.id).fetchCount(); List content = from(gathering) - .distinct() .join(zoneCategoryChild).on(zoneCategoryChild.id.eq(gathering.zoneCategory.id)) .leftJoin(zoneCategoryParent).on(zoneCategoryParent.id.eq(zoneCategoryChild.parentZoneCategory.id)) - .leftJoin(bookMarkGathering) - .on(bookMarkGathering.gathering.id.eq(gathering.id).and(bookMarkGathering.user.id.eq(userId))) - .leftJoin(gatheringApplicants).on(gatheringApplicants.gathering.id.eq(gathering.id).and(gatheringApplicants.gatheringStatus.eq(GatheringStatus.CONSENT))) .where(booleanBuilder) .groupBy(gathering.id, zoneCategoryChild.id, zoneCategoryParent.id, category.id, gathering.title, gathering.viewCount, gathering.user.name, @@ -135,7 +124,7 @@ public Page getGatheringPageFilterAndOrder(Pageable page zoneCategoryParent.name, zoneCategoryChild.name, gathering.viewCount, - bookMarkGathering.user.id.isNotNull(), + isGatheringBookmark(userId), countGreatGathering, gathering.gatheringCategory.name, gathering.user.name, @@ -146,7 +135,7 @@ public Page getGatheringPageFilterAndOrder(Pageable page gathering.startAge, gathering.endAge, gathering.personCount, - gatheringApplicants.count().coalesce(0L).intValue(), + applicantsCount, isUserGreatGathering(userId) )) .offset(pageable.getOffset()) @@ -236,13 +225,10 @@ public List getGatheringRankList() { @Override public List getGatheringLikeCountFromCreatedIn3(Long userId) { NumberExpression likeCount = countGreatGatheringByGatheringById(); + NumberExpression applicantsCount = applicantsCountNowConsent(); return from(gathering) - .distinct() .join(zoneCategoryChild).on(zoneCategoryChild.id.eq(gathering.zoneCategory.id)) .leftJoin(zoneCategoryParent).on(zoneCategoryParent.id.eq(zoneCategoryChild.parentZoneCategory.id)) - .leftJoin(bookMarkGathering).on(bookMarkGathering.gathering.id.eq(gathering.id).and(bookMarkGathering.user.id.eq(userId))) - .leftJoin(category).on(category.id.eq(gathering.gatheringCategory.id)) - .leftJoin(gatheringApplicants).on(gatheringApplicants.gathering.id.eq(gathering.id).and(gatheringApplicants.gatheringStatus.eq(GatheringStatus.CONSENT))) .where(gathering.isFinish.eq(Boolean.FALSE) .and(gathering.isDeleted.eq(Boolean.FALSE)) .and(gathering.createdAt.after(LocalDateTime.now().minusMonths(3))) @@ -260,7 +246,7 @@ public List getGatheringLikeCountFromCreatedIn3(Long use zoneCategoryParent.name, zoneCategoryChild.name, gathering.viewCount, - bookMarkGathering.user.id.isNotNull(), + isGatheringBookmark(userId), likeCount, gathering.gatheringCategory.name, gathering.user.name, @@ -271,7 +257,7 @@ public List getGatheringLikeCountFromCreatedIn3(Long use gathering.startAge, gathering.endAge, gathering.personCount, - gatheringApplicants.count().coalesce(0L).intValue(), + applicantsCount, isUserGreatGathering(userId) )).limit(6L).fetch(); } @@ -358,4 +344,26 @@ private BooleanExpression isUserGreatGathering(Long userId) { .otherwise(false); } + private BooleanExpression isGatheringBookmark(Long userId) { + return new CaseBuilder() + .when(JPAExpressions.selectOne() + .from(bookMarkGathering) + .where(bookMarkGathering.gathering.id.eq(gathering.id) + .and(bookMarkGathering.user.id.eq(userId))) + .exists()) + .then(true) + .otherwise(false); + } + + private NumberExpression applicantsCountNowConsent() { + JPQLQuery applicantsCountSubQuery = JPAExpressions + .select(gatheringApplicants.count().intValue()) + .from(gatheringApplicants) + .where(gatheringApplicants.gathering.id.eq(gathering.id) + .and(gatheringApplicants.gatheringStatus.eq(GatheringStatus.CONSENT))); + + return Expressions.numberTemplate(Integer.class, "{0}", applicantsCountSubQuery) + .coalesce(0); + } + } From 1d6df565ba2a6083fe3755163db2a0d0a97d7c8b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=85=B8=ED=98=84=EC=A7=84?= Date: Sat, 21 Sep 2024 20:43:44 +0900 Subject: [PATCH 321/371] =?UTF-8?q?Fix:=20=EB=AA=A8=EC=9E=84=20=EC=82=AC?= =?UTF-8?q?=EC=9A=A9=EC=9E=90=20=EB=B3=B8=EB=AA=85=20=EB=8C=80=EC=8B=A0=20?= =?UTF-8?q?=EB=8B=89=EB=84=A4=EC=9E=84=20=EC=A0=84=EB=8B=AC=20(#185)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * refactor: zone_category에 "세종" 추가 * fix: 모임 작성자 본명이 아니라 닉네임 전달 --- .../gathering/dto/response/GatheringBriefResponse.java | 2 +- .../gathering/repository/GatheringRepositoryImpl.java | 4 ++-- src/main/resources/zone_category.sql | 5 +++-- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/main/java/solitour_backend/solitour/gathering/dto/response/GatheringBriefResponse.java b/src/main/java/solitour_backend/solitour/gathering/dto/response/GatheringBriefResponse.java index 2d34c161..0451bbd0 100644 --- a/src/main/java/solitour_backend/solitour/gathering/dto/response/GatheringBriefResponse.java +++ b/src/main/java/solitour_backend/solitour/gathering/dto/response/GatheringBriefResponse.java @@ -17,7 +17,7 @@ public class GatheringBriefResponse { private Integer likeCount; private String gatheringCategoryName; - private String userName; + private String nickname; private LocalDateTime scheduleStartDate; private LocalDateTime scheduleEndDate; diff --git a/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryImpl.java b/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryImpl.java index 340508ca..8e2bc14d 100644 --- a/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryImpl.java +++ b/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryImpl.java @@ -127,7 +127,7 @@ public Page getGatheringPageFilterAndOrder(Pageable page isGatheringBookmark(userId), countGreatGathering, gathering.gatheringCategory.name, - gathering.user.name, + gathering.user.nickname, gathering.scheduleStartDate, gathering.scheduleEndDate, gathering.deadline, @@ -249,7 +249,7 @@ public List getGatheringLikeCountFromCreatedIn3(Long use isGatheringBookmark(userId), likeCount, gathering.gatheringCategory.name, - gathering.user.name, + gathering.user.nickname, gathering.scheduleStartDate, gathering.scheduleEndDate, gathering.deadline, diff --git a/src/main/resources/zone_category.sql b/src/main/resources/zone_category.sql index a9eaa9a9..ab22ac72 100644 --- a/src/main/resources/zone_category.sql +++ b/src/main/resources/zone_category.sql @@ -276,5 +276,6 @@ VALUES (16, '전주시'), (16, '무주군'), (16, '장수군'); -# INSERT INTO `zone_category` (`parent_zone_category_id`, `zone_category_name`) -# VALUES (17, '세종'); \ No newline at end of file +INSERT INTO `zone_category` (`parent_zone_category_id`, `zone_category_name`) VALUES (NULL, '세종'); +INSERT INTO `zone_category` (`parent_zone_category_id`, `zone_category_name`) VALUES (245, '세종'); + From 6436730635a6a49f6ffc08c44f3e9f1f140a754e Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Sat, 21 Sep 2024 21:02:15 +0900 Subject: [PATCH 322/371] =?UTF-8?q?refactor:=20name=20->=20nickname=20?= =?UTF-8?q?=ED=95=84=EB=93=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../solitour/gathering/dto/response/GatheringBriefResponse.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/solitour_backend/solitour/gathering/dto/response/GatheringBriefResponse.java b/src/main/java/solitour_backend/solitour/gathering/dto/response/GatheringBriefResponse.java index 2d34c161..0451bbd0 100644 --- a/src/main/java/solitour_backend/solitour/gathering/dto/response/GatheringBriefResponse.java +++ b/src/main/java/solitour_backend/solitour/gathering/dto/response/GatheringBriefResponse.java @@ -17,7 +17,7 @@ public class GatheringBriefResponse { private Integer likeCount; private String gatheringCategoryName; - private String userName; + private String nickname; private LocalDateTime scheduleStartDate; private LocalDateTime scheduleEndDate; From 216d13ab3e92f57dd2bf0580a5188ba7c8763f75 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Sat, 21 Sep 2024 21:02:24 +0900 Subject: [PATCH 323/371] =?UTF-8?q?refactor:=20name=20->=20nickname=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 --- .../gathering/repository/GatheringRepositoryImpl.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryImpl.java b/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryImpl.java index 340508ca..c614e7fc 100644 --- a/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryImpl.java +++ b/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryImpl.java @@ -78,7 +78,7 @@ public List getGatheringRecommend(Long gatheringId, Long isGatheringBookmark(userId), likeCount, gathering.gatheringCategory.name, - gathering.user.name, + gathering.user.nickname, gathering.scheduleStartDate, gathering.scheduleEndDate, gathering.deadline, @@ -127,7 +127,7 @@ public Page getGatheringPageFilterAndOrder(Pageable page isGatheringBookmark(userId), countGreatGathering, gathering.gatheringCategory.name, - gathering.user.name, + gathering.user.nickname, gathering.scheduleStartDate, gathering.scheduleEndDate, gathering.deadline, @@ -249,7 +249,7 @@ public List getGatheringLikeCountFromCreatedIn3(Long use isGatheringBookmark(userId), likeCount, gathering.gatheringCategory.name, - gathering.user.name, + gathering.user.nickname, gathering.scheduleStartDate, gathering.scheduleEndDate, gathering.deadline, From cdba1e92f869a10ec41911b56c13524886b69187 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Sat, 21 Sep 2024 21:02:48 +0900 Subject: [PATCH 324/371] =?UTF-8?q?feat:=20category=20name=20=EB=8D=B0?= =?UTF-8?q?=EC=9D=B4=ED=84=B0=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../information/dto/response/InformationBriefResponse.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/solitour_backend/solitour/information/dto/response/InformationBriefResponse.java b/src/main/java/solitour_backend/solitour/information/dto/response/InformationBriefResponse.java index b1665862..c8332111 100644 --- a/src/main/java/solitour_backend/solitour/information/dto/response/InformationBriefResponse.java +++ b/src/main/java/solitour_backend/solitour/information/dto/response/InformationBriefResponse.java @@ -11,6 +11,7 @@ public class InformationBriefResponse { private String title; private String zoneCategoryParentName; private String zoneCategoryChildName; + private String categoryName; private Integer viewCount; private Boolean isBookMark; private String thumbNailImage; From fa9cc189417a7003ef36e37c1a4a32baedeb7e46 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Sat, 21 Sep 2024 21:03:05 +0900 Subject: [PATCH 325/371] =?UTF-8?q?refactor:=20=EC=BF=BC=EB=A6=AC=EB=AC=B8?= =?UTF-8?q?=20=EA=B0=9C=EC=84=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../repository/InformationRepositoryImpl.java | 42 +++++++++---------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/src/main/java/solitour_backend/solitour/information/repository/InformationRepositoryImpl.java b/src/main/java/solitour_backend/solitour/information/repository/InformationRepositoryImpl.java index a19e228f..ce3b4455 100644 --- a/src/main/java/solitour_backend/solitour/information/repository/InformationRepositoryImpl.java +++ b/src/main/java/solitour_backend/solitour/information/repository/InformationRepositoryImpl.java @@ -76,25 +76,15 @@ public Page getInformationPageFilterAndOrder(Pageable NumberExpression countGreatInformation = countGreatInformationByInformationById(); long total = from(information) - .join(zoneCategoryChild).on(zoneCategoryChild.id.eq(information.zoneCategory.id)) - .leftJoin(zoneCategoryParent).on(zoneCategoryParent.id.eq(zoneCategoryChild.parentZoneCategory.id)) - .leftJoin(bookMarkInformation) - .on(bookMarkInformation.information.id.eq(information.id).and(bookMarkInformation.user.id.eq(userId))) - .leftJoin(image) - .on(image.information.id.eq(information.id).and(image.imageStatus.eq(ImageStatus.THUMBNAIL))) - .join(category).on(category.id.eq(information.category.id).and(categoryCondition)) .where(whereClause) - .select(information.count()).fetchCount(); + .select(information.id).fetchCount(); List list = from(information) .join(zoneCategoryChild).on(zoneCategoryChild.id.eq(information.zoneCategory.id)) .leftJoin(zoneCategoryParent).on(zoneCategoryParent.id.eq(zoneCategoryChild.parentZoneCategory.id)) - .leftJoin(bookMarkInformation) - .on(bookMarkInformation.information.id.eq(information.id).and(bookMarkInformation.user.id.eq(userId))) .leftJoin(image) .on(image.information.id.eq(information.id).and(image.imageStatus.eq(ImageStatus.THUMBNAIL))) .join(category).on(category.id.eq(information.category.id).and(categoryCondition)) - .leftJoin(greatInformation).on(greatInformation.information.id.eq(information.id)) .where(whereClause) .groupBy(information.id, zoneCategoryChild.id, zoneCategoryParent.id, image.id) .orderBy(orderSpecifier) @@ -104,8 +94,9 @@ public Page getInformationPageFilterAndOrder(Pageable information.title, zoneCategoryParent.name, zoneCategoryChild.name, + information.category.name, information.viewCount, - bookMarkInformation.user.id.isNotNull(), + isInformationBookmark(userId), image.address, countGreatInformation, isUserGreatInformation(userId) @@ -122,11 +113,8 @@ public List getInformationLikeCountFromCreatedIn3(Long return from(information) .leftJoin(zoneCategoryChild).on(zoneCategoryChild.id.eq(information.zoneCategory.id)) .leftJoin(zoneCategoryParent).on(zoneCategoryParent.id.eq(zoneCategoryChild.parentZoneCategory.id)) - .leftJoin(bookMarkInformation) - .on(bookMarkInformation.information.id.eq(information.id).and(bookMarkInformation.user.id.eq(userId))) .leftJoin(image) .on(image.information.id.eq(information.id).and(image.imageStatus.eq(ImageStatus.THUMBNAIL))) - .leftJoin(greatInformation).on(greatInformation.information.id.eq(information.id)) .leftJoin(category).on(category.id.eq(information.category.id)) .where(information.createdDate.after(LocalDateTime.now().minusMonths(3))) .groupBy(information.id, information.title, zoneCategoryParent.name, zoneCategoryChild.name, @@ -140,7 +128,7 @@ public List getInformationLikeCountFromCreatedIn3(Long zoneCategoryChild.name, category.parentCategory.name, information.viewCount, - bookMarkInformation.user.id.isNotNull(), + isInformationBookmark(userId), image.address, countGreatInformationByInformationById(), isUserGreatInformation(userId) @@ -154,11 +142,8 @@ public List getInformationRecommend(Long informationId return from(information) .join(zoneCategoryChild).on(zoneCategoryChild.id.eq(information.zoneCategory.id)) .leftJoin(zoneCategoryParent).on(zoneCategoryParent.id.eq(zoneCategoryChild.parentZoneCategory.id)) - .leftJoin(bookMarkInformation) - .on(bookMarkInformation.information.id.eq(information.id).and(bookMarkInformation.user.id.eq(userId))) .leftJoin(image).on(image.information.id.eq(information.id) .and(image.imageStatus.eq(ImageStatus.THUMBNAIL))) - .leftJoin(greatInformation).on(greatInformation.information.id.eq(information.id)) .where(information.category.id.eq(childCategoryId).and(information.id.ne(informationId))) .groupBy(information.id, zoneCategoryChild.id, zoneCategoryParent.id, image.id) .orderBy(information.createdDate.desc()) @@ -168,8 +153,9 @@ public List getInformationRecommend(Long informationId information.title, zoneCategoryParent.name, zoneCategoryChild.name, + information.category.name, information.viewCount, - bookMarkInformation.user.id.isNotNull(), + isInformationBookmark(userId), image.address, countGreatInformationByInformationById(), isUserGreatInformation(userId) @@ -233,6 +219,7 @@ public Page getInformationPageByTag(Pageable pageable, information.title, zoneCategoryParent.name, zoneCategoryChild.name, + information.category.name, information.viewCount, bookMarkInformation.user.id.isNotNull(), image.address, @@ -278,7 +265,9 @@ private NumberExpression countGreatInformationByInformationById() { .from(greatInformationSub) .where(greatInformationSub.information.id.eq(information.id)); - return Expressions.numberTemplate(Long.class, "{0}", likeCountSubQuery).coalesce(0L).intValue(); + return Expressions.numberTemplate(Long.class, "{0}", likeCountSubQuery) + .coalesce(0L) + .intValue(); } private BooleanExpression isUserGreatInformation(Long userId) { @@ -292,5 +281,16 @@ private BooleanExpression isUserGreatInformation(Long userId) { .otherwise(false); } + private BooleanExpression isInformationBookmark(Long userId) { + return new CaseBuilder() + .when(JPAExpressions.selectOne() + .from(bookMarkInformation) + .where(bookMarkInformation.information.id.eq(information.id) + .and(bookMarkInformation.user.id.eq(userId))) + .exists()) + .then(true) + .otherwise(false); + } + } From 8f3234ce9a3930f69c558224fbb506c4009e56c4 Mon Sep 17 00:00:00 2001 From: Donghun Won Date: Sat, 21 Sep 2024 23:07:45 +0900 Subject: [PATCH 326/371] =?UTF-8?q?Feat=20:=20=EC=9C=A0=EC=A0=80=20?= =?UTF-8?q?=EB=B8=94=EB=9D=BD=20=EA=B8=B0=EB=8A=A5=20(#186)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../auth/controller/OauthController.java | 10 ++++++---- .../solitour/auth/service/OauthService.java | 19 +++++++++++++++++-- .../service/dto/response/LoginResponse.java | 2 ++ .../error/GlobalControllerAdvice.java | 16 +++++++++++++++- .../user/controller/UserController.java | 3 --- .../user/exception/BlockedUserException.java | 8 ++++++++ .../user/exception/DeletedUserException.java | 8 ++++++++ .../user/exception/DormantUserException.java | 8 ++++++++ .../solitour/user/user_status/UserStatus.java | 2 ++ 9 files changed, 66 insertions(+), 10 deletions(-) create mode 100644 src/main/java/solitour_backend/solitour/user/exception/BlockedUserException.java create mode 100644 src/main/java/solitour_backend/solitour/user/exception/DeletedUserException.java create mode 100644 src/main/java/solitour_backend/solitour/user/exception/DormantUserException.java diff --git a/src/main/java/solitour_backend/solitour/auth/controller/OauthController.java b/src/main/java/solitour_backend/solitour/auth/controller/OauthController.java index 6428b2dd..c745848d 100644 --- a/src/main/java/solitour_backend/solitour/auth/controller/OauthController.java +++ b/src/main/java/solitour_backend/solitour/auth/controller/OauthController.java @@ -24,6 +24,7 @@ import solitour_backend.solitour.auth.service.dto.response.OauthLinkResponse; import solitour_backend.solitour.auth.support.google.GoogleConnector; import solitour_backend.solitour.auth.support.kakao.KakaoConnector; +import solitour_backend.solitour.user.user_status.UserStatus; @RequiredArgsConstructor @@ -43,8 +44,8 @@ public ResponseEntity access(@RequestParam String type, @Requ } @GetMapping(value = "/login", params = {"type", "code", "redirectUrl"}) - public ResponseEntity login(HttpServletResponse response, @RequestParam String type, - @RequestParam String code, @RequestParam String redirectUrl) { + public ResponseEntity login(HttpServletResponse response, @RequestParam String type, + @RequestParam String code, @RequestParam String redirectUrl) { LoginResponse loginResponse = oauthService.requestAccessToken(type, code, redirectUrl); String accessCookieHeader = setCookieHeader(loginResponse.getAccessToken()); @@ -53,7 +54,7 @@ public ResponseEntity login(HttpServletResponse response, @Reques response.addHeader("Set-Cookie", accessCookieHeader); response.addHeader("Set-Cookie", refreshCookieHeader); - return ResponseEntity.ok().build(); + return ResponseEntity.ok(loginResponse.getLoginStatus()); } @PostMapping("/logout") @@ -77,7 +78,8 @@ public ResponseEntity reissueAccessToken(HttpServletResponse response, @Authenticated @DeleteMapping() - public ResponseEntity deleteUser(HttpServletResponse response, @AuthenticationPrincipal Long id, @RequestParam String type) { + public ResponseEntity deleteUser(HttpServletResponse response, @AuthenticationPrincipal Long id, + @RequestParam String type) { Token token = tokenRepository.findByUserId(id) .orElseThrow(() -> new TokenNotExistsException("토큰이 존재하지 않습니다")); String oauthRefreshToken = getOauthAccessToken(type, token.getOauthToken()); diff --git a/src/main/java/solitour_backend/solitour/auth/service/OauthService.java b/src/main/java/solitour_backend/solitour/auth/service/OauthService.java index 60b77235..7d0946a8 100644 --- a/src/main/java/solitour_backend/solitour/auth/service/OauthService.java +++ b/src/main/java/solitour_backend/solitour/auth/service/OauthService.java @@ -7,6 +7,7 @@ import java.time.LocalDateTime; import java.util.Objects; import java.util.concurrent.TimeUnit; +import jdk.jshell.spi.ExecutionControl.UserException; import lombok.RequiredArgsConstructor; import org.springframework.beans.factory.annotation.Value; import org.springframework.http.HttpStatusCode; @@ -29,6 +30,9 @@ import solitour_backend.solitour.auth.support.kakao.dto.KakaoUserResponse; import solitour_backend.solitour.image.s3.S3Uploader; import solitour_backend.solitour.user.entity.User; +import solitour_backend.solitour.user.exception.BlockedUserException; +import solitour_backend.solitour.user.exception.DeletedUserException; +import solitour_backend.solitour.user.exception.DormantUserException; import solitour_backend.solitour.user.repository.UserRepository; import solitour_backend.solitour.user.user_status.UserStatus; import solitour_backend.solitour.user_image.entity.UserImage; @@ -77,7 +81,7 @@ public LoginResponse requestAccessToken(String type, String code, String redirec Cookie accessCookie = createCookie("access_token", token, ACCESS_COOKIE_AGE); Cookie refreshCookie = createCookie("refresh_token", refreshToken, REFRESH_COOKIE_AGE); - return new LoginResponse(accessCookie, refreshCookie); + return new LoginResponse(accessCookie, refreshCookie,user.getUserStatus()); } private Cookie createCookie(String name, String value, int maxAge) { @@ -99,6 +103,8 @@ private User checkAndSaveUser(String type, String code, String redirectUrl) { User user = userRepository.findByOauthId(id) .orElseGet(() -> saveKakaoUser(kakaoUserResponse)); + checkUserStatus(user); + Token token = tokenRepository.findByUserId(user.getId()) .orElseGet(() -> tokenService.saveToken(tokenResponse, user)); @@ -115,6 +121,15 @@ private User checkAndSaveUser(String type, String code, String redirectUrl) { } } + private void checkUserStatus(User user) { + UserStatus userStatus = user.getUserStatus(); + switch (userStatus){ + case BLOCK -> throw new BlockedUserException("차단된 계정입니다."); + case DELETE -> throw new DeletedUserException("탈퇴한 계정입니다."); + case DORMANT -> throw new DormantUserException("휴면 계정입니다."); + } + } + private void saveToken(KakaoTokenResponse tokenResponse, User user) { Token token = Token.builder() .user(user) @@ -160,7 +175,7 @@ private User saveKakaoUser(KakaoUserResponse response) { UserImage savedUserImage = userImageService.saveUserImage(imageUrl); User user = User.builder() - .userStatus(UserStatus.ACTIVATE) + .userStatus(UserStatus.INACTIVATE) .oauthId(String.valueOf(response.getId())) .provider("kakao") .isAdmin(false) diff --git a/src/main/java/solitour_backend/solitour/auth/service/dto/response/LoginResponse.java b/src/main/java/solitour_backend/solitour/auth/service/dto/response/LoginResponse.java index 5a7a3966..572a9c2f 100644 --- a/src/main/java/solitour_backend/solitour/auth/service/dto/response/LoginResponse.java +++ b/src/main/java/solitour_backend/solitour/auth/service/dto/response/LoginResponse.java @@ -5,6 +5,7 @@ import lombok.AllArgsConstructor; import lombok.Getter; import lombok.NoArgsConstructor; +import solitour_backend.solitour.user.user_status.UserStatus; @Getter @NoArgsConstructor(access = AccessLevel.PRIVATE) @@ -13,4 +14,5 @@ public class LoginResponse { private Cookie accessToken; private Cookie refreshToken; + private UserStatus loginStatus; } diff --git a/src/main/java/solitour_backend/solitour/error/GlobalControllerAdvice.java b/src/main/java/solitour_backend/solitour/error/GlobalControllerAdvice.java index eacf1021..d9f9bdf9 100644 --- a/src/main/java/solitour_backend/solitour/error/GlobalControllerAdvice.java +++ b/src/main/java/solitour_backend/solitour/error/GlobalControllerAdvice.java @@ -26,6 +26,9 @@ import solitour_backend.solitour.image.exception.ImageRequestValidationFailedException; import solitour_backend.solitour.information.exception.InformationNotExistsException; import solitour_backend.solitour.information.exception.InformationNotManageException; +import solitour_backend.solitour.user.exception.BlockedUserException; +import solitour_backend.solitour.user.exception.DeletedUserException; +import solitour_backend.solitour.user.exception.DormantUserException; import solitour_backend.solitour.user.exception.UserNotExistsException; import solitour_backend.solitour.zone_category.exception.ZoneCategoryAlreadyExistsException; import solitour_backend.solitour.zone_category.exception.ZoneCategoryNotExistsException; @@ -81,7 +84,9 @@ public ResponseEntity notFoundException(Exception exception) { } @ExceptionHandler({GatheringNotManagerException.class, - ForbiddenAccessException.class + ForbiddenAccessException.class, + BlockedUserException.class, + DeletedUserException.class }) public ResponseEntity forbiddenException(Exception exception) { return ResponseEntity @@ -89,6 +94,15 @@ public ResponseEntity forbiddenException(Exception exception) { .body(exception.getMessage()); } + @ExceptionHandler({ + DormantUserException.class + }) + public ResponseEntity dormantException(Exception exception) { + return ResponseEntity + .status(HttpStatus.LOCKED) + .body(exception.getMessage()); + } + @ExceptionHandler({ TokenNotExistsException.class }) diff --git a/src/main/java/solitour_backend/solitour/user/controller/UserController.java b/src/main/java/solitour_backend/solitour/user/controller/UserController.java index 9f0207f0..7d32079c 100644 --- a/src/main/java/solitour_backend/solitour/user/controller/UserController.java +++ b/src/main/java/solitour_backend/solitour/user/controller/UserController.java @@ -40,9 +40,6 @@ public class UserController { private final UserService userService; - private final OauthService oauthservice; - private final KakaoConnector kakaoConnector; - private final GoogleConnector googleConnector; public static final int PAGE_SIZE = 6; diff --git a/src/main/java/solitour_backend/solitour/user/exception/BlockedUserException.java b/src/main/java/solitour_backend/solitour/user/exception/BlockedUserException.java new file mode 100644 index 00000000..45873406 --- /dev/null +++ b/src/main/java/solitour_backend/solitour/user/exception/BlockedUserException.java @@ -0,0 +1,8 @@ +package solitour_backend.solitour.user.exception; + +public class BlockedUserException extends RuntimeException { + + public BlockedUserException(String message) { + super(message); + } +} diff --git a/src/main/java/solitour_backend/solitour/user/exception/DeletedUserException.java b/src/main/java/solitour_backend/solitour/user/exception/DeletedUserException.java new file mode 100644 index 00000000..1daf94b1 --- /dev/null +++ b/src/main/java/solitour_backend/solitour/user/exception/DeletedUserException.java @@ -0,0 +1,8 @@ +package solitour_backend.solitour.user.exception; + +public class DeletedUserException extends RuntimeException { + + public DeletedUserException(String message) { + super(message); + } +} diff --git a/src/main/java/solitour_backend/solitour/user/exception/DormantUserException.java b/src/main/java/solitour_backend/solitour/user/exception/DormantUserException.java new file mode 100644 index 00000000..d93ac892 --- /dev/null +++ b/src/main/java/solitour_backend/solitour/user/exception/DormantUserException.java @@ -0,0 +1,8 @@ +package solitour_backend.solitour.user.exception; + +public class DormantUserException extends RuntimeException { + + public DormantUserException(String message) { + super(message); + } +} diff --git a/src/main/java/solitour_backend/solitour/user/user_status/UserStatus.java b/src/main/java/solitour_backend/solitour/user/user_status/UserStatus.java index 957a8cb3..3e6759c1 100644 --- a/src/main/java/solitour_backend/solitour/user/user_status/UserStatus.java +++ b/src/main/java/solitour_backend/solitour/user/user_status/UserStatus.java @@ -6,6 +6,8 @@ @Getter public enum UserStatus { ACTIVATE("활성화"), + INACTIVATE("비활성화"), + BLOCK("차단"), DORMANT("휴먼"), DELETE("삭제"), MANAGER("관리자"); From 1c71e26632215025f0a6d35d4b272d41014b410d Mon Sep 17 00:00:00 2001 From: Donghun Won Date: Sat, 21 Sep 2024 23:10:22 +0900 Subject: [PATCH 327/371] =?UTF-8?q?Refactor=20:=20=EB=A1=9C=EA=B7=B8?= =?UTF-8?q?=EC=9D=B8=20=EB=A1=9C=EC=A7=81=20=EC=88=98=EC=A0=95=20(#187)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Refactor : 로그인 로직 수정 최초 로그인 시에 inactive 상태 부여 이후 이름,성별,나이가 입력되면 active 상태로 전환 * Feat : 유저 성별 없을때 디폴트 이미지로 프로필 설정 --- .../solitour/auth/service/OauthService.java | 15 ++++++------- .../user/controller/UserController.java | 21 +++++++------------ .../dto/request/UpdateUserInfoRequest.java | 12 +++++++++++ .../solitour/user/entity/User.java | 8 +++++++ .../solitour/user/service/UserService.java | 15 ++++++------- 5 files changed, 42 insertions(+), 29 deletions(-) create mode 100644 src/main/java/solitour_backend/solitour/user/dto/request/UpdateUserInfoRequest.java diff --git a/src/main/java/solitour_backend/solitour/auth/service/OauthService.java b/src/main/java/solitour_backend/solitour/auth/service/OauthService.java index 7d0946a8..93eddf2f 100644 --- a/src/main/java/solitour_backend/solitour/auth/service/OauthService.java +++ b/src/main/java/solitour_backend/solitour/auth/service/OauthService.java @@ -58,8 +58,8 @@ public class OauthService { private String USER_PROFILE_MALE; @Value("${user.profile.url.female}") private String USER_PROFILE_FEMALE; - - + @Value("${user.profile.url.none}") + private String USER_PROFILE_NONE; public OauthLinkResponse generateAuthUrl(String type, String redirectUrl) { String oauthLink = getAuthLink(type, redirectUrl); @@ -120,7 +120,7 @@ private User checkAndSaveUser(String type, String code, String redirectUrl) { throw new RuntimeException("지원하지 않는 oauth 타입입니다."); } } - + private void checkUserStatus(User user) { UserStatus userStatus = user.getUserStatus(); switch (userStatus){ @@ -144,7 +144,7 @@ private User saveGoogleUser(GoogleUserResponse response) { UserImage savedUserImage = userImageService.saveUserImage(imageUrl); User user = User.builder() - .userStatus(UserStatus.ACTIVATE) + .userStatus(UserStatus.INACTIVATE) .oauthId(response.getResourceName()) .provider("google") .isAdmin(false) @@ -167,7 +167,7 @@ private String getGoogleUserImage(GoogleUserResponse response) { if (Objects.equals(gender, "female")) { return USER_PROFILE_FEMALE; } - return "none"; + return USER_PROFILE_NONE; } private User saveKakaoUser(KakaoUserResponse response) { @@ -180,10 +180,7 @@ private User saveKakaoUser(KakaoUserResponse response) { .provider("kakao") .isAdmin(false) .userImage(savedUserImage) - .name(response.getKakaoAccount().getName()) .nickname(RandomNickName.generateRandomNickname()) - .age(Integer.valueOf(response.getKakaoAccount().getBirthYear())) - .sex(response.getKakaoAccount().getGender()) .email(response.getKakaoAccount().getEmail()) .createdAt(LocalDateTime.now()) .build(); @@ -198,7 +195,7 @@ private String getKakaoUserImage(KakaoUserResponse response) { if (Objects.equals(gender, "female")) { return USER_PROFILE_FEMALE; } - return "none"; + return USER_PROFILE_NONE; } private String getAuthLink(String type, String redirectUrl) { diff --git a/src/main/java/solitour_backend/solitour/user/controller/UserController.java b/src/main/java/solitour_backend/solitour/user/controller/UserController.java index 7d32079c..19d1926b 100644 --- a/src/main/java/solitour_backend/solitour/user/controller/UserController.java +++ b/src/main/java/solitour_backend/solitour/user/controller/UserController.java @@ -28,6 +28,7 @@ import solitour_backend.solitour.information.dto.response.InformationBriefResponse; import solitour_backend.solitour.user.dto.UpdateAgeAndSex; import solitour_backend.solitour.user.dto.UpdateNicknameRequest; +import solitour_backend.solitour.user.dto.request.UpdateUserInfoRequest; import solitour_backend.solitour.user.exception.NicknameAlreadyExistsException; import solitour_backend.solitour.user.exception.UserNotExistsException; import solitour_backend.solitour.user.service.UserService; @@ -50,6 +51,13 @@ public ResponseEntity retrieveUserInfo(@AuthenticationPrincipa return ResponseEntity.ok(response); } + @PutMapping("/info") + public ResponseEntity updateUserInfo(@AuthenticationPrincipal Long userId, @RequestBody UpdateUserInfoRequest request) { + userService.updateUserInfo(userId, request); + + return ResponseEntity.noContent().build(); + } + @PutMapping("/nickname") public ResponseEntity updateNickname(@AuthenticationPrincipal Long userId, @RequestBody UpdateNicknameRequest request) { @@ -65,19 +73,6 @@ public ResponseEntity updateNickname(@AuthenticationPrincipal Long userI } } - @PutMapping("/age-sex") - public ResponseEntity updateAgeAndSex(@AuthenticationPrincipal Long userId, - @RequestBody UpdateAgeAndSex request) { - try { - userService.updateAgeAndSex(userId, request.age(), request.sex()); - return ResponseEntity.ok("Age and Sex updated successfully"); - } catch (UserNotExistsException e) { - return ResponseEntity.status(HttpStatus.NOT_FOUND).body("User not found"); - } catch (Exception e) { - return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("An internal error occurred"); - } - } - @PutMapping("/profile") public ResponseEntity updateUserProfile(@AuthenticationPrincipal Long userId, @RequestPart(value = "userProfile", required = false) MultipartFile userProfile) { diff --git a/src/main/java/solitour_backend/solitour/user/dto/request/UpdateUserInfoRequest.java b/src/main/java/solitour_backend/solitour/user/dto/request/UpdateUserInfoRequest.java new file mode 100644 index 00000000..704c56e3 --- /dev/null +++ b/src/main/java/solitour_backend/solitour/user/dto/request/UpdateUserInfoRequest.java @@ -0,0 +1,12 @@ +package solitour_backend.solitour.user.dto.request; + +import lombok.Getter; +import lombok.NoArgsConstructor; + +@NoArgsConstructor +@Getter +public class UpdateUserInfoRequest { + private String name; + private String age; + private String sex; +} diff --git a/src/main/java/solitour_backend/solitour/user/entity/User.java b/src/main/java/solitour_backend/solitour/user/entity/User.java index c6d76671..659e2228 100644 --- a/src/main/java/solitour_backend/solitour/user/entity/User.java +++ b/src/main/java/solitour_backend/solitour/user/entity/User.java @@ -15,6 +15,7 @@ import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; +import solitour_backend.solitour.user.dto.request.UpdateUserInfoRequest; import solitour_backend.solitour.user.user_status.UserStatus; import solitour_backend.solitour.user.user_status.UserStatusConverter; import solitour_backend.solitour.user_image.entity.UserImage; @@ -103,4 +104,11 @@ public void updateUserImage(String imageUrl) { public void updateLoginTime() { this.latestLoginAt = LocalDateTime.now(); } + + public void updateUserInfo(UpdateUserInfoRequest request) { + this.name = request.getName(); + this.userStatus = UserStatus.ACTIVE; + this.age = Integer.valueOf(request.getAge()); + this.sex = request.getSex(); + } } diff --git a/src/main/java/solitour_backend/solitour/user/service/UserService.java b/src/main/java/solitour_backend/solitour/user/service/UserService.java index d0b5b0b2..325ec666 100644 --- a/src/main/java/solitour_backend/solitour/user/service/UserService.java +++ b/src/main/java/solitour_backend/solitour/user/service/UserService.java @@ -12,6 +12,7 @@ import solitour_backend.solitour.gathering.dto.response.GatheringMypageResponse; import solitour_backend.solitour.image.s3.S3Uploader; import solitour_backend.solitour.information.dto.response.InformationBriefResponse; +import solitour_backend.solitour.user.dto.request.UpdateUserInfoRequest; import solitour_backend.solitour.user.entity.User; import solitour_backend.solitour.user.exception.NicknameAlreadyExistsException; import solitour_backend.solitour.user.repository.UserRepository; @@ -38,18 +39,12 @@ public UserInfoResponse retrieveUserInfo(Long userId) { @Transactional public void updateNickname(Long userId, String nickname) { if (userRepository.existsByNickname(nickname)) { - throw new NicknameAlreadyExistsException("Nickname already exists"); + throw new NicknameAlreadyExistsException("이미 존재하는 닉네임입니다."); } User user = userRepository.findByUserId(userId); user.updateNickname(nickname); } - @Transactional - public void updateAgeAndSex(Long userId, String age, String sex) { - User user = userRepository.findByUserId(userId); - user.updateAgeAndSex(age, sex); - } - public Page retrieveInformationOwner(Pageable pageable, Long userId) { return userRepository.retrieveInformationOwner(pageable, userId); } @@ -76,4 +71,10 @@ public Page retrieveGatheringBookmark(Pageable pageable public Page retrieveGatheringApplicant(Pageable pageable, Long userId) { return userRepository.retrieveGatheringApplicant(pageable, userId); } + + @Transactional + public void updateUserInfo(Long userId, UpdateUserInfoRequest request) { + User user = userRepository.findByUserId(userId); + user.updateUserInfo(request); + } } From 2fa634a412d36b7d14db2b7f38d5295244c8ece6 Mon Sep 17 00:00:00 2001 From: Donghun Won Date: Sat, 21 Sep 2024 23:21:56 +0900 Subject: [PATCH 328/371] =?UTF-8?q?Feat=20:=20=EC=9C=A0=EC=A0=80=20?= =?UTF-8?q?=ED=94=84=EB=A1=9C=ED=95=84=20=EC=9D=B4=EB=AF=B8=EC=A7=80=20?= =?UTF-8?q?=EC=82=AD=EC=A0=9C=20=EA=B8=B0=EB=8A=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../user/controller/UserController.java | 7 +++++++ .../solitour/user/service/UserService.java | 18 ++++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/src/main/java/solitour_backend/solitour/user/controller/UserController.java b/src/main/java/solitour_backend/solitour/user/controller/UserController.java index 19d1926b..ea21c6d2 100644 --- a/src/main/java/solitour_backend/solitour/user/controller/UserController.java +++ b/src/main/java/solitour_backend/solitour/user/controller/UserController.java @@ -58,6 +58,13 @@ public ResponseEntity updateUserInfo(@AuthenticationPrincipal Long userId, return ResponseEntity.noContent().build(); } + @DeleteMapping("/profile") + public ResponseEntity deleteUserProfile(@AuthenticationPrincipal Long userId) { + userService.deleteUserProfile(userId); + + return ResponseEntity.ok().build(); + } + @PutMapping("/nickname") public ResponseEntity updateNickname(@AuthenticationPrincipal Long userId, @RequestBody UpdateNicknameRequest request) { diff --git a/src/main/java/solitour_backend/solitour/user/service/UserService.java b/src/main/java/solitour_backend/solitour/user/service/UserService.java index 325ec666..641527fe 100644 --- a/src/main/java/solitour_backend/solitour/user/service/UserService.java +++ b/src/main/java/solitour_backend/solitour/user/service/UserService.java @@ -60,6 +60,12 @@ public void updateUserProfile(Long userId, MultipartFile userProfile) { user.updateUserImage(response.getImageUrl()); } + @Transactional + public void deleteUserProfile(Long userId) { + User user = userRepository.findByUserId(userId); + resetUserProfile(user, user.getUserImage().getAddress(), user.getSex()); + } + public Page retrieveGatheringHost(Pageable pageable, Long userId) { return userRepository.retrieveGatheringHost(pageable, userId); } @@ -77,4 +83,16 @@ public void updateUserInfo(Long userId, UpdateUserInfoRequest request) { User user = userRepository.findByUserId(userId); user.updateUserInfo(request); } + + private void resetUserProfile(User user, String imageUrl, String sex) { + checkUserProfile(imageUrl); + if (sex.equals("male")) { + user.updateUserImage(maleProfileUrl); + } else if (sex.equals("female")) { + user.updateUserImage(femaleProfileUrl); + } else { + user.updateUserImage(noneProfileUrl); + } + } + } From 253dcf14c2ba4e8e89d6f1629fcd482f81452a1f Mon Sep 17 00:00:00 2001 From: Donghun Won Date: Sat, 21 Sep 2024 23:22:16 +0900 Subject: [PATCH 329/371] =?UTF-8?q?Refactor=20:=20=EC=9C=A0=EC=A0=80=20?= =?UTF-8?q?=EC=9D=B4=EB=AF=B8=EC=A7=80=20=EC=97=85=EB=8D=B0=EC=9D=B4?= =?UTF-8?q?=ED=8A=B8=20=EC=8B=9C=20s3=EC=97=90=EC=84=9C=20=EC=9D=B4?= =?UTF-8?q?=EB=AF=B8=EC=A7=80=20=EC=82=AD=EC=A0=9C=EB=90=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 --- .../solitour/user/controller/UserController.java | 4 ++-- .../solitour/user/service/UserService.java | 16 +++++++++++++++- .../controller/UserImageController.java | 2 +- .../user_image/service/UserImageService.java | 2 +- 4 files changed, 19 insertions(+), 5 deletions(-) diff --git a/src/main/java/solitour_backend/solitour/user/controller/UserController.java b/src/main/java/solitour_backend/solitour/user/controller/UserController.java index ea21c6d2..d9c080b0 100644 --- a/src/main/java/solitour_backend/solitour/user/controller/UserController.java +++ b/src/main/java/solitour_backend/solitour/user/controller/UserController.java @@ -41,7 +41,6 @@ public class UserController { private final UserService userService; - public static final int PAGE_SIZE = 6; @GetMapping("/info") @@ -52,7 +51,8 @@ public ResponseEntity retrieveUserInfo(@AuthenticationPrincipa } @PutMapping("/info") - public ResponseEntity updateUserInfo(@AuthenticationPrincipal Long userId, @RequestBody UpdateUserInfoRequest request) { + public ResponseEntity updateUserInfo(@AuthenticationPrincipal Long userId, + @RequestBody UpdateUserInfoRequest request) { userService.updateUserInfo(userId, request); return ResponseEntity.noContent().build(); diff --git a/src/main/java/solitour_backend/solitour/user/service/UserService.java b/src/main/java/solitour_backend/solitour/user/service/UserService.java index 641527fe..88568d62 100644 --- a/src/main/java/solitour_backend/solitour/user/service/UserService.java +++ b/src/main/java/solitour_backend/solitour/user/service/UserService.java @@ -29,6 +29,13 @@ public class UserService { private final UserRepository userRepository; private final UserImageService userImageService; + private final S3Uploader s3Uploader; + @Value("${user.profile.url.female}") + private String femaleProfileUrl; + @Value("${user.profile.male}") + private String maleProfileUrl; + @Value("${user.profile.none}") + private String noneProfileUrl; public UserInfoResponse retrieveUserInfo(Long userId) { User user = userRepository.findByUserId(userId); @@ -55,8 +62,9 @@ public Page retrieveInformationBookmark(Pageable pagea @Transactional public void updateUserProfile(Long userId, MultipartFile userProfile) { - UserImageResponse response = userImageService.registerInformation(userId, userProfile); + UserImageResponse response = userImageService.updateUserProfile(userId, userProfile); User user = userRepository.findByUserId(userId); + checkUserProfile(user.getUserImage().getAddress()); user.updateUserImage(response.getImageUrl()); } @@ -95,4 +103,10 @@ private void resetUserProfile(User user, String imageUrl, String sex) { } } + private void checkUserProfile(String imageUrl) { + if (imageUrl.equals(femaleProfileUrl) || imageUrl.equals(maleProfileUrl) || imageUrl.equals(noneProfileUrl)) { + return; + } + s3Uploader.deleteImage(imageUrl); + } } diff --git a/src/main/java/solitour_backend/solitour/user_image/controller/UserImageController.java b/src/main/java/solitour_backend/solitour/user_image/controller/UserImageController.java index 0db91a59..bb798347 100644 --- a/src/main/java/solitour_backend/solitour/user_image/controller/UserImageController.java +++ b/src/main/java/solitour_backend/solitour/user_image/controller/UserImageController.java @@ -27,7 +27,7 @@ public ResponseEntity createUserImage(@RequestPart("request") @RequestPart("userImage") MultipartFile userImage, BindingResult bindingResult) { Utils.validationRequest(bindingResult); - UserImageResponse informationResponse = userImageService.registerInformation( + UserImageResponse informationResponse = userImageService.updateUserProfile( imageRequest.getUserId(), userImage); return ResponseEntity diff --git a/src/main/java/solitour_backend/solitour/user_image/service/UserImageService.java b/src/main/java/solitour_backend/solitour/user_image/service/UserImageService.java index 2a9496bd..6f509925 100644 --- a/src/main/java/solitour_backend/solitour/user_image/service/UserImageService.java +++ b/src/main/java/solitour_backend/solitour/user_image/service/UserImageService.java @@ -29,7 +29,7 @@ public UserImage saveUserImage(String imageUrl) { } @Transactional - public UserImageResponse registerInformation(Long userId, MultipartFile userImage) { + public UserImageResponse updateUserProfile(Long userId, MultipartFile userImage) { String userImageUrl = s3Uploader.upload(userImage, IMAGE_PATH, userId); From c9214b4ff4fba4009d87800cf9c6b814cda13131 Mon Sep 17 00:00:00 2001 From: Donghun Won Date: Sat, 21 Sep 2024 23:23:48 +0900 Subject: [PATCH 330/371] =?UTF-8?q?Style:=20=EC=BD=94=EB=93=9C=20=ED=8F=AC?= =?UTF-8?q?=EB=A7=B7=ED=8C=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../solitour/auth/config/AuthInterceptor.java | 2 +- .../solitour/auth/config/TokenResolver.java | 1 - .../solitour/auth/entity/Token.java | 4 +-- .../solitour/auth/service/OauthService.java | 25 ++++++++++--------- .../auth/support/kakao/KakaoConnector.java | 6 ++--- .../BookMarkGatheringController.java | 4 --- .../entity/BookMarkGathering.java | 1 - .../BookMarkGatheringRepository.java | 1 - .../BookMarkInformationController.java | 2 -- .../service/BookMarkInformationService.java | 4 --- .../diary/controller/DiaryController.java | 2 +- .../dto/response/DiaryDayContentDetail.java | 1 - .../solitour/diary/entity/Diary.java | 1 - .../solitour/diary/service/DiaryService.java | 6 ++--- .../controller/GreatGatheringController.java | 6 ++--- .../service/GreatGatheringService.java | 1 - .../GreatInformationController.java | 2 -- .../user/controller/UserController.java | 6 ----- .../user/repository/UserRepositoryCustom.java | 1 - .../user/repository/UserRepositoryImpl.java | 17 ++++++------- .../solitour/user/service/UserService.java | 3 --- 21 files changed, 32 insertions(+), 64 deletions(-) diff --git a/src/main/java/solitour_backend/solitour/auth/config/AuthInterceptor.java b/src/main/java/solitour_backend/solitour/auth/config/AuthInterceptor.java index 093e0c92..9b30bc5f 100644 --- a/src/main/java/solitour_backend/solitour/auth/config/AuthInterceptor.java +++ b/src/main/java/solitour_backend/solitour/auth/config/AuthInterceptor.java @@ -32,7 +32,7 @@ public boolean preHandle(HttpServletRequest request, HttpServletResponse respons if (authenticated.isPresent()) { try { validateToken(request); - }catch (TokenNotValidException e) { + } catch (TokenNotValidException e) { throw new TokenNotExistsException("토큰이 존재하지 않습니다."); } } diff --git a/src/main/java/solitour_backend/solitour/auth/config/TokenResolver.java b/src/main/java/solitour_backend/solitour/auth/config/TokenResolver.java index aec87084..440b2779 100644 --- a/src/main/java/solitour_backend/solitour/auth/config/TokenResolver.java +++ b/src/main/java/solitour_backend/solitour/auth/config/TokenResolver.java @@ -7,7 +7,6 @@ import org.springframework.web.context.request.NativeWebRequest; import org.springframework.web.method.support.HandlerMethodArgumentResolver; import org.springframework.web.method.support.ModelAndViewContainer; -import solitour_backend.solitour.auth.exception.TokenNotExistsException; import solitour_backend.solitour.auth.support.CookieExtractor; import solitour_backend.solitour.auth.support.JwtTokenProvider; diff --git a/src/main/java/solitour_backend/solitour/auth/entity/Token.java b/src/main/java/solitour_backend/solitour/auth/entity/Token.java index 096b17c7..2c8d3c72 100644 --- a/src/main/java/solitour_backend/solitour/auth/entity/Token.java +++ b/src/main/java/solitour_backend/solitour/auth/entity/Token.java @@ -32,10 +32,10 @@ public class Token { @JoinColumn(name = "user_id") private User user; - @Column(nullable = false,name = "refresh_token") + @Column(nullable = false, name = "refresh_token") private String refreshToken; - @Column(nullable = false,name = "oauth_token") + @Column(nullable = false, name = "oauth_token") private String oauthToken; public Token(User user, String refreshToken) { diff --git a/src/main/java/solitour_backend/solitour/auth/service/OauthService.java b/src/main/java/solitour_backend/solitour/auth/service/OauthService.java index 93eddf2f..413b16cd 100644 --- a/src/main/java/solitour_backend/solitour/auth/service/OauthService.java +++ b/src/main/java/solitour_backend/solitour/auth/service/OauthService.java @@ -7,7 +7,6 @@ import java.time.LocalDateTime; import java.util.Objects; import java.util.concurrent.TimeUnit; -import jdk.jshell.spi.ExecutionControl.UserException; import lombok.RequiredArgsConstructor; import org.springframework.beans.factory.annotation.Value; import org.springframework.http.HttpStatusCode; @@ -81,7 +80,7 @@ public LoginResponse requestAccessToken(String type, String code, String redirec Cookie accessCookie = createCookie("access_token", token, ACCESS_COOKIE_AGE); Cookie refreshCookie = createCookie("refresh_token", refreshToken, REFRESH_COOKIE_AGE); - return new LoginResponse(accessCookie, refreshCookie,user.getUserStatus()); + return new LoginResponse(accessCookie, refreshCookie, user.getUserStatus()); } private Cookie createCookie(String name, String value, int maxAge) { @@ -100,7 +99,7 @@ private User checkAndSaveUser(String type, String code, String redirectUrl) { KakaoUserResponse kakaoUserResponse = response.getKakaoUserResponse(); String id = kakaoUserResponse.getId().toString(); - User user = userRepository.findByOauthId(id) + User user = userRepository.findByOauthId(id) .orElseGet(() -> saveKakaoUser(kakaoUserResponse)); checkUserStatus(user); @@ -120,10 +119,10 @@ private User checkAndSaveUser(String type, String code, String redirectUrl) { throw new RuntimeException("지원하지 않는 oauth 타입입니다."); } } - + private void checkUserStatus(User user) { UserStatus userStatus = user.getUserStatus(); - switch (userStatus){ + switch (userStatus) { case BLOCK -> throw new BlockedUserException("차단된 계정입니다."); case DELETE -> throw new DeletedUserException("탈퇴한 계정입니다."); case DORMANT -> throw new DormantUserException("휴면 계정입니다."); @@ -131,7 +130,7 @@ private void checkUserStatus(User user) { } private void saveToken(KakaoTokenResponse tokenResponse, User user) { - Token token = Token.builder() + Token token = Token.builder() .user(user) .oauthToken(tokenResponse.getRefreshToken()) .build(); @@ -258,21 +257,23 @@ public void deleteUser(Long userId) { private void changeToDefaultProfile(User user, UserImage userImage) { String defaultImageUrl = getDefaultProfile(user); - deleteUserProfileFromS3(userImage,defaultImageUrl); + deleteUserProfileFromS3(userImage, defaultImageUrl); } private String getDefaultProfile(User user) { String sex = user.getSex(); - if(sex.equals("male")){{ - return USER_PROFILE_MALE; - }} else { + if (sex.equals("male")) { + { + return USER_PROFILE_MALE; + } + } else { return USER_PROFILE_FEMALE; } } - private void deleteUserProfileFromS3(UserImage userImage,String defaultImageUrl) { + private void deleteUserProfileFromS3(UserImage userImage, String defaultImageUrl) { String userImageUrl = userImage.getAddress(); - if(userImageUrl.equals(USER_PROFILE_MALE) || userImageUrl.equals(USER_PROFILE_FEMALE)){ + if (userImageUrl.equals(USER_PROFILE_MALE) || userImageUrl.equals(USER_PROFILE_FEMALE)) { return; } s3Uploader.deleteImage(userImageUrl); diff --git a/src/main/java/solitour_backend/solitour/auth/support/kakao/KakaoConnector.java b/src/main/java/solitour_backend/solitour/auth/support/kakao/KakaoConnector.java index 3da5d8b3..c5f34dca 100644 --- a/src/main/java/solitour_backend/solitour/auth/support/kakao/KakaoConnector.java +++ b/src/main/java/solitour_backend/solitour/auth/support/kakao/KakaoConnector.java @@ -3,7 +3,6 @@ import java.io.IOException; import java.util.Collections; -import java.util.Optional; import lombok.Getter; import lombok.RequiredArgsConstructor; import org.springframework.http.HttpEntity; @@ -37,10 +36,11 @@ public KakaoTokenAndUserResponse requestKakaoUserInfo(String code, String redire headers.set("Authorization", String.join(" ", BEARER_TYPE, kakaoToken.getAccessToken())); HttpEntity entity = new HttpEntity<>(headers); - ResponseEntity responseEntity = REST_TEMPLATE.exchange(provider.getUserInfoUrl(), HttpMethod.GET, entity, + ResponseEntity responseEntity = REST_TEMPLATE.exchange(provider.getUserInfoUrl(), + HttpMethod.GET, entity, KakaoUserResponse.class); - return new KakaoTokenAndUserResponse(kakaoToken,responseEntity.getBody()); + return new KakaoTokenAndUserResponse(kakaoToken, responseEntity.getBody()); } diff --git a/src/main/java/solitour_backend/solitour/book_mark_gathering/controller/BookMarkGatheringController.java b/src/main/java/solitour_backend/solitour/book_mark_gathering/controller/BookMarkGatheringController.java index bd3b2d29..8f6f9e7a 100644 --- a/src/main/java/solitour_backend/solitour/book_mark_gathering/controller/BookMarkGatheringController.java +++ b/src/main/java/solitour_backend/solitour/book_mark_gathering/controller/BookMarkGatheringController.java @@ -4,18 +4,14 @@ import org.springframework.http.ResponseEntity; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.bind.annotation.DeleteMapping; -import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import solitour_backend.solitour.auth.config.Authenticated; import solitour_backend.solitour.auth.config.AuthenticationPrincipal; -import solitour_backend.solitour.book_mark_gathering.dto.response.BookMarkGatheringResponse; import solitour_backend.solitour.book_mark_gathering.entity.BookMarkGathering; import solitour_backend.solitour.book_mark_gathering.service.BookMarkGatheringService; -import solitour_backend.solitour.book_mark_information.service.BookMarkInformationService; -import solitour_backend.solitour.book_mark_information.service.dto.response.BookMarkInformationResponse; @Authenticated @RestController diff --git a/src/main/java/solitour_backend/solitour/book_mark_gathering/entity/BookMarkGathering.java b/src/main/java/solitour_backend/solitour/book_mark_gathering/entity/BookMarkGathering.java index a167e44c..2263e049 100644 --- a/src/main/java/solitour_backend/solitour/book_mark_gathering/entity/BookMarkGathering.java +++ b/src/main/java/solitour_backend/solitour/book_mark_gathering/entity/BookMarkGathering.java @@ -9,7 +9,6 @@ import jakarta.persistence.JoinColumn; import jakarta.persistence.ManyToOne; import jakarta.persistence.Table; -import lombok.AllArgsConstructor; import lombok.Getter; import lombok.NoArgsConstructor; import solitour_backend.solitour.gathering.entity.Gathering; diff --git a/src/main/java/solitour_backend/solitour/book_mark_gathering/repository/BookMarkGatheringRepository.java b/src/main/java/solitour_backend/solitour/book_mark_gathering/repository/BookMarkGatheringRepository.java index 20fb7837..d3e08e83 100644 --- a/src/main/java/solitour_backend/solitour/book_mark_gathering/repository/BookMarkGatheringRepository.java +++ b/src/main/java/solitour_backend/solitour/book_mark_gathering/repository/BookMarkGatheringRepository.java @@ -5,7 +5,6 @@ import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; import solitour_backend.solitour.book_mark_gathering.entity.BookMarkGathering; -import solitour_backend.solitour.book_mark_information.entity.BookMarkInformation; public interface BookMarkGatheringRepository extends JpaRepository { diff --git a/src/main/java/solitour_backend/solitour/book_mark_information/controller/BookMarkInformationController.java b/src/main/java/solitour_backend/solitour/book_mark_information/controller/BookMarkInformationController.java index b8f50dbe..3cc8c30c 100644 --- a/src/main/java/solitour_backend/solitour/book_mark_information/controller/BookMarkInformationController.java +++ b/src/main/java/solitour_backend/solitour/book_mark_information/controller/BookMarkInformationController.java @@ -4,7 +4,6 @@ import org.springframework.http.ResponseEntity; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.bind.annotation.DeleteMapping; -import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; @@ -13,7 +12,6 @@ import solitour_backend.solitour.auth.config.AuthenticationPrincipal; import solitour_backend.solitour.book_mark_information.entity.BookMarkInformation; import solitour_backend.solitour.book_mark_information.service.BookMarkInformationService; -import solitour_backend.solitour.book_mark_information.service.dto.response.BookMarkInformationResponse; @Authenticated @RestController diff --git a/src/main/java/solitour_backend/solitour/book_mark_information/service/BookMarkInformationService.java b/src/main/java/solitour_backend/solitour/book_mark_information/service/BookMarkInformationService.java index 7a8dc306..e297b48a 100644 --- a/src/main/java/solitour_backend/solitour/book_mark_information/service/BookMarkInformationService.java +++ b/src/main/java/solitour_backend/solitour/book_mark_information/service/BookMarkInformationService.java @@ -1,15 +1,11 @@ package solitour_backend.solitour.book_mark_information.service; -import jakarta.persistence.EntityNotFoundException; -import java.util.List; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import solitour_backend.solitour.book_mark_gathering.entity.BookMarkGathering; import solitour_backend.solitour.book_mark_information.entity.BookMarkInformation; import solitour_backend.solitour.book_mark_information.entity.BookMarkInformationRepository; import solitour_backend.solitour.book_mark_information.exception.InformationBookMarkNotExistsException; -import solitour_backend.solitour.book_mark_information.service.dto.response.BookMarkInformationResponse; import solitour_backend.solitour.information.entity.Information; import solitour_backend.solitour.information.repository.InformationRepository; import solitour_backend.solitour.user.entity.User; diff --git a/src/main/java/solitour_backend/solitour/diary/controller/DiaryController.java b/src/main/java/solitour_backend/solitour/diary/controller/DiaryController.java index 6e917c73..5d44b4f5 100644 --- a/src/main/java/solitour_backend/solitour/diary/controller/DiaryController.java +++ b/src/main/java/solitour_backend/solitour/diary/controller/DiaryController.java @@ -17,9 +17,9 @@ import org.springframework.web.bind.annotation.RestController; import solitour_backend.solitour.auth.config.Authenticated; import solitour_backend.solitour.auth.config.AuthenticationPrincipal; +import solitour_backend.solitour.diary.dto.request.DiaryCreateRequest; import solitour_backend.solitour.diary.dto.request.DiaryUpdateRequest; import solitour_backend.solitour.diary.dto.response.DiaryContent; -import solitour_backend.solitour.diary.dto.request.DiaryCreateRequest; import solitour_backend.solitour.diary.dto.response.DiaryResponse; import solitour_backend.solitour.diary.service.DiaryService; diff --git a/src/main/java/solitour_backend/solitour/diary/dto/response/DiaryDayContentDetail.java b/src/main/java/solitour_backend/solitour/diary/dto/response/DiaryDayContentDetail.java index 96a6f1a4..9dc25c91 100644 --- a/src/main/java/solitour_backend/solitour/diary/dto/response/DiaryDayContentDetail.java +++ b/src/main/java/solitour_backend/solitour/diary/dto/response/DiaryDayContentDetail.java @@ -1,6 +1,5 @@ package solitour_backend.solitour.diary.dto.response; -import java.util.List; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Getter; diff --git a/src/main/java/solitour_backend/solitour/diary/entity/Diary.java b/src/main/java/solitour_backend/solitour/diary/entity/Diary.java index 0b17d215..c33909cd 100644 --- a/src/main/java/solitour_backend/solitour/diary/entity/Diary.java +++ b/src/main/java/solitour_backend/solitour/diary/entity/Diary.java @@ -22,7 +22,6 @@ import org.springframework.data.annotation.LastModifiedDate; import org.springframework.data.jpa.domain.support.AuditingEntityListener; import solitour_backend.solitour.diary.diary_day_content.DiaryDayContent; -import solitour_backend.solitour.diary.dto.request.DiaryCreateRequest; import solitour_backend.solitour.diary.dto.request.DiaryUpdateRequest; import solitour_backend.solitour.user.entity.User; diff --git a/src/main/java/solitour_backend/solitour/diary/service/DiaryService.java b/src/main/java/solitour_backend/solitour/diary/service/DiaryService.java index 5fbfdcd5..18ae66f5 100644 --- a/src/main/java/solitour_backend/solitour/diary/service/DiaryService.java +++ b/src/main/java/solitour_backend/solitour/diary/service/DiaryService.java @@ -2,18 +2,17 @@ import java.time.LocalDateTime; import java.util.List; - import lombok.RequiredArgsConstructor; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import solitour_backend.solitour.diary.diary_day_content.DiaryDayContent; +import solitour_backend.solitour.diary.dto.request.DiaryCreateRequest; +import solitour_backend.solitour.diary.dto.request.DiaryCreateRequest.DiaryDayRequest; import solitour_backend.solitour.diary.dto.request.DiaryUpdateRequest; import solitour_backend.solitour.diary.dto.request.DiaryUpdateRequest.DiaryUpdateDayRequest; import solitour_backend.solitour.diary.dto.response.DiaryContent; -import solitour_backend.solitour.diary.dto.request.DiaryCreateRequest; -import solitour_backend.solitour.diary.dto.request.DiaryCreateRequest.DiaryDayRequest; import solitour_backend.solitour.diary.dto.response.DiaryResponse; import solitour_backend.solitour.diary.entity.Diary; import solitour_backend.solitour.diary.exception.DiaryNotExistsException; @@ -134,7 +133,6 @@ private void deleteDiaryImage(DiaryUpdateRequest request) { s3Uploader.deleteImage(request.getDeleteTitleImage()); } - for (DiaryUpdateDayRequest dayRequest : request.getDiaryDayRequests()) { for (String imageUrl : dayRequest.getSplitImageUrl(dayRequest.getDeleteImagesUrl())) { s3Uploader.deleteImage(imageUrl); diff --git a/src/main/java/solitour_backend/solitour/great_gathering/controller/GreatGatheringController.java b/src/main/java/solitour_backend/solitour/great_gathering/controller/GreatGatheringController.java index d498cc88..e51f4abb 100644 --- a/src/main/java/solitour_backend/solitour/great_gathering/controller/GreatGatheringController.java +++ b/src/main/java/solitour_backend/solitour/great_gathering/controller/GreatGatheringController.java @@ -11,8 +11,6 @@ import solitour_backend.solitour.auth.config.AuthenticationPrincipal; import solitour_backend.solitour.great_gathering.entity.GreatGathering; import solitour_backend.solitour.great_gathering.service.GreatGatheringService; -import solitour_backend.solitour.great_information.entity.GreatInformation; -import solitour_backend.solitour.great_information.service.GreatInformationService; @Authenticated @RestController @@ -24,7 +22,7 @@ public class GreatGatheringController { @PostMapping() public ResponseEntity createGatheringGreat(@AuthenticationPrincipal Long userId, - @RequestParam Long gatheringId) { + @RequestParam Long gatheringId) { GreatGathering greatGathering = service.createGatheringGreat(userId, gatheringId); return ResponseEntity.ok(greatGathering.getId()); @@ -32,7 +30,7 @@ public ResponseEntity createGatheringGreat(@AuthenticationPrincipal Long u @DeleteMapping() public ResponseEntity deleteGatheringGreat(@AuthenticationPrincipal Long userId, - @RequestParam Long gatheringId) { + @RequestParam Long gatheringId) { service.deleteGatheringGreat(userId, gatheringId); return ResponseEntity.noContent().build(); diff --git a/src/main/java/solitour_backend/solitour/great_gathering/service/GreatGatheringService.java b/src/main/java/solitour_backend/solitour/great_gathering/service/GreatGatheringService.java index f6861744..24b8cd67 100644 --- a/src/main/java/solitour_backend/solitour/great_gathering/service/GreatGatheringService.java +++ b/src/main/java/solitour_backend/solitour/great_gathering/service/GreatGatheringService.java @@ -9,7 +9,6 @@ import solitour_backend.solitour.great_gathering.entity.GreatGathering; import solitour_backend.solitour.great_gathering.exception.GatheringGreatNotExistsException; import solitour_backend.solitour.great_gathering.repository.GreatGatheringRepository; -import solitour_backend.solitour.great_information.exception.InformationGreatNotExistsException; import solitour_backend.solitour.user.entity.User; import solitour_backend.solitour.user.repository.UserRepository; diff --git a/src/main/java/solitour_backend/solitour/great_information/controller/GreatInformationController.java b/src/main/java/solitour_backend/solitour/great_information/controller/GreatInformationController.java index 289fafdd..71703aaf 100644 --- a/src/main/java/solitour_backend/solitour/great_information/controller/GreatInformationController.java +++ b/src/main/java/solitour_backend/solitour/great_information/controller/GreatInformationController.java @@ -3,14 +3,12 @@ import lombok.RequiredArgsConstructor; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.DeleteMapping; -import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import solitour_backend.solitour.auth.config.Authenticated; import solitour_backend.solitour.auth.config.AuthenticationPrincipal; -import solitour_backend.solitour.great_information.dto.response.GreatInformationResponse; import solitour_backend.solitour.great_information.entity.GreatInformation; import solitour_backend.solitour.great_information.service.GreatInformationService; diff --git a/src/main/java/solitour_backend/solitour/user/controller/UserController.java b/src/main/java/solitour_backend/solitour/user/controller/UserController.java index d9c080b0..6287361c 100644 --- a/src/main/java/solitour_backend/solitour/user/controller/UserController.java +++ b/src/main/java/solitour_backend/solitour/user/controller/UserController.java @@ -1,7 +1,6 @@ package solitour_backend.solitour.user.controller; -import jakarta.servlet.http.HttpServletResponse; import lombok.RequiredArgsConstructor; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; @@ -19,14 +18,9 @@ import org.springframework.web.multipart.MultipartFile; import solitour_backend.solitour.auth.config.Authenticated; import solitour_backend.solitour.auth.config.AuthenticationPrincipal; -import solitour_backend.solitour.auth.service.OauthService; -import solitour_backend.solitour.auth.support.google.GoogleConnector; -import solitour_backend.solitour.auth.support.kakao.KakaoConnector; import solitour_backend.solitour.gathering.dto.response.GatheringApplicantResponse; -import solitour_backend.solitour.gathering.dto.response.GatheringBriefResponse; import solitour_backend.solitour.gathering.dto.response.GatheringMypageResponse; import solitour_backend.solitour.information.dto.response.InformationBriefResponse; -import solitour_backend.solitour.user.dto.UpdateAgeAndSex; import solitour_backend.solitour.user.dto.UpdateNicknameRequest; import solitour_backend.solitour.user.dto.request.UpdateUserInfoRequest; import solitour_backend.solitour.user.exception.NicknameAlreadyExistsException; diff --git a/src/main/java/solitour_backend/solitour/user/repository/UserRepositoryCustom.java b/src/main/java/solitour_backend/solitour/user/repository/UserRepositoryCustom.java index 1ae4a264..32765091 100644 --- a/src/main/java/solitour_backend/solitour/user/repository/UserRepositoryCustom.java +++ b/src/main/java/solitour_backend/solitour/user/repository/UserRepositoryCustom.java @@ -4,7 +4,6 @@ import org.springframework.data.domain.Pageable; import org.springframework.data.repository.NoRepositoryBean; import solitour_backend.solitour.gathering.dto.response.GatheringApplicantResponse; -import solitour_backend.solitour.gathering.dto.response.GatheringBriefResponse; import solitour_backend.solitour.gathering.dto.response.GatheringMypageResponse; import solitour_backend.solitour.information.dto.response.InformationBriefResponse; diff --git a/src/main/java/solitour_backend/solitour/user/repository/UserRepositoryImpl.java b/src/main/java/solitour_backend/solitour/user/repository/UserRepositoryImpl.java index 165203f4..c01c02a0 100644 --- a/src/main/java/solitour_backend/solitour/user/repository/UserRepositoryImpl.java +++ b/src/main/java/solitour_backend/solitour/user/repository/UserRepositoryImpl.java @@ -8,9 +8,7 @@ import com.querydsl.core.types.dsl.StringExpression; import com.querydsl.jpa.JPAExpressions; import com.querydsl.jpa.JPQLQuery; - import java.util.List; - import org.springframework.beans.factory.annotation.Value; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageImpl; @@ -20,7 +18,6 @@ import solitour_backend.solitour.book_mark_information.entity.QBookMarkInformation; import solitour_backend.solitour.gathering.dto.response.GatheringApplicantResponse; import solitour_backend.solitour.gathering.dto.response.GatheringMypageResponse; -import solitour_backend.solitour.gathering.dto.response.GatheringMypageResponse; import solitour_backend.solitour.gathering.entity.Gathering; import solitour_backend.solitour.gathering.entity.QGathering; import solitour_backend.solitour.gathering_applicants.entity.GatheringStatus; @@ -147,7 +144,8 @@ public Page retrieveGatheringHost(Pageable pageable, Lo .leftJoin(gatheringCategory) .on(gatheringCategory.id.eq(gathering.gatheringCategory.id)) .leftJoin(gatheringApplicants) - .on(gatheringApplicants.gathering.id.eq(gathering.id).and(gatheringApplicants.gatheringStatus.eq(GatheringStatus.CONSENT))) + .on(gatheringApplicants.gathering.id.eq(gathering.id) + .and(gatheringApplicants.gatheringStatus.eq(GatheringStatus.CONSENT))) .orderBy(gathering.createdAt.desc()) .where(gathering.user.id.eq(userId)); @@ -195,7 +193,8 @@ public Page retrieveGatheringBookmark(Pageable pageable .leftJoin(gatheringCategory) .on(gatheringCategory.id.eq(gathering.gatheringCategory.id)) .leftJoin(gatheringApplicants) - .on(gatheringApplicants.gathering.id.eq(gathering.id).and(gatheringApplicants.gatheringStatus.eq(GatheringStatus.CONSENT))) + .on(gatheringApplicants.gathering.id.eq(gathering.id) + .and(gatheringApplicants.gatheringStatus.eq(GatheringStatus.CONSENT))) .leftJoin(bookMarkGathering) .on(bookMarkGathering.gathering.id.eq(gathering.id)) .orderBy(gathering.createdAt.desc()) @@ -241,7 +240,6 @@ public Page retrieveGatheringApplicant(Pageable page StringExpression gatheringStatus = getGatheringStatus(); NumberExpression gatheringApplicantCount = countGatheringApplicant(userId); - JPQLQuery query = from(gathering) .leftJoin(zoneCategoryParent) .on(zoneCategoryParent.id.eq(gathering.zoneCategory.parentZoneCategory.id)) @@ -254,7 +252,7 @@ public Page retrieveGatheringApplicant(Pageable page List list = query .groupBy(gathering.id, zoneCategoryParent.id, zoneCategoryChild.id, - gatheringCategory.id, gatheringApplicants.id) + gatheringCategory.id, gatheringApplicants.id) .select(Projections.constructor( GatheringApplicantResponse.class, gathering.id, @@ -273,7 +271,7 @@ public Page retrieveGatheringApplicant(Pageable page gathering.startAge, gathering.endAge, gathering.personCount, - gatheringApplicantCount, isUserGreatGathering(userId), + gatheringApplicantCount, isUserGreatGathering(userId), gatheringStatus, gathering.isFinish )) @@ -291,7 +289,8 @@ private NumberExpression countGatheringApplicant(Long userId) { JPQLQuery countApplicant = JPAExpressions .select(gatheringApplicants.count()) .from(gatheringApplicants) - .where(gatheringApplicants.user.id.eq(userId).and(gatheringApplicants.gatheringStatus.eq(GatheringStatus.CONSENT))); + .where(gatheringApplicants.user.id.eq(userId) + .and(gatheringApplicants.gatheringStatus.eq(GatheringStatus.CONSENT))); return Expressions.numberTemplate(Long.class, "{0}", countApplicant) .coalesce(0L) diff --git a/src/main/java/solitour_backend/solitour/user/service/UserService.java b/src/main/java/solitour_backend/solitour/user/service/UserService.java index 88568d62..e8fcc629 100644 --- a/src/main/java/solitour_backend/solitour/user/service/UserService.java +++ b/src/main/java/solitour_backend/solitour/user/service/UserService.java @@ -8,7 +8,6 @@ import org.springframework.transaction.annotation.Transactional; import org.springframework.web.multipart.MultipartFile; import solitour_backend.solitour.gathering.dto.response.GatheringApplicantResponse; -import solitour_backend.solitour.gathering.dto.response.GatheringBriefResponse; import solitour_backend.solitour.gathering.dto.response.GatheringMypageResponse; import solitour_backend.solitour.image.s3.S3Uploader; import solitour_backend.solitour.information.dto.response.InformationBriefResponse; @@ -18,8 +17,6 @@ import solitour_backend.solitour.user.repository.UserRepository; import solitour_backend.solitour.user.service.dto.response.UserInfoResponse; import solitour_backend.solitour.user_image.dto.UserImageResponse; -import solitour_backend.solitour.user_image.entity.UserImage; -import solitour_backend.solitour.user_image.entity.UserImageRepository; import solitour_backend.solitour.user_image.service.UserImageService; @Service From da8fea731665c4de8f2421ab1d8077174b947e8e Mon Sep 17 00:00:00 2001 From: Donghun Won Date: Sat, 21 Sep 2024 23:46:49 +0900 Subject: [PATCH 331/371] =?UTF-8?q?Fix=20:=20=EC=9C=A0=EC=A0=80=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80=20=EC=A0=95=EB=B3=B4=20=EC=9E=85=EB=A0=A5?= =?UTF-8?q?=EC=8B=9C=20=ED=99=9C=EC=84=B1=ED=99=94=20=EC=83=81=ED=83=9C?= =?UTF-8?q?=EB=A1=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/solitour_backend/solitour/user/entity/User.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/solitour_backend/solitour/user/entity/User.java b/src/main/java/solitour_backend/solitour/user/entity/User.java index 659e2228..3be37531 100644 --- a/src/main/java/solitour_backend/solitour/user/entity/User.java +++ b/src/main/java/solitour_backend/solitour/user/entity/User.java @@ -107,7 +107,7 @@ public void updateLoginTime() { public void updateUserInfo(UpdateUserInfoRequest request) { this.name = request.getName(); - this.userStatus = UserStatus.ACTIVE; + this.userStatus = UserStatus.ACTIVATE; this.age = Integer.valueOf(request.getAge()); this.sex = request.getSex(); } From 8a1c61d70b04c45ae5303c7bf39002ec43ae5787 Mon Sep 17 00:00:00 2001 From: Donghun Won Date: Sat, 21 Sep 2024 23:48:45 +0900 Subject: [PATCH 332/371] =?UTF-8?q?Feat=20:=20=EC=9C=A0=EC=A0=80=20?= =?UTF-8?q?=ED=94=84=EB=A1=9C=ED=95=84=20=EC=82=AD=EC=A0=9C=20=EA=B8=B0?= =?UTF-8?q?=EB=8A=A5=20=20(#190)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Feat : 유저 프로필 이미지 삭제 기능 * Refactor : 유저 이미지 업데이트 시 s3에서 이미지 삭제되도록 수정 * Style: 코드 포맷팅 * Fix : 유저 추가 정보 입력시 활성화 상태로 수정 --- .../solitour/auth/config/AuthInterceptor.java | 2 +- .../solitour/auth/config/TokenResolver.java | 1 - .../solitour/auth/entity/Token.java | 4 +- .../solitour/auth/service/OauthService.java | 25 +++++++------ .../auth/support/kakao/KakaoConnector.java | 6 +-- .../BookMarkGatheringController.java | 4 -- .../entity/BookMarkGathering.java | 1 - .../BookMarkGatheringRepository.java | 1 - .../BookMarkInformationController.java | 2 - .../service/BookMarkInformationService.java | 4 -- .../diary/controller/DiaryController.java | 2 +- .../dto/response/DiaryDayContentDetail.java | 1 - .../solitour/diary/entity/Diary.java | 1 - .../solitour/diary/service/DiaryService.java | 6 +-- .../controller/GreatGatheringController.java | 6 +-- .../service/GreatGatheringService.java | 1 - .../GreatInformationController.java | 2 - .../user/controller/UserController.java | 17 +++++---- .../solitour/user/entity/User.java | 2 +- .../user/repository/UserRepositoryCustom.java | 1 - .../user/repository/UserRepositoryImpl.java | 17 ++++----- .../solitour/user/service/UserService.java | 37 +++++++++++++++++-- .../controller/UserImageController.java | 2 +- .../user_image/service/UserImageService.java | 2 +- 24 files changed, 77 insertions(+), 70 deletions(-) diff --git a/src/main/java/solitour_backend/solitour/auth/config/AuthInterceptor.java b/src/main/java/solitour_backend/solitour/auth/config/AuthInterceptor.java index 093e0c92..9b30bc5f 100644 --- a/src/main/java/solitour_backend/solitour/auth/config/AuthInterceptor.java +++ b/src/main/java/solitour_backend/solitour/auth/config/AuthInterceptor.java @@ -32,7 +32,7 @@ public boolean preHandle(HttpServletRequest request, HttpServletResponse respons if (authenticated.isPresent()) { try { validateToken(request); - }catch (TokenNotValidException e) { + } catch (TokenNotValidException e) { throw new TokenNotExistsException("토큰이 존재하지 않습니다."); } } diff --git a/src/main/java/solitour_backend/solitour/auth/config/TokenResolver.java b/src/main/java/solitour_backend/solitour/auth/config/TokenResolver.java index aec87084..440b2779 100644 --- a/src/main/java/solitour_backend/solitour/auth/config/TokenResolver.java +++ b/src/main/java/solitour_backend/solitour/auth/config/TokenResolver.java @@ -7,7 +7,6 @@ import org.springframework.web.context.request.NativeWebRequest; import org.springframework.web.method.support.HandlerMethodArgumentResolver; import org.springframework.web.method.support.ModelAndViewContainer; -import solitour_backend.solitour.auth.exception.TokenNotExistsException; import solitour_backend.solitour.auth.support.CookieExtractor; import solitour_backend.solitour.auth.support.JwtTokenProvider; diff --git a/src/main/java/solitour_backend/solitour/auth/entity/Token.java b/src/main/java/solitour_backend/solitour/auth/entity/Token.java index 096b17c7..2c8d3c72 100644 --- a/src/main/java/solitour_backend/solitour/auth/entity/Token.java +++ b/src/main/java/solitour_backend/solitour/auth/entity/Token.java @@ -32,10 +32,10 @@ public class Token { @JoinColumn(name = "user_id") private User user; - @Column(nullable = false,name = "refresh_token") + @Column(nullable = false, name = "refresh_token") private String refreshToken; - @Column(nullable = false,name = "oauth_token") + @Column(nullable = false, name = "oauth_token") private String oauthToken; public Token(User user, String refreshToken) { diff --git a/src/main/java/solitour_backend/solitour/auth/service/OauthService.java b/src/main/java/solitour_backend/solitour/auth/service/OauthService.java index 93eddf2f..413b16cd 100644 --- a/src/main/java/solitour_backend/solitour/auth/service/OauthService.java +++ b/src/main/java/solitour_backend/solitour/auth/service/OauthService.java @@ -7,7 +7,6 @@ import java.time.LocalDateTime; import java.util.Objects; import java.util.concurrent.TimeUnit; -import jdk.jshell.spi.ExecutionControl.UserException; import lombok.RequiredArgsConstructor; import org.springframework.beans.factory.annotation.Value; import org.springframework.http.HttpStatusCode; @@ -81,7 +80,7 @@ public LoginResponse requestAccessToken(String type, String code, String redirec Cookie accessCookie = createCookie("access_token", token, ACCESS_COOKIE_AGE); Cookie refreshCookie = createCookie("refresh_token", refreshToken, REFRESH_COOKIE_AGE); - return new LoginResponse(accessCookie, refreshCookie,user.getUserStatus()); + return new LoginResponse(accessCookie, refreshCookie, user.getUserStatus()); } private Cookie createCookie(String name, String value, int maxAge) { @@ -100,7 +99,7 @@ private User checkAndSaveUser(String type, String code, String redirectUrl) { KakaoUserResponse kakaoUserResponse = response.getKakaoUserResponse(); String id = kakaoUserResponse.getId().toString(); - User user = userRepository.findByOauthId(id) + User user = userRepository.findByOauthId(id) .orElseGet(() -> saveKakaoUser(kakaoUserResponse)); checkUserStatus(user); @@ -120,10 +119,10 @@ private User checkAndSaveUser(String type, String code, String redirectUrl) { throw new RuntimeException("지원하지 않는 oauth 타입입니다."); } } - + private void checkUserStatus(User user) { UserStatus userStatus = user.getUserStatus(); - switch (userStatus){ + switch (userStatus) { case BLOCK -> throw new BlockedUserException("차단된 계정입니다."); case DELETE -> throw new DeletedUserException("탈퇴한 계정입니다."); case DORMANT -> throw new DormantUserException("휴면 계정입니다."); @@ -131,7 +130,7 @@ private void checkUserStatus(User user) { } private void saveToken(KakaoTokenResponse tokenResponse, User user) { - Token token = Token.builder() + Token token = Token.builder() .user(user) .oauthToken(tokenResponse.getRefreshToken()) .build(); @@ -258,21 +257,23 @@ public void deleteUser(Long userId) { private void changeToDefaultProfile(User user, UserImage userImage) { String defaultImageUrl = getDefaultProfile(user); - deleteUserProfileFromS3(userImage,defaultImageUrl); + deleteUserProfileFromS3(userImage, defaultImageUrl); } private String getDefaultProfile(User user) { String sex = user.getSex(); - if(sex.equals("male")){{ - return USER_PROFILE_MALE; - }} else { + if (sex.equals("male")) { + { + return USER_PROFILE_MALE; + } + } else { return USER_PROFILE_FEMALE; } } - private void deleteUserProfileFromS3(UserImage userImage,String defaultImageUrl) { + private void deleteUserProfileFromS3(UserImage userImage, String defaultImageUrl) { String userImageUrl = userImage.getAddress(); - if(userImageUrl.equals(USER_PROFILE_MALE) || userImageUrl.equals(USER_PROFILE_FEMALE)){ + if (userImageUrl.equals(USER_PROFILE_MALE) || userImageUrl.equals(USER_PROFILE_FEMALE)) { return; } s3Uploader.deleteImage(userImageUrl); diff --git a/src/main/java/solitour_backend/solitour/auth/support/kakao/KakaoConnector.java b/src/main/java/solitour_backend/solitour/auth/support/kakao/KakaoConnector.java index 3da5d8b3..c5f34dca 100644 --- a/src/main/java/solitour_backend/solitour/auth/support/kakao/KakaoConnector.java +++ b/src/main/java/solitour_backend/solitour/auth/support/kakao/KakaoConnector.java @@ -3,7 +3,6 @@ import java.io.IOException; import java.util.Collections; -import java.util.Optional; import lombok.Getter; import lombok.RequiredArgsConstructor; import org.springframework.http.HttpEntity; @@ -37,10 +36,11 @@ public KakaoTokenAndUserResponse requestKakaoUserInfo(String code, String redire headers.set("Authorization", String.join(" ", BEARER_TYPE, kakaoToken.getAccessToken())); HttpEntity entity = new HttpEntity<>(headers); - ResponseEntity responseEntity = REST_TEMPLATE.exchange(provider.getUserInfoUrl(), HttpMethod.GET, entity, + ResponseEntity responseEntity = REST_TEMPLATE.exchange(provider.getUserInfoUrl(), + HttpMethod.GET, entity, KakaoUserResponse.class); - return new KakaoTokenAndUserResponse(kakaoToken,responseEntity.getBody()); + return new KakaoTokenAndUserResponse(kakaoToken, responseEntity.getBody()); } diff --git a/src/main/java/solitour_backend/solitour/book_mark_gathering/controller/BookMarkGatheringController.java b/src/main/java/solitour_backend/solitour/book_mark_gathering/controller/BookMarkGatheringController.java index bd3b2d29..8f6f9e7a 100644 --- a/src/main/java/solitour_backend/solitour/book_mark_gathering/controller/BookMarkGatheringController.java +++ b/src/main/java/solitour_backend/solitour/book_mark_gathering/controller/BookMarkGatheringController.java @@ -4,18 +4,14 @@ import org.springframework.http.ResponseEntity; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.bind.annotation.DeleteMapping; -import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import solitour_backend.solitour.auth.config.Authenticated; import solitour_backend.solitour.auth.config.AuthenticationPrincipal; -import solitour_backend.solitour.book_mark_gathering.dto.response.BookMarkGatheringResponse; import solitour_backend.solitour.book_mark_gathering.entity.BookMarkGathering; import solitour_backend.solitour.book_mark_gathering.service.BookMarkGatheringService; -import solitour_backend.solitour.book_mark_information.service.BookMarkInformationService; -import solitour_backend.solitour.book_mark_information.service.dto.response.BookMarkInformationResponse; @Authenticated @RestController diff --git a/src/main/java/solitour_backend/solitour/book_mark_gathering/entity/BookMarkGathering.java b/src/main/java/solitour_backend/solitour/book_mark_gathering/entity/BookMarkGathering.java index a167e44c..2263e049 100644 --- a/src/main/java/solitour_backend/solitour/book_mark_gathering/entity/BookMarkGathering.java +++ b/src/main/java/solitour_backend/solitour/book_mark_gathering/entity/BookMarkGathering.java @@ -9,7 +9,6 @@ import jakarta.persistence.JoinColumn; import jakarta.persistence.ManyToOne; import jakarta.persistence.Table; -import lombok.AllArgsConstructor; import lombok.Getter; import lombok.NoArgsConstructor; import solitour_backend.solitour.gathering.entity.Gathering; diff --git a/src/main/java/solitour_backend/solitour/book_mark_gathering/repository/BookMarkGatheringRepository.java b/src/main/java/solitour_backend/solitour/book_mark_gathering/repository/BookMarkGatheringRepository.java index 20fb7837..d3e08e83 100644 --- a/src/main/java/solitour_backend/solitour/book_mark_gathering/repository/BookMarkGatheringRepository.java +++ b/src/main/java/solitour_backend/solitour/book_mark_gathering/repository/BookMarkGatheringRepository.java @@ -5,7 +5,6 @@ import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; import solitour_backend.solitour.book_mark_gathering.entity.BookMarkGathering; -import solitour_backend.solitour.book_mark_information.entity.BookMarkInformation; public interface BookMarkGatheringRepository extends JpaRepository { diff --git a/src/main/java/solitour_backend/solitour/book_mark_information/controller/BookMarkInformationController.java b/src/main/java/solitour_backend/solitour/book_mark_information/controller/BookMarkInformationController.java index b8f50dbe..3cc8c30c 100644 --- a/src/main/java/solitour_backend/solitour/book_mark_information/controller/BookMarkInformationController.java +++ b/src/main/java/solitour_backend/solitour/book_mark_information/controller/BookMarkInformationController.java @@ -4,7 +4,6 @@ import org.springframework.http.ResponseEntity; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.bind.annotation.DeleteMapping; -import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; @@ -13,7 +12,6 @@ import solitour_backend.solitour.auth.config.AuthenticationPrincipal; import solitour_backend.solitour.book_mark_information.entity.BookMarkInformation; import solitour_backend.solitour.book_mark_information.service.BookMarkInformationService; -import solitour_backend.solitour.book_mark_information.service.dto.response.BookMarkInformationResponse; @Authenticated @RestController diff --git a/src/main/java/solitour_backend/solitour/book_mark_information/service/BookMarkInformationService.java b/src/main/java/solitour_backend/solitour/book_mark_information/service/BookMarkInformationService.java index 7a8dc306..e297b48a 100644 --- a/src/main/java/solitour_backend/solitour/book_mark_information/service/BookMarkInformationService.java +++ b/src/main/java/solitour_backend/solitour/book_mark_information/service/BookMarkInformationService.java @@ -1,15 +1,11 @@ package solitour_backend.solitour.book_mark_information.service; -import jakarta.persistence.EntityNotFoundException; -import java.util.List; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import solitour_backend.solitour.book_mark_gathering.entity.BookMarkGathering; import solitour_backend.solitour.book_mark_information.entity.BookMarkInformation; import solitour_backend.solitour.book_mark_information.entity.BookMarkInformationRepository; import solitour_backend.solitour.book_mark_information.exception.InformationBookMarkNotExistsException; -import solitour_backend.solitour.book_mark_information.service.dto.response.BookMarkInformationResponse; import solitour_backend.solitour.information.entity.Information; import solitour_backend.solitour.information.repository.InformationRepository; import solitour_backend.solitour.user.entity.User; diff --git a/src/main/java/solitour_backend/solitour/diary/controller/DiaryController.java b/src/main/java/solitour_backend/solitour/diary/controller/DiaryController.java index 6e917c73..5d44b4f5 100644 --- a/src/main/java/solitour_backend/solitour/diary/controller/DiaryController.java +++ b/src/main/java/solitour_backend/solitour/diary/controller/DiaryController.java @@ -17,9 +17,9 @@ import org.springframework.web.bind.annotation.RestController; import solitour_backend.solitour.auth.config.Authenticated; import solitour_backend.solitour.auth.config.AuthenticationPrincipal; +import solitour_backend.solitour.diary.dto.request.DiaryCreateRequest; import solitour_backend.solitour.diary.dto.request.DiaryUpdateRequest; import solitour_backend.solitour.diary.dto.response.DiaryContent; -import solitour_backend.solitour.diary.dto.request.DiaryCreateRequest; import solitour_backend.solitour.diary.dto.response.DiaryResponse; import solitour_backend.solitour.diary.service.DiaryService; diff --git a/src/main/java/solitour_backend/solitour/diary/dto/response/DiaryDayContentDetail.java b/src/main/java/solitour_backend/solitour/diary/dto/response/DiaryDayContentDetail.java index 96a6f1a4..9dc25c91 100644 --- a/src/main/java/solitour_backend/solitour/diary/dto/response/DiaryDayContentDetail.java +++ b/src/main/java/solitour_backend/solitour/diary/dto/response/DiaryDayContentDetail.java @@ -1,6 +1,5 @@ package solitour_backend.solitour.diary.dto.response; -import java.util.List; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Getter; diff --git a/src/main/java/solitour_backend/solitour/diary/entity/Diary.java b/src/main/java/solitour_backend/solitour/diary/entity/Diary.java index 0b17d215..c33909cd 100644 --- a/src/main/java/solitour_backend/solitour/diary/entity/Diary.java +++ b/src/main/java/solitour_backend/solitour/diary/entity/Diary.java @@ -22,7 +22,6 @@ import org.springframework.data.annotation.LastModifiedDate; import org.springframework.data.jpa.domain.support.AuditingEntityListener; import solitour_backend.solitour.diary.diary_day_content.DiaryDayContent; -import solitour_backend.solitour.diary.dto.request.DiaryCreateRequest; import solitour_backend.solitour.diary.dto.request.DiaryUpdateRequest; import solitour_backend.solitour.user.entity.User; diff --git a/src/main/java/solitour_backend/solitour/diary/service/DiaryService.java b/src/main/java/solitour_backend/solitour/diary/service/DiaryService.java index 5fbfdcd5..18ae66f5 100644 --- a/src/main/java/solitour_backend/solitour/diary/service/DiaryService.java +++ b/src/main/java/solitour_backend/solitour/diary/service/DiaryService.java @@ -2,18 +2,17 @@ import java.time.LocalDateTime; import java.util.List; - import lombok.RequiredArgsConstructor; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import solitour_backend.solitour.diary.diary_day_content.DiaryDayContent; +import solitour_backend.solitour.diary.dto.request.DiaryCreateRequest; +import solitour_backend.solitour.diary.dto.request.DiaryCreateRequest.DiaryDayRequest; import solitour_backend.solitour.diary.dto.request.DiaryUpdateRequest; import solitour_backend.solitour.diary.dto.request.DiaryUpdateRequest.DiaryUpdateDayRequest; import solitour_backend.solitour.diary.dto.response.DiaryContent; -import solitour_backend.solitour.diary.dto.request.DiaryCreateRequest; -import solitour_backend.solitour.diary.dto.request.DiaryCreateRequest.DiaryDayRequest; import solitour_backend.solitour.diary.dto.response.DiaryResponse; import solitour_backend.solitour.diary.entity.Diary; import solitour_backend.solitour.diary.exception.DiaryNotExistsException; @@ -134,7 +133,6 @@ private void deleteDiaryImage(DiaryUpdateRequest request) { s3Uploader.deleteImage(request.getDeleteTitleImage()); } - for (DiaryUpdateDayRequest dayRequest : request.getDiaryDayRequests()) { for (String imageUrl : dayRequest.getSplitImageUrl(dayRequest.getDeleteImagesUrl())) { s3Uploader.deleteImage(imageUrl); diff --git a/src/main/java/solitour_backend/solitour/great_gathering/controller/GreatGatheringController.java b/src/main/java/solitour_backend/solitour/great_gathering/controller/GreatGatheringController.java index d498cc88..e51f4abb 100644 --- a/src/main/java/solitour_backend/solitour/great_gathering/controller/GreatGatheringController.java +++ b/src/main/java/solitour_backend/solitour/great_gathering/controller/GreatGatheringController.java @@ -11,8 +11,6 @@ import solitour_backend.solitour.auth.config.AuthenticationPrincipal; import solitour_backend.solitour.great_gathering.entity.GreatGathering; import solitour_backend.solitour.great_gathering.service.GreatGatheringService; -import solitour_backend.solitour.great_information.entity.GreatInformation; -import solitour_backend.solitour.great_information.service.GreatInformationService; @Authenticated @RestController @@ -24,7 +22,7 @@ public class GreatGatheringController { @PostMapping() public ResponseEntity createGatheringGreat(@AuthenticationPrincipal Long userId, - @RequestParam Long gatheringId) { + @RequestParam Long gatheringId) { GreatGathering greatGathering = service.createGatheringGreat(userId, gatheringId); return ResponseEntity.ok(greatGathering.getId()); @@ -32,7 +30,7 @@ public ResponseEntity createGatheringGreat(@AuthenticationPrincipal Long u @DeleteMapping() public ResponseEntity deleteGatheringGreat(@AuthenticationPrincipal Long userId, - @RequestParam Long gatheringId) { + @RequestParam Long gatheringId) { service.deleteGatheringGreat(userId, gatheringId); return ResponseEntity.noContent().build(); diff --git a/src/main/java/solitour_backend/solitour/great_gathering/service/GreatGatheringService.java b/src/main/java/solitour_backend/solitour/great_gathering/service/GreatGatheringService.java index f6861744..24b8cd67 100644 --- a/src/main/java/solitour_backend/solitour/great_gathering/service/GreatGatheringService.java +++ b/src/main/java/solitour_backend/solitour/great_gathering/service/GreatGatheringService.java @@ -9,7 +9,6 @@ import solitour_backend.solitour.great_gathering.entity.GreatGathering; import solitour_backend.solitour.great_gathering.exception.GatheringGreatNotExistsException; import solitour_backend.solitour.great_gathering.repository.GreatGatheringRepository; -import solitour_backend.solitour.great_information.exception.InformationGreatNotExistsException; import solitour_backend.solitour.user.entity.User; import solitour_backend.solitour.user.repository.UserRepository; diff --git a/src/main/java/solitour_backend/solitour/great_information/controller/GreatInformationController.java b/src/main/java/solitour_backend/solitour/great_information/controller/GreatInformationController.java index 289fafdd..71703aaf 100644 --- a/src/main/java/solitour_backend/solitour/great_information/controller/GreatInformationController.java +++ b/src/main/java/solitour_backend/solitour/great_information/controller/GreatInformationController.java @@ -3,14 +3,12 @@ import lombok.RequiredArgsConstructor; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.DeleteMapping; -import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import solitour_backend.solitour.auth.config.Authenticated; import solitour_backend.solitour.auth.config.AuthenticationPrincipal; -import solitour_backend.solitour.great_information.dto.response.GreatInformationResponse; import solitour_backend.solitour.great_information.entity.GreatInformation; import solitour_backend.solitour.great_information.service.GreatInformationService; diff --git a/src/main/java/solitour_backend/solitour/user/controller/UserController.java b/src/main/java/solitour_backend/solitour/user/controller/UserController.java index 19d1926b..6287361c 100644 --- a/src/main/java/solitour_backend/solitour/user/controller/UserController.java +++ b/src/main/java/solitour_backend/solitour/user/controller/UserController.java @@ -1,7 +1,6 @@ package solitour_backend.solitour.user.controller; -import jakarta.servlet.http.HttpServletResponse; import lombok.RequiredArgsConstructor; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; @@ -19,14 +18,9 @@ import org.springframework.web.multipart.MultipartFile; import solitour_backend.solitour.auth.config.Authenticated; import solitour_backend.solitour.auth.config.AuthenticationPrincipal; -import solitour_backend.solitour.auth.service.OauthService; -import solitour_backend.solitour.auth.support.google.GoogleConnector; -import solitour_backend.solitour.auth.support.kakao.KakaoConnector; import solitour_backend.solitour.gathering.dto.response.GatheringApplicantResponse; -import solitour_backend.solitour.gathering.dto.response.GatheringBriefResponse; import solitour_backend.solitour.gathering.dto.response.GatheringMypageResponse; import solitour_backend.solitour.information.dto.response.InformationBriefResponse; -import solitour_backend.solitour.user.dto.UpdateAgeAndSex; import solitour_backend.solitour.user.dto.UpdateNicknameRequest; import solitour_backend.solitour.user.dto.request.UpdateUserInfoRequest; import solitour_backend.solitour.user.exception.NicknameAlreadyExistsException; @@ -41,7 +35,6 @@ public class UserController { private final UserService userService; - public static final int PAGE_SIZE = 6; @GetMapping("/info") @@ -52,12 +45,20 @@ public ResponseEntity retrieveUserInfo(@AuthenticationPrincipa } @PutMapping("/info") - public ResponseEntity updateUserInfo(@AuthenticationPrincipal Long userId, @RequestBody UpdateUserInfoRequest request) { + public ResponseEntity updateUserInfo(@AuthenticationPrincipal Long userId, + @RequestBody UpdateUserInfoRequest request) { userService.updateUserInfo(userId, request); return ResponseEntity.noContent().build(); } + @DeleteMapping("/profile") + public ResponseEntity deleteUserProfile(@AuthenticationPrincipal Long userId) { + userService.deleteUserProfile(userId); + + return ResponseEntity.ok().build(); + } + @PutMapping("/nickname") public ResponseEntity updateNickname(@AuthenticationPrincipal Long userId, @RequestBody UpdateNicknameRequest request) { diff --git a/src/main/java/solitour_backend/solitour/user/entity/User.java b/src/main/java/solitour_backend/solitour/user/entity/User.java index 659e2228..3be37531 100644 --- a/src/main/java/solitour_backend/solitour/user/entity/User.java +++ b/src/main/java/solitour_backend/solitour/user/entity/User.java @@ -107,7 +107,7 @@ public void updateLoginTime() { public void updateUserInfo(UpdateUserInfoRequest request) { this.name = request.getName(); - this.userStatus = UserStatus.ACTIVE; + this.userStatus = UserStatus.ACTIVATE; this.age = Integer.valueOf(request.getAge()); this.sex = request.getSex(); } diff --git a/src/main/java/solitour_backend/solitour/user/repository/UserRepositoryCustom.java b/src/main/java/solitour_backend/solitour/user/repository/UserRepositoryCustom.java index 1ae4a264..32765091 100644 --- a/src/main/java/solitour_backend/solitour/user/repository/UserRepositoryCustom.java +++ b/src/main/java/solitour_backend/solitour/user/repository/UserRepositoryCustom.java @@ -4,7 +4,6 @@ import org.springframework.data.domain.Pageable; import org.springframework.data.repository.NoRepositoryBean; import solitour_backend.solitour.gathering.dto.response.GatheringApplicantResponse; -import solitour_backend.solitour.gathering.dto.response.GatheringBriefResponse; import solitour_backend.solitour.gathering.dto.response.GatheringMypageResponse; import solitour_backend.solitour.information.dto.response.InformationBriefResponse; diff --git a/src/main/java/solitour_backend/solitour/user/repository/UserRepositoryImpl.java b/src/main/java/solitour_backend/solitour/user/repository/UserRepositoryImpl.java index 165203f4..c01c02a0 100644 --- a/src/main/java/solitour_backend/solitour/user/repository/UserRepositoryImpl.java +++ b/src/main/java/solitour_backend/solitour/user/repository/UserRepositoryImpl.java @@ -8,9 +8,7 @@ import com.querydsl.core.types.dsl.StringExpression; import com.querydsl.jpa.JPAExpressions; import com.querydsl.jpa.JPQLQuery; - import java.util.List; - import org.springframework.beans.factory.annotation.Value; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageImpl; @@ -20,7 +18,6 @@ import solitour_backend.solitour.book_mark_information.entity.QBookMarkInformation; import solitour_backend.solitour.gathering.dto.response.GatheringApplicantResponse; import solitour_backend.solitour.gathering.dto.response.GatheringMypageResponse; -import solitour_backend.solitour.gathering.dto.response.GatheringMypageResponse; import solitour_backend.solitour.gathering.entity.Gathering; import solitour_backend.solitour.gathering.entity.QGathering; import solitour_backend.solitour.gathering_applicants.entity.GatheringStatus; @@ -147,7 +144,8 @@ public Page retrieveGatheringHost(Pageable pageable, Lo .leftJoin(gatheringCategory) .on(gatheringCategory.id.eq(gathering.gatheringCategory.id)) .leftJoin(gatheringApplicants) - .on(gatheringApplicants.gathering.id.eq(gathering.id).and(gatheringApplicants.gatheringStatus.eq(GatheringStatus.CONSENT))) + .on(gatheringApplicants.gathering.id.eq(gathering.id) + .and(gatheringApplicants.gatheringStatus.eq(GatheringStatus.CONSENT))) .orderBy(gathering.createdAt.desc()) .where(gathering.user.id.eq(userId)); @@ -195,7 +193,8 @@ public Page retrieveGatheringBookmark(Pageable pageable .leftJoin(gatheringCategory) .on(gatheringCategory.id.eq(gathering.gatheringCategory.id)) .leftJoin(gatheringApplicants) - .on(gatheringApplicants.gathering.id.eq(gathering.id).and(gatheringApplicants.gatheringStatus.eq(GatheringStatus.CONSENT))) + .on(gatheringApplicants.gathering.id.eq(gathering.id) + .and(gatheringApplicants.gatheringStatus.eq(GatheringStatus.CONSENT))) .leftJoin(bookMarkGathering) .on(bookMarkGathering.gathering.id.eq(gathering.id)) .orderBy(gathering.createdAt.desc()) @@ -241,7 +240,6 @@ public Page retrieveGatheringApplicant(Pageable page StringExpression gatheringStatus = getGatheringStatus(); NumberExpression gatheringApplicantCount = countGatheringApplicant(userId); - JPQLQuery query = from(gathering) .leftJoin(zoneCategoryParent) .on(zoneCategoryParent.id.eq(gathering.zoneCategory.parentZoneCategory.id)) @@ -254,7 +252,7 @@ public Page retrieveGatheringApplicant(Pageable page List list = query .groupBy(gathering.id, zoneCategoryParent.id, zoneCategoryChild.id, - gatheringCategory.id, gatheringApplicants.id) + gatheringCategory.id, gatheringApplicants.id) .select(Projections.constructor( GatheringApplicantResponse.class, gathering.id, @@ -273,7 +271,7 @@ public Page retrieveGatheringApplicant(Pageable page gathering.startAge, gathering.endAge, gathering.personCount, - gatheringApplicantCount, isUserGreatGathering(userId), + gatheringApplicantCount, isUserGreatGathering(userId), gatheringStatus, gathering.isFinish )) @@ -291,7 +289,8 @@ private NumberExpression countGatheringApplicant(Long userId) { JPQLQuery countApplicant = JPAExpressions .select(gatheringApplicants.count()) .from(gatheringApplicants) - .where(gatheringApplicants.user.id.eq(userId).and(gatheringApplicants.gatheringStatus.eq(GatheringStatus.CONSENT))); + .where(gatheringApplicants.user.id.eq(userId) + .and(gatheringApplicants.gatheringStatus.eq(GatheringStatus.CONSENT))); return Expressions.numberTemplate(Long.class, "{0}", countApplicant) .coalesce(0L) diff --git a/src/main/java/solitour_backend/solitour/user/service/UserService.java b/src/main/java/solitour_backend/solitour/user/service/UserService.java index 325ec666..e8fcc629 100644 --- a/src/main/java/solitour_backend/solitour/user/service/UserService.java +++ b/src/main/java/solitour_backend/solitour/user/service/UserService.java @@ -8,7 +8,6 @@ import org.springframework.transaction.annotation.Transactional; import org.springframework.web.multipart.MultipartFile; import solitour_backend.solitour.gathering.dto.response.GatheringApplicantResponse; -import solitour_backend.solitour.gathering.dto.response.GatheringBriefResponse; import solitour_backend.solitour.gathering.dto.response.GatheringMypageResponse; import solitour_backend.solitour.image.s3.S3Uploader; import solitour_backend.solitour.information.dto.response.InformationBriefResponse; @@ -18,8 +17,6 @@ import solitour_backend.solitour.user.repository.UserRepository; import solitour_backend.solitour.user.service.dto.response.UserInfoResponse; import solitour_backend.solitour.user_image.dto.UserImageResponse; -import solitour_backend.solitour.user_image.entity.UserImage; -import solitour_backend.solitour.user_image.entity.UserImageRepository; import solitour_backend.solitour.user_image.service.UserImageService; @Service @@ -29,6 +26,13 @@ public class UserService { private final UserRepository userRepository; private final UserImageService userImageService; + private final S3Uploader s3Uploader; + @Value("${user.profile.url.female}") + private String femaleProfileUrl; + @Value("${user.profile.male}") + private String maleProfileUrl; + @Value("${user.profile.none}") + private String noneProfileUrl; public UserInfoResponse retrieveUserInfo(Long userId) { User user = userRepository.findByUserId(userId); @@ -55,11 +59,18 @@ public Page retrieveInformationBookmark(Pageable pagea @Transactional public void updateUserProfile(Long userId, MultipartFile userProfile) { - UserImageResponse response = userImageService.registerInformation(userId, userProfile); + UserImageResponse response = userImageService.updateUserProfile(userId, userProfile); User user = userRepository.findByUserId(userId); + checkUserProfile(user.getUserImage().getAddress()); user.updateUserImage(response.getImageUrl()); } + @Transactional + public void deleteUserProfile(Long userId) { + User user = userRepository.findByUserId(userId); + resetUserProfile(user, user.getUserImage().getAddress(), user.getSex()); + } + public Page retrieveGatheringHost(Pageable pageable, Long userId) { return userRepository.retrieveGatheringHost(pageable, userId); } @@ -77,4 +88,22 @@ public void updateUserInfo(Long userId, UpdateUserInfoRequest request) { User user = userRepository.findByUserId(userId); user.updateUserInfo(request); } + + private void resetUserProfile(User user, String imageUrl, String sex) { + checkUserProfile(imageUrl); + if (sex.equals("male")) { + user.updateUserImage(maleProfileUrl); + } else if (sex.equals("female")) { + user.updateUserImage(femaleProfileUrl); + } else { + user.updateUserImage(noneProfileUrl); + } + } + + private void checkUserProfile(String imageUrl) { + if (imageUrl.equals(femaleProfileUrl) || imageUrl.equals(maleProfileUrl) || imageUrl.equals(noneProfileUrl)) { + return; + } + s3Uploader.deleteImage(imageUrl); + } } diff --git a/src/main/java/solitour_backend/solitour/user_image/controller/UserImageController.java b/src/main/java/solitour_backend/solitour/user_image/controller/UserImageController.java index 0db91a59..bb798347 100644 --- a/src/main/java/solitour_backend/solitour/user_image/controller/UserImageController.java +++ b/src/main/java/solitour_backend/solitour/user_image/controller/UserImageController.java @@ -27,7 +27,7 @@ public ResponseEntity createUserImage(@RequestPart("request") @RequestPart("userImage") MultipartFile userImage, BindingResult bindingResult) { Utils.validationRequest(bindingResult); - UserImageResponse informationResponse = userImageService.registerInformation( + UserImageResponse informationResponse = userImageService.updateUserProfile( imageRequest.getUserId(), userImage); return ResponseEntity diff --git a/src/main/java/solitour_backend/solitour/user_image/service/UserImageService.java b/src/main/java/solitour_backend/solitour/user_image/service/UserImageService.java index 2a9496bd..6f509925 100644 --- a/src/main/java/solitour_backend/solitour/user_image/service/UserImageService.java +++ b/src/main/java/solitour_backend/solitour/user_image/service/UserImageService.java @@ -29,7 +29,7 @@ public UserImage saveUserImage(String imageUrl) { } @Transactional - public UserImageResponse registerInformation(Long userId, MultipartFile userImage) { + public UserImageResponse updateUserProfile(Long userId, MultipartFile userImage) { String userImageUrl = s3Uploader.upload(userImage, IMAGE_PATH, userId); From 645a4f6847e946a780ee7a26f231ec7c69aba167 Mon Sep 17 00:00:00 2001 From: Donghun Won Date: Sun, 22 Sep 2024 00:05:06 +0900 Subject: [PATCH 333/371] =?UTF-8?q?Fix=20:=20=ED=94=84=EB=A1=9C=ED=95=84?= =?UTF-8?q?=20=EC=9D=B4=EB=AF=B8=EC=A7=80=20yml=20=EA=B2=BD=EB=A1=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 --- .../solitour_backend/solitour/user/service/UserService.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/solitour_backend/solitour/user/service/UserService.java b/src/main/java/solitour_backend/solitour/user/service/UserService.java index e8fcc629..eef5f0a3 100644 --- a/src/main/java/solitour_backend/solitour/user/service/UserService.java +++ b/src/main/java/solitour_backend/solitour/user/service/UserService.java @@ -29,9 +29,9 @@ public class UserService { private final S3Uploader s3Uploader; @Value("${user.profile.url.female}") private String femaleProfileUrl; - @Value("${user.profile.male}") + @Value("${user.profile.url.male}") private String maleProfileUrl; - @Value("${user.profile.none}") + @Value("${user.profile.url.none}") private String noneProfileUrl; public UserInfoResponse retrieveUserInfo(Long userId) { From 65db7d90f677c233b1de2b534787e25ae9a8d26e Mon Sep 17 00:00:00 2001 From: Donghun Won Date: Sun, 22 Sep 2024 00:06:19 +0900 Subject: [PATCH 334/371] =?UTF-8?q?Revert=20"Fix=20:=20=ED=94=84=EB=A1=9C?= =?UTF-8?q?=ED=95=84=20=EC=9D=B4=EB=AF=B8=EC=A7=80=20yml=20=EA=B2=BD?= =?UTF-8?q?=EB=A1=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 645a4f6847e946a780ee7a26f231ec7c69aba167. --- .../solitour_backend/solitour/user/service/UserService.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/solitour_backend/solitour/user/service/UserService.java b/src/main/java/solitour_backend/solitour/user/service/UserService.java index eef5f0a3..e8fcc629 100644 --- a/src/main/java/solitour_backend/solitour/user/service/UserService.java +++ b/src/main/java/solitour_backend/solitour/user/service/UserService.java @@ -29,9 +29,9 @@ public class UserService { private final S3Uploader s3Uploader; @Value("${user.profile.url.female}") private String femaleProfileUrl; - @Value("${user.profile.url.male}") + @Value("${user.profile.male}") private String maleProfileUrl; - @Value("${user.profile.url.none}") + @Value("${user.profile.none}") private String noneProfileUrl; public UserInfoResponse retrieveUserInfo(Long userId) { From 68abaa6d276a1fc3b34e8d0433dbe3ec04b5c64a Mon Sep 17 00:00:00 2001 From: Donghun Won Date: Sun, 22 Sep 2024 00:07:36 +0900 Subject: [PATCH 335/371] =?UTF-8?q?Feat=20:=20=ED=94=84=EB=A1=9C=ED=95=84?= =?UTF-8?q?=20=EC=9D=B4=EB=AF=B8=EC=A7=80=20yml=20=EA=B2=BD=EB=A1=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 --- .../solitour_backend/solitour/user/service/UserService.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/solitour_backend/solitour/user/service/UserService.java b/src/main/java/solitour_backend/solitour/user/service/UserService.java index e8fcc629..eef5f0a3 100644 --- a/src/main/java/solitour_backend/solitour/user/service/UserService.java +++ b/src/main/java/solitour_backend/solitour/user/service/UserService.java @@ -29,9 +29,9 @@ public class UserService { private final S3Uploader s3Uploader; @Value("${user.profile.url.female}") private String femaleProfileUrl; - @Value("${user.profile.male}") + @Value("${user.profile.url.male}") private String maleProfileUrl; - @Value("${user.profile.none}") + @Value("${user.profile.url.none}") private String noneProfileUrl; public UserInfoResponse retrieveUserInfo(Long userId) { From 089b461edca02f631854737fb248e33c9be04146 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Sun, 22 Sep 2024 16:58:01 +0900 Subject: [PATCH 336/371] =?UTF-8?q?docs:=20application-common=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/deploy.yml | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 3ab74785..d29e776c 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -23,17 +23,12 @@ jobs: run: | mkdir -p ./src/main/resources echo "${{ secrets.APPLICATION_YML }}" > ./src/main/resources/application.yml + echo "${{ secrets.APPLICATION_COMMON }}" > ./src/main/resources/application-common.yml echo "${{ secrets.APPLICATION_DEV }}" > ./src/main/resources/application-dev.yml echo "${{ secrets.APPLICATION_PROD }}" > ./src/main/resources/application-prod.yml echo "${{ secrets.APPLICATION_LOCAL }}" > ./src/main/resources/application-local.yml echo "${{ secrets.APPLICATION_TEST }}" > ./src/main/resources/application-test.yml -# - name: sql 파일 만들기 -# run: | -# echo "${{ secrets.SCHEMA }}" > ./src/main/resources/schema.sql -# echo "${{ secrets.CATEGORY }}" > ./src/main/resources/category.sql -# echo "${{ secrets.GATHERING_CATEGORY }}" > ./src/main/resources/gathering_category.sql -# echo "${{ secrets.ZONE_CATEGORY }}" > ./src/main/resources/zone_category.sql - name: gradlew 실행 권한 부여 run: chmod +x ./gradlew From 0fdd62fade6ca326a7322b6213f4454f542388bc Mon Sep 17 00:00:00 2001 From: Donghun Won Date: Sun, 22 Sep 2024 18:14:46 +0900 Subject: [PATCH 337/371] =?UTF-8?q?Fix=20:=20=ED=86=A0=ED=81=B0=20?= =?UTF-8?q?=EC=98=88=EC=99=B8=EC=B2=98=EB=A6=AC=20=EC=88=98=EC=A0=95=20(#1?= =?UTF-8?q?93)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../solitour/gathering/controller/GatheringController.java | 3 ++- .../solitour/information/controller/InformationController.java | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/main/java/solitour_backend/solitour/gathering/controller/GatheringController.java b/src/main/java/solitour_backend/solitour/gathering/controller/GatheringController.java index 73ffeee6..d6472d9b 100644 --- a/src/main/java/solitour_backend/solitour/gathering/controller/GatheringController.java +++ b/src/main/java/solitour_backend/solitour/gathering/controller/GatheringController.java @@ -29,6 +29,7 @@ import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import solitour_backend.solitour.auth.config.AuthenticationPrincipal; +import solitour_backend.solitour.auth.exception.TokenNotExistsException; import solitour_backend.solitour.auth.exception.TokenNotValidException; import solitour_backend.solitour.auth.support.CookieExtractor; import solitour_backend.solitour.auth.support.JwtTokenProvider; @@ -212,7 +213,7 @@ private Long findUser(HttpServletRequest request) { } if (jwtTokenProvider.validateTokenNotUsable(token)) { - throw new TokenNotValidException("토큰이 유효하지 않습니다."); + throw new TokenNotExistsException("토큰이 존재하지 않습니다."); } return jwtTokenProvider.getPayload(token); diff --git a/src/main/java/solitour_backend/solitour/information/controller/InformationController.java b/src/main/java/solitour_backend/solitour/information/controller/InformationController.java index e188c9e5..fda63684 100644 --- a/src/main/java/solitour_backend/solitour/information/controller/InformationController.java +++ b/src/main/java/solitour_backend/solitour/information/controller/InformationController.java @@ -19,6 +19,7 @@ import org.springframework.web.bind.annotation.*; import solitour_backend.solitour.auth.config.Authenticated; import solitour_backend.solitour.auth.config.AuthenticationPrincipal; +import solitour_backend.solitour.auth.exception.TokenNotExistsException; import solitour_backend.solitour.auth.exception.TokenNotValidException; import solitour_backend.solitour.auth.support.CookieExtractor; import solitour_backend.solitour.auth.support.JwtTokenProvider; @@ -165,7 +166,7 @@ private Long findUser(HttpServletRequest request) { } if (jwtTokenProvider.validateTokenNotUsable(token)) { - throw new TokenNotValidException("토큰이 유효하지 않습니다."); + throw new TokenNotExistsException("토큰이 존재하지 않습니다."); } return jwtTokenProvider.getPayload(token); From 87c65d163dd109e03f32eae84057f3280cba25a7 Mon Sep 17 00:00:00 2001 From: Donghun Won Date: Sun, 22 Sep 2024 18:14:59 +0900 Subject: [PATCH 338/371] =?UTF-8?q?Fix=20:=20=EB=8B=A4=EC=9D=B4=EC=96=B4?= =?UTF-8?q?=EB=A6=AC=20=EC=9E=A5=EC=86=8C=20=EA=B8=80=EC=9E=90=EC=88=98=20?= =?UTF-8?q?=EC=88=98=EC=A0=95=20(#194)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../solitour_backend/solitour/diary/service/DiaryService.java | 2 +- src/main/resources/schema.sql | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/solitour_backend/solitour/diary/service/DiaryService.java b/src/main/java/solitour_backend/solitour/diary/service/DiaryService.java index 18ae66f5..eb71af52 100644 --- a/src/main/java/solitour_backend/solitour/diary/service/DiaryService.java +++ b/src/main/java/solitour_backend/solitour/diary/service/DiaryService.java @@ -94,7 +94,7 @@ public void updateDiary(Long userId, Long diaryId, DiaryUpdateRequest request) { } private void updateDiary(Long diaryId, DiaryUpdateRequest request) { - Diary diary = diaryRepository.findById(diaryId).orElseThrow(() -> new RuntimeException("Diary not found")); + Diary diary = diaryRepository.findById(diaryId).orElseThrow(() -> new DiaryNotExistsException("해당 일기가 존재하지 않습니다.")); deleteDiaryImage(request); diary.getDiaryDayContent().clear(); diary.updateDiary(request); diff --git a/src/main/resources/schema.sql b/src/main/resources/schema.sql index d9b1a94d..80fd873d 100644 --- a/src/main/resources/schema.sql +++ b/src/main/resources/schema.sql @@ -305,7 +305,7 @@ CREATE TABLE `diary_day_content` ( `diary_day_content_id` BIGINT NOT NULL AUTO_INCREMENT, `diary_id` BIGINT NOT NULL, - `diary_day_content_place` VARCHAR(20) NOT NULL, + `diary_day_content_place` VARCHAR(50) NOT NULL, `diary_day_content_content` TEXT NOT NULL, `diary_day_content_feeling_status` VARCHAR(20) NOT NULL, `diary_day_content_image` TEXT DEFAULT NULL, From 7535e300ef1bed429453b41a54e701a669c68169 Mon Sep 17 00:00:00 2001 From: Donghun Won Date: Sun, 22 Sep 2024 19:14:44 +0900 Subject: [PATCH 339/371] =?UTF-8?q?Fix=20:=20=EB=B9=84=ED=99=9C=EC=84=B1?= =?UTF-8?q?=ED=99=94=20=EC=83=81=ED=83=9C=EC=97=90=EC=84=9C=EB=8F=84=20?= =?UTF-8?q?=EB=A1=9C=EA=B7=B8=EC=9D=B8=20=EB=90=98=EB=8F=84=EB=A1=9D=20?= =?UTF-8?q?=EC=88=98=EC=A0=95=20(#195)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../solitour/user/repository/UserRepository.java | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/src/main/java/solitour_backend/solitour/user/repository/UserRepository.java b/src/main/java/solitour_backend/solitour/user/repository/UserRepository.java index 12b784ae..d745b376 100644 --- a/src/main/java/solitour_backend/solitour/user/repository/UserRepository.java +++ b/src/main/java/solitour_backend/solitour/user/repository/UserRepository.java @@ -7,16 +7,10 @@ public interface UserRepository extends JpaRepository, UserRepositoryCustom { - @Query("SELECT u FROM User u JOIN FETCH u.userImage WHERE u.nickname = :nickname AND u.userStatus = '활성화'") - Optional findByNickname(String nickname); - - @Query("SELECT u FROM User u JOIN FETCH u.userImage WHERE u.email = :email AND u.userStatus = '활성화'") - Optional findByEmail(String email); - - @Query("SELECT u FROM User u JOIN FETCH u.userImage WHERE u.id = :userId AND u.userStatus = '활성화'") + @Query("SELECT u FROM User u JOIN FETCH u.userImage WHERE u.id = :userId AND u.userStatus = '활성화' OR u.userStatus = '비활성화'") User findByUserId(Long userId); - @Query("SELECT u FROM User u JOIN FETCH u.userImage WHERE u.oauthId = :oauthId AND u.userStatus = '활성화'") + @Query("SELECT u FROM User u JOIN FETCH u.userImage WHERE u.oauthId = :oauthId AND u.userStatus = '활성화' OR u.userStatus = '비활성화'") Optional findByOauthId(String oauthId); boolean existsByNickname(String nickname); From ebc5dc6b776e1e6be7168eba75a6e3f6240100dc Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Sun, 22 Sep 2024 19:38:55 +0900 Subject: [PATCH 340/371] =?UTF-8?q?fix:=20home=20information=20order=20?= =?UTF-8?q?=EC=A0=88=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../information/repository/InformationRepositoryImpl.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/solitour_backend/solitour/information/repository/InformationRepositoryImpl.java b/src/main/java/solitour_backend/solitour/information/repository/InformationRepositoryImpl.java index ce3b4455..568320bc 100644 --- a/src/main/java/solitour_backend/solitour/information/repository/InformationRepositoryImpl.java +++ b/src/main/java/solitour_backend/solitour/information/repository/InformationRepositoryImpl.java @@ -119,7 +119,7 @@ public List getInformationLikeCountFromCreatedIn3(Long .where(information.createdDate.after(LocalDateTime.now().minusMonths(3))) .groupBy(information.id, information.title, zoneCategoryParent.name, zoneCategoryChild.name, bookMarkInformation.id, image.address) - .orderBy(greatInformation.information.id.count().desc()) + .orderBy(countGreatInformationByInformationById().desc()) .select(Projections.constructor( InformationMainResponse.class, information.id, @@ -238,7 +238,7 @@ public List getInformationRank() { .leftJoin(greatInformation) .on(greatInformation.information.id.eq(information.id)) .groupBy(information.id, information.title) - .orderBy(greatInformation.information.id.count().desc()) + .orderBy(countGreatInformationByInformationById().desc()) .limit(5) .select(Projections.constructor( InformationRankResponse.class, From a7e5ba3585a76b1a0a2f79994dc0f2baf496247f Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Sun, 22 Sep 2024 20:32:33 +0900 Subject: [PATCH 341/371] =?UTF-8?q?fix:=20=EC=A2=8B=EC=95=84=EC=9A=94=20?= =?UTF-8?q?=EC=88=98=20=EA=B5=AC=ED=95=98=EB=8A=94=20=EC=A0=88=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 --- .../repository/GatheringRepositoryImpl.java | 53 +++++++------------ .../repository/InformationRepositoryImpl.java | 41 ++++++-------- 2 files changed, 33 insertions(+), 61 deletions(-) diff --git a/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryImpl.java b/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryImpl.java index c614e7fc..b1a0facf 100644 --- a/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryImpl.java +++ b/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryImpl.java @@ -3,11 +3,7 @@ import com.querydsl.core.BooleanBuilder; import com.querydsl.core.types.OrderSpecifier; import com.querydsl.core.types.Projections; -import com.querydsl.core.types.dsl.BooleanExpression; -import com.querydsl.core.types.dsl.CaseBuilder; -import com.querydsl.core.types.dsl.Expressions; -import com.querydsl.core.types.dsl.NumberExpression; -import com.querydsl.core.types.dsl.PathBuilder; +import com.querydsl.core.types.dsl.*; import com.querydsl.jpa.JPAExpressions; import com.querydsl.jpa.JPQLQuery; @@ -51,8 +47,6 @@ public GatheringRepositoryImpl() { @Override public List getGatheringRecommend(Long gatheringId, Long gatheringCategoryId, Long userId) { - NumberExpression likeCount = countGreatGatheringByGatheringById(); - NumberExpression applicantsCount = applicantsCountNowConsent(); return from(gathering) .join(zoneCategoryChild).on(zoneCategoryChild.id.eq(gathering.zoneCategory.id)) .leftJoin(zoneCategoryParent).on(zoneCategoryParent.id.eq(zoneCategoryChild.parentZoneCategory.id)) @@ -76,7 +70,7 @@ public List getGatheringRecommend(Long gatheringId, Long zoneCategoryChild.name, gathering.viewCount, isGatheringBookmark(userId), - likeCount, + countGreatGatheringByGatheringById(gathering.id), gathering.gatheringCategory.name, gathering.user.nickname, gathering.scheduleStartDate, @@ -86,7 +80,7 @@ public List getGatheringRecommend(Long gatheringId, Long gathering.startAge, gathering.endAge, gathering.personCount, - applicantsCount, + applicantsCountNowConsent(gathering.id), isUserGreatGathering(userId) )).limit(3L).fetch(); } @@ -98,11 +92,6 @@ public Page getGatheringPageFilterAndOrder(Pageable page Long userId) { BooleanBuilder booleanBuilder = makeWhereSQL(gatheringPageRequest); - OrderSpecifier orderSpecifier = getOrderSpecifier(gatheringPageRequest.getSort()); - - NumberExpression countGreatGathering = countGreatGatheringByGatheringById(); - NumberExpression applicantsCount = applicantsCountNowConsent(); - long total = from(gathering) .where(booleanBuilder) .select(gathering.id).fetchCount(); @@ -116,7 +105,7 @@ public Page getGatheringPageFilterAndOrder(Pageable page gathering.scheduleStartDate, gathering.scheduleEndDate, gathering.deadline, gathering.allowedSex, gathering.startAge, gathering.endAge, gathering.personCount) - .orderBy(orderSpecifier) + .orderBy(getOrderSpecifier(gatheringPageRequest.getSort(), gathering.id)) .select(Projections.constructor( GatheringBriefResponse.class, gathering.id, @@ -125,7 +114,7 @@ public Page getGatheringPageFilterAndOrder(Pageable page zoneCategoryChild.name, gathering.viewCount, isGatheringBookmark(userId), - countGreatGathering, + countGreatGatheringByGatheringById(gathering.id), gathering.gatheringCategory.name, gathering.user.nickname, gathering.scheduleStartDate, @@ -135,7 +124,7 @@ public Page getGatheringPageFilterAndOrder(Pageable page gathering.startAge, gathering.endAge, gathering.personCount, - applicantsCount, + applicantsCountNowConsent(gathering.id), isUserGreatGathering(userId) )) .offset(pageable.getOffset()) @@ -151,10 +140,6 @@ public Page getPageGatheringByTag(Pageable pageable, String decodedTag) { BooleanBuilder booleanBuilder = makeWhereSQL(gatheringPageRequest); - OrderSpecifier orderSpecifier = getOrderSpecifier(gatheringPageRequest.getSort()); - - NumberExpression countGreatGathering = countGreatGatheringByGatheringById(); - long total = from(gathering) .join(zoneCategoryChild).on(zoneCategoryChild.id.eq(gathering.zoneCategory.id)) .leftJoin(zoneCategoryParent).on(zoneCategoryParent.id.eq(zoneCategoryChild.parentZoneCategory.id)) @@ -176,7 +161,7 @@ public Page getPageGatheringByTag(Pageable pageable, .on(gatheringTag.gathering.id.eq(gathering.id).and(gatheringTag.tag.name.eq(decodedTag))) .where(booleanBuilder.and(gatheringTag.tag.name.eq(decodedTag))) .groupBy(gathering.id, zoneCategoryChild.id, zoneCategoryParent.id, category.id) - .orderBy(orderSpecifier) + .orderBy(getOrderSpecifier(gatheringPageRequest.getSort(), gathering.id)) .select(Projections.constructor( GatheringBriefResponse.class, gathering.id, @@ -185,7 +170,7 @@ public Page getPageGatheringByTag(Pageable pageable, zoneCategoryChild.name, gathering.viewCount, bookMarkGathering.user.id.isNotNull(), - countGreatGathering, + countGreatGatheringByGatheringById(gathering.id), gathering.gatheringCategory.name, gathering.user.name, gathering.scheduleStartDate, @@ -208,7 +193,7 @@ public Page getPageGatheringByTag(Pageable pageable, @Override public List getGatheringRankList() { return from(gathering) - .orderBy(countGreatGatheringByGatheringById().desc()) + .orderBy(countGreatGatheringByGatheringById(gathering.id).desc()) .groupBy(gathering.id, gathering.title) .where(gathering.isFinish.eq(Boolean.FALSE) .and(gathering.isDeleted.eq(Boolean.FALSE)) @@ -224,8 +209,6 @@ public List getGatheringRankList() { @Override public List getGatheringLikeCountFromCreatedIn3(Long userId) { - NumberExpression likeCount = countGreatGatheringByGatheringById(); - NumberExpression applicantsCount = applicantsCountNowConsent(); return from(gathering) .join(zoneCategoryChild).on(zoneCategoryChild.id.eq(gathering.zoneCategory.id)) .leftJoin(zoneCategoryParent).on(zoneCategoryParent.id.eq(zoneCategoryChild.parentZoneCategory.id)) @@ -238,7 +221,7 @@ public List getGatheringLikeCountFromCreatedIn3(Long use gathering.scheduleStartDate, gathering.scheduleEndDate, gathering.deadline, gathering.allowedSex, gathering.startAge, gathering.endAge, gathering.personCount) - .orderBy(likeCount.desc()) + .orderBy(countGreatGatheringByGatheringById(gathering.id).desc()) .select(Projections.constructor( GatheringBriefResponse.class, gathering.id, @@ -247,7 +230,7 @@ public List getGatheringLikeCountFromCreatedIn3(Long use zoneCategoryChild.name, gathering.viewCount, isGatheringBookmark(userId), - likeCount, + countGreatGatheringByGatheringById(gathering.id), gathering.gatheringCategory.name, gathering.user.nickname, gathering.scheduleStartDate, @@ -257,7 +240,7 @@ public List getGatheringLikeCountFromCreatedIn3(Long use gathering.startAge, gathering.endAge, gathering.personCount, - applicantsCount, + applicantsCountNowConsent(gathering.id), isUserGreatGathering(userId) )).limit(6L).fetch(); } @@ -306,12 +289,12 @@ private BooleanBuilder makeWhereSQL(GatheringPageRequest gatheringPageRequest) { } // 정렬 방식 - private OrderSpecifier getOrderSpecifier(String sort) { + private OrderSpecifier getOrderSpecifier(String sort, NumberPath gatheringId) { PathBuilder entityPath = new PathBuilder<>(Gathering.class, "gathering"); if (Objects.nonNull(sort)) { if (LIKE_COUNT_SORT.equalsIgnoreCase(sort)) { - return countGreatGatheringByGatheringById().desc(); + return countGreatGatheringByGatheringById(gatheringId).desc(); } else if (VIEW_COUNT_SORT.equalsIgnoreCase(sort)) { return entityPath.getNumber("viewCount", Integer.class).desc(); } @@ -321,12 +304,12 @@ private OrderSpecifier getOrderSpecifier(String sort) { } // 좋아요 수 가져오는 식 - private NumberExpression countGreatGatheringByGatheringById() { + private NumberExpression countGreatGatheringByGatheringById(NumberPath gatheringId) { QGreatGathering greatGatheringSub = QGreatGathering.greatGathering; JPQLQuery likeCountSubQuery = JPAExpressions .select(greatGatheringSub.count()) .from(greatGatheringSub) - .where(greatGatheringSub.gathering.id.eq(gathering.id)); + .where(greatGatheringSub.gathering.id.eq(gatheringId)); return Expressions.numberTemplate(Long.class, "{0}", likeCountSubQuery) .coalesce(0L) @@ -355,11 +338,11 @@ private BooleanExpression isGatheringBookmark(Long userId) { .otherwise(false); } - private NumberExpression applicantsCountNowConsent() { + private NumberExpression applicantsCountNowConsent(NumberPath gatheringId) { JPQLQuery applicantsCountSubQuery = JPAExpressions .select(gatheringApplicants.count().intValue()) .from(gatheringApplicants) - .where(gatheringApplicants.gathering.id.eq(gathering.id) + .where(gatheringApplicants.gathering.id.eq(gatheringId) .and(gatheringApplicants.gatheringStatus.eq(GatheringStatus.CONSENT))); return Expressions.numberTemplate(Integer.class, "{0}", applicantsCountSubQuery) diff --git a/src/main/java/solitour_backend/solitour/information/repository/InformationRepositoryImpl.java b/src/main/java/solitour_backend/solitour/information/repository/InformationRepositoryImpl.java index 568320bc..8bdb8522 100644 --- a/src/main/java/solitour_backend/solitour/information/repository/InformationRepositoryImpl.java +++ b/src/main/java/solitour_backend/solitour/information/repository/InformationRepositoryImpl.java @@ -3,10 +3,7 @@ import com.querydsl.core.BooleanBuilder; import com.querydsl.core.types.OrderSpecifier; import com.querydsl.core.types.Projections; -import com.querydsl.core.types.dsl.BooleanExpression; -import com.querydsl.core.types.dsl.CaseBuilder; -import com.querydsl.core.types.dsl.Expressions; -import com.querydsl.core.types.dsl.NumberExpression; +import com.querydsl.core.types.dsl.*; import com.querydsl.jpa.JPAExpressions; import com.querydsl.jpa.JPQLQuery; @@ -72,8 +69,6 @@ public Page getInformationPageFilterAndOrder(Pageable whereClause.and(information.title.trim().containsIgnoreCase(searchKeyword)); } - OrderSpecifier orderSpecifier = getOrderSpecifier(informationPageRequest.getSort()); - NumberExpression countGreatInformation = countGreatInformationByInformationById(); long total = from(information) .where(whereClause) @@ -87,7 +82,7 @@ public Page getInformationPageFilterAndOrder(Pageable .join(category).on(category.id.eq(information.category.id).and(categoryCondition)) .where(whereClause) .groupBy(information.id, zoneCategoryChild.id, zoneCategoryParent.id, image.id) - .orderBy(orderSpecifier) + .orderBy(getOrderSpecifier(informationPageRequest.getSort(), information.id)) .select(Projections.constructor( InformationBriefResponse.class, information.id, @@ -98,7 +93,7 @@ public Page getInformationPageFilterAndOrder(Pageable information.viewCount, isInformationBookmark(userId), image.address, - countGreatInformation, + countGreatInformationByInformationById(information.id), isUserGreatInformation(userId) )).offset(pageable.getOffset()) .limit(pageable.getPageSize()) @@ -113,13 +108,12 @@ public List getInformationLikeCountFromCreatedIn3(Long return from(information) .leftJoin(zoneCategoryChild).on(zoneCategoryChild.id.eq(information.zoneCategory.id)) .leftJoin(zoneCategoryParent).on(zoneCategoryParent.id.eq(zoneCategoryChild.parentZoneCategory.id)) - .leftJoin(image) - .on(image.information.id.eq(information.id).and(image.imageStatus.eq(ImageStatus.THUMBNAIL))) + .leftJoin(image).on(image.information.id.eq(information.id).and(image.imageStatus.eq(ImageStatus.THUMBNAIL))) .leftJoin(category).on(category.id.eq(information.category.id)) .where(information.createdDate.after(LocalDateTime.now().minusMonths(3))) .groupBy(information.id, information.title, zoneCategoryParent.name, zoneCategoryChild.name, bookMarkInformation.id, image.address) - .orderBy(countGreatInformationByInformationById().desc()) + .orderBy(countGreatInformationByInformationById(information.id).desc()) // 파라미터로 information.id 전달 .select(Projections.constructor( InformationMainResponse.class, information.id, @@ -130,10 +124,9 @@ public List getInformationLikeCountFromCreatedIn3(Long information.viewCount, isInformationBookmark(userId), image.address, - countGreatInformationByInformationById(), + countGreatInformationByInformationById(information.id), // 파라미터 전달 isUserGreatInformation(userId) )).limit(6).fetch(); - } @Override @@ -157,7 +150,7 @@ public List getInformationRecommend(Long informationId information.viewCount, isInformationBookmark(userId), image.address, - countGreatInformationByInformationById(), + countGreatInformationByInformationById(information.id), isUserGreatInformation(userId) )) .limit(3L) @@ -183,8 +176,6 @@ public Page getInformationPageByTag(Pageable pageable, categoryCondition.and(category.parentCategory.id.eq(parentCategoryId)); } - OrderSpecifier orderSpecifier = getOrderSpecifier(informationPageRequest.getSort()); - NumberExpression countGreatInformation = countGreatInformationByInformationById(); long total = from(information) .join(zoneCategoryChild).on(zoneCategoryChild.id.eq(information.zoneCategory.id)) @@ -212,7 +203,7 @@ public Page getInformationPageByTag(Pageable pageable, .on(infoTag.information.id.eq(information.id)) .where(whereClause) .groupBy(information.id, zoneCategoryChild.id, zoneCategoryParent.id, image.id, infoTag.id) - .orderBy(orderSpecifier) + .orderBy(getOrderSpecifier(informationPageRequest.getSort(), information.id)) .select(Projections.constructor( InformationBriefResponse.class, information.id, @@ -223,7 +214,7 @@ public Page getInformationPageByTag(Pageable pageable, information.viewCount, bookMarkInformation.user.id.isNotNull(), image.address, - countGreatInformation, + countGreatInformationByInformationById(information.id), isUserGreatInformation(userId) )).offset(pageable.getOffset()) .limit(pageable.getPageSize()) @@ -238,7 +229,7 @@ public List getInformationRank() { .leftJoin(greatInformation) .on(greatInformation.information.id.eq(information.id)) .groupBy(information.id, information.title) - .orderBy(countGreatInformationByInformationById().desc()) + .orderBy(countGreatInformationByInformationById(information.id).desc()) .limit(5) .select(Projections.constructor( InformationRankResponse.class, @@ -247,10 +238,10 @@ public List getInformationRank() { )).fetch(); } - private OrderSpecifier getOrderSpecifier(String sort) { + private OrderSpecifier getOrderSpecifier(String sort, NumberPath informationId) { if (Objects.nonNull(sort)) { if (Objects.equals(LIKE_COUNT_SORT, sort)) { - return countGreatInformationByInformationById().desc(); + return countGreatInformationByInformationById(informationId).desc(); } else if (Objects.equals(VIEW_COUNT_SORT, sort)) { return information.viewCount.desc(); } @@ -258,16 +249,14 @@ private OrderSpecifier getOrderSpecifier(String sort) { return information.createdDate.desc(); } - private NumberExpression countGreatInformationByInformationById() { + private NumberExpression countGreatInformationByInformationById(NumberPath informationId) { QGreatInformation greatInformationSub = QGreatInformation.greatInformation; JPQLQuery likeCountSubQuery = JPAExpressions .select(greatInformationSub.count()) .from(greatInformationSub) - .where(greatInformationSub.information.id.eq(information.id)); + .where(greatInformationSub.information.id.eq(informationId)); // 파라미터로 받은 NumberPath와 비교 - return Expressions.numberTemplate(Long.class, "{0}", likeCountSubQuery) - .coalesce(0L) - .intValue(); + return Expressions.asNumber(likeCountSubQuery).longValue(); // 명확하게 Long 타입 반환 } private BooleanExpression isUserGreatInformation(Long userId) { From 42e2bb95d55d6253376baa7d1756ece38d64a1c5 Mon Sep 17 00:00:00 2001 From: Donghun Won Date: Sun, 22 Sep 2024 20:44:09 +0900 Subject: [PATCH 342/371] =?UTF-8?q?fix=20:=20=EB=A1=9C=EA=B7=B8=EC=9D=B8?= =?UTF-8?q?=20=EC=9C=A0=EC=A0=80=20=EC=83=81=ED=83=9C=20=ED=99=95=EC=9D=B8?= =?UTF-8?q?=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../solitour/user/repository/UserRepository.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/solitour_backend/solitour/user/repository/UserRepository.java b/src/main/java/solitour_backend/solitour/user/repository/UserRepository.java index d745b376..059014d9 100644 --- a/src/main/java/solitour_backend/solitour/user/repository/UserRepository.java +++ b/src/main/java/solitour_backend/solitour/user/repository/UserRepository.java @@ -7,10 +7,10 @@ public interface UserRepository extends JpaRepository, UserRepositoryCustom { - @Query("SELECT u FROM User u JOIN FETCH u.userImage WHERE u.id = :userId AND u.userStatus = '활성화' OR u.userStatus = '비활성화'") + @Query("SELECT u FROM User u JOIN FETCH u.userImage WHERE u.id = :userId AND (u.userStatus = '활성화' OR u.userStatus = '비활성화')") User findByUserId(Long userId); - @Query("SELECT u FROM User u JOIN FETCH u.userImage WHERE u.oauthId = :oauthId AND u.userStatus = '활성화' OR u.userStatus = '비활성화'") + @Query("SELECT u FROM User u JOIN FETCH u.userImage WHERE u.oauthId = :oauthId AND (u.userStatus = '활성화' OR u.userStatus = '비활성화')") Optional findByOauthId(String oauthId); boolean existsByNickname(String nickname); From cc55833b8abd77b6f4b66d2bfdb0885dfbd89f8b Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Sun, 22 Sep 2024 20:46:00 +0900 Subject: [PATCH 343/371] =?UTF-8?q?fix:=20=EC=A2=8B=EC=95=84=EC=9A=94=20?= =?UTF-8?q?=EC=88=98=20=EA=B5=AC=ED=95=98=EB=8A=94=20=EC=A0=88=20=EC=88=98?= =?UTF-8?q?=EC=A0=95=20Long=20->=20Integer=20=EB=A1=9C=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 --- .../information/repository/InformationRepositoryImpl.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/main/java/solitour_backend/solitour/information/repository/InformationRepositoryImpl.java b/src/main/java/solitour_backend/solitour/information/repository/InformationRepositoryImpl.java index 8bdb8522..49a38c46 100644 --- a/src/main/java/solitour_backend/solitour/information/repository/InformationRepositoryImpl.java +++ b/src/main/java/solitour_backend/solitour/information/repository/InformationRepositoryImpl.java @@ -249,14 +249,16 @@ private OrderSpecifier getOrderSpecifier(String sort, NumberPath inform return information.createdDate.desc(); } - private NumberExpression countGreatInformationByInformationById(NumberPath informationId) { + private NumberExpression countGreatInformationByInformationById(NumberPath informationId) { QGreatInformation greatInformationSub = QGreatInformation.greatInformation; JPQLQuery likeCountSubQuery = JPAExpressions .select(greatInformationSub.count()) .from(greatInformationSub) .where(greatInformationSub.information.id.eq(informationId)); // 파라미터로 받은 NumberPath와 비교 - return Expressions.asNumber(likeCountSubQuery).longValue(); // 명확하게 Long 타입 반환 + return Expressions.numberTemplate(Long.class, "{0}", likeCountSubQuery) + .coalesce(0L) + .intValue(); } private BooleanExpression isUserGreatInformation(Long userId) { From f756a4d20adc8815a9cfe80f0a218f30f6f8cefc Mon Sep 17 00:00:00 2001 From: Fiat_lux <50399586+hyeonjaez@users.noreply.github.com> Date: Sun, 22 Sep 2024 21:02:50 +0900 Subject: [PATCH 344/371] =?UTF-8?q?fix:=20bookMark=20=ED=96=88=EB=8A=94?= =?UTF-8?q?=EC=A7=80=20=EA=B5=AC=ED=95=98=EB=8A=94=20=EC=A0=88=20=EC=88=98?= =?UTF-8?q?=EC=A0=95=20(#200)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../gathering/repository/GatheringRepositoryImpl.java | 10 +++++----- .../repository/InformationRepositoryImpl.java | 10 +++++----- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryImpl.java b/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryImpl.java index b1a0facf..918b278f 100644 --- a/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryImpl.java +++ b/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryImpl.java @@ -69,7 +69,7 @@ public List getGatheringRecommend(Long gatheringId, Long zoneCategoryParent.name, zoneCategoryChild.name, gathering.viewCount, - isGatheringBookmark(userId), + isGatheringBookmark(userId, gathering.id), countGreatGatheringByGatheringById(gathering.id), gathering.gatheringCategory.name, gathering.user.nickname, @@ -113,7 +113,7 @@ public Page getGatheringPageFilterAndOrder(Pageable page zoneCategoryParent.name, zoneCategoryChild.name, gathering.viewCount, - isGatheringBookmark(userId), + isGatheringBookmark(userId, gathering.id), countGreatGatheringByGatheringById(gathering.id), gathering.gatheringCategory.name, gathering.user.nickname, @@ -229,7 +229,7 @@ public List getGatheringLikeCountFromCreatedIn3(Long use zoneCategoryParent.name, zoneCategoryChild.name, gathering.viewCount, - isGatheringBookmark(userId), + isGatheringBookmark(userId, gathering.id), countGreatGatheringByGatheringById(gathering.id), gathering.gatheringCategory.name, gathering.user.nickname, @@ -327,11 +327,11 @@ private BooleanExpression isUserGreatGathering(Long userId) { .otherwise(false); } - private BooleanExpression isGatheringBookmark(Long userId) { + private BooleanExpression isGatheringBookmark(Long userId, NumberPath gatheringId) { return new CaseBuilder() .when(JPAExpressions.selectOne() .from(bookMarkGathering) - .where(bookMarkGathering.gathering.id.eq(gathering.id) + .where(bookMarkGathering.gathering.id.eq(gatheringId) .and(bookMarkGathering.user.id.eq(userId))) .exists()) .then(true) diff --git a/src/main/java/solitour_backend/solitour/information/repository/InformationRepositoryImpl.java b/src/main/java/solitour_backend/solitour/information/repository/InformationRepositoryImpl.java index 49a38c46..6b502347 100644 --- a/src/main/java/solitour_backend/solitour/information/repository/InformationRepositoryImpl.java +++ b/src/main/java/solitour_backend/solitour/information/repository/InformationRepositoryImpl.java @@ -91,7 +91,7 @@ public Page getInformationPageFilterAndOrder(Pageable zoneCategoryChild.name, information.category.name, information.viewCount, - isInformationBookmark(userId), + isInformationBookmark(userId, information.id), image.address, countGreatInformationByInformationById(information.id), isUserGreatInformation(userId) @@ -122,7 +122,7 @@ public List getInformationLikeCountFromCreatedIn3(Long zoneCategoryChild.name, category.parentCategory.name, information.viewCount, - isInformationBookmark(userId), + isInformationBookmark(userId, information.id), image.address, countGreatInformationByInformationById(information.id), // 파라미터 전달 isUserGreatInformation(userId) @@ -148,7 +148,7 @@ public List getInformationRecommend(Long informationId zoneCategoryChild.name, information.category.name, information.viewCount, - isInformationBookmark(userId), + isInformationBookmark(userId, information.id), image.address, countGreatInformationByInformationById(information.id), isUserGreatInformation(userId) @@ -272,11 +272,11 @@ private BooleanExpression isUserGreatInformation(Long userId) { .otherwise(false); } - private BooleanExpression isInformationBookmark(Long userId) { + private BooleanExpression isInformationBookmark(Long userId, NumberPath informationId) { return new CaseBuilder() .when(JPAExpressions.selectOne() .from(bookMarkInformation) - .where(bookMarkInformation.information.id.eq(information.id) + .where(bookMarkInformation.information.id.eq(informationId) .and(bookMarkInformation.user.id.eq(userId))) .exists()) .then(true) From a07f0834eddc6222494aa52dcd35c245d14a78ef Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Sun, 22 Sep 2024 21:13:23 +0900 Subject: [PATCH 345/371] =?UTF-8?q?fix:=20join=20->=20=EC=84=9C=EB=B8=8C?= =?UTF-8?q?=EC=BF=BC=EB=A6=AC=EB=A1=9C=20=EC=B2=98=EB=A6=AC=ED=9B=84=20gro?= =?UTF-8?q?up=20by=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../repository/GatheringRepositoryImpl.java | 18 +++--------------- .../repository/InformationRepositoryImpl.java | 5 ++--- 2 files changed, 5 insertions(+), 18 deletions(-) diff --git a/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryImpl.java b/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryImpl.java index 918b278f..90809047 100644 --- a/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryImpl.java +++ b/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryImpl.java @@ -56,11 +56,7 @@ public List getGatheringRecommend(Long gatheringId, Long .and(gathering.isDeleted.eq(Boolean.FALSE)) .and(gathering.deadline.after(LocalDateTime.now())) ) - .groupBy(gathering.id, zoneCategoryChild.id, zoneCategoryParent.id, category.id, - gathering.title, gathering.viewCount, gathering.user.name, - gathering.scheduleStartDate, gathering.scheduleEndDate, - gathering.deadline, gathering.allowedSex, - gathering.startAge, gathering.endAge, gathering.personCount) + .groupBy(gathering.id, zoneCategoryChild.id, zoneCategoryParent.id) .orderBy(gathering.createdAt.desc()) .select(Projections.constructor( GatheringBriefResponse.class, @@ -100,11 +96,7 @@ public Page getGatheringPageFilterAndOrder(Pageable page .join(zoneCategoryChild).on(zoneCategoryChild.id.eq(gathering.zoneCategory.id)) .leftJoin(zoneCategoryParent).on(zoneCategoryParent.id.eq(zoneCategoryChild.parentZoneCategory.id)) .where(booleanBuilder) - .groupBy(gathering.id, zoneCategoryChild.id, zoneCategoryParent.id, category.id, - gathering.title, gathering.viewCount, gathering.user.name, - gathering.scheduleStartDate, gathering.scheduleEndDate, - gathering.deadline, gathering.allowedSex, - gathering.startAge, gathering.endAge, gathering.personCount) + .groupBy(gathering.id, zoneCategoryChild.id, zoneCategoryParent.id) .orderBy(getOrderSpecifier(gatheringPageRequest.getSort(), gathering.id)) .select(Projections.constructor( GatheringBriefResponse.class, @@ -216,11 +208,7 @@ public List getGatheringLikeCountFromCreatedIn3(Long use .and(gathering.isDeleted.eq(Boolean.FALSE)) .and(gathering.createdAt.after(LocalDateTime.now().minusMonths(3))) .and(gathering.deadline.after(LocalDateTime.now()))) - .groupBy(gathering.id, zoneCategoryChild.id, zoneCategoryParent.id, category.id, - gathering.title, gathering.viewCount, gathering.user.name, - gathering.scheduleStartDate, gathering.scheduleEndDate, - gathering.deadline, gathering.allowedSex, - gathering.startAge, gathering.endAge, gathering.personCount) + .groupBy(gathering.id, zoneCategoryChild.id, zoneCategoryParent.id) .orderBy(countGreatGatheringByGatheringById(gathering.id).desc()) .select(Projections.constructor( GatheringBriefResponse.class, diff --git a/src/main/java/solitour_backend/solitour/information/repository/InformationRepositoryImpl.java b/src/main/java/solitour_backend/solitour/information/repository/InformationRepositoryImpl.java index 6b502347..67a26578 100644 --- a/src/main/java/solitour_backend/solitour/information/repository/InformationRepositoryImpl.java +++ b/src/main/java/solitour_backend/solitour/information/repository/InformationRepositoryImpl.java @@ -111,9 +111,8 @@ public List getInformationLikeCountFromCreatedIn3(Long .leftJoin(image).on(image.information.id.eq(information.id).and(image.imageStatus.eq(ImageStatus.THUMBNAIL))) .leftJoin(category).on(category.id.eq(information.category.id)) .where(information.createdDate.after(LocalDateTime.now().minusMonths(3))) - .groupBy(information.id, information.title, zoneCategoryParent.name, zoneCategoryChild.name, - bookMarkInformation.id, image.address) - .orderBy(countGreatInformationByInformationById(information.id).desc()) // 파라미터로 information.id 전달 + .groupBy(information.id, zoneCategoryParent.name, zoneCategoryChild.name, image.address) + .orderBy(countGreatInformationByInformationById(information.id).desc()) .select(Projections.constructor( InformationMainResponse.class, information.id, From 24208ad21dd492ef7298e15f25c61eccc297890a Mon Sep 17 00:00:00 2001 From: Donghun Won Date: Sun, 22 Sep 2024 21:28:29 +0900 Subject: [PATCH 346/371] =?UTF-8?q?Fix=20:=20=EC=A0=95=EB=B3=B4=20?= =?UTF-8?q?=EC=B9=B4=ED=85=8C=EA=B3=A0=EB=A6=AC=20=EC=9D=B4=EB=A6=84=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../solitour/user/repository/UserRepositoryImpl.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/solitour_backend/solitour/user/repository/UserRepositoryImpl.java b/src/main/java/solitour_backend/solitour/user/repository/UserRepositoryImpl.java index c01c02a0..f8ac7fc5 100644 --- a/src/main/java/solitour_backend/solitour/user/repository/UserRepositoryImpl.java +++ b/src/main/java/solitour_backend/solitour/user/repository/UserRepositoryImpl.java @@ -81,6 +81,7 @@ public Page retrieveInformationOwner(Pageable pageable information.title, zoneCategoryParent.name, zoneCategoryChild.name, + information.category.name, information.viewCount, bookMarkInformation.user.id.isNotNull(), image.address, From 1f95640a20eb5e1fb04213979dbe0b0d472dce91 Mon Sep 17 00:00:00 2001 From: Donghun Won Date: Sun, 22 Sep 2024 21:32:17 +0900 Subject: [PATCH 347/371] =?UTF-8?q?Fix=20:=20=EC=B9=B4=ED=85=8C=EA=B3=A0?= =?UTF-8?q?=EB=A6=AC=20=EC=9D=B4=EB=A6=84=20=ED=95=84=EB=93=9C=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../solitour/user/repository/UserRepositoryImpl.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/solitour_backend/solitour/user/repository/UserRepositoryImpl.java b/src/main/java/solitour_backend/solitour/user/repository/UserRepositoryImpl.java index f8ac7fc5..6a4193bd 100644 --- a/src/main/java/solitour_backend/solitour/user/repository/UserRepositoryImpl.java +++ b/src/main/java/solitour_backend/solitour/user/repository/UserRepositoryImpl.java @@ -119,6 +119,7 @@ public Page retrieveInformationBookmark(Pageable pagea information.title, zoneCategoryParent.name, zoneCategoryChild.name, + information.category.name, information.viewCount, bookMarkInformation.user.id.isNotNull(), image.address, From 404656093e00cae677e2b0f5e7dc9f9848982f49 Mon Sep 17 00:00:00 2001 From: Donghun Won Date: Sun, 22 Sep 2024 22:24:28 +0900 Subject: [PATCH 348/371] =?UTF-8?q?Refactor=20:=20=EC=84=B1=EB=B3=84?= =?UTF-8?q?=EC=9E=85=EB=A0=A5=EC=8B=9C=20=EC=9C=A0=EC=A0=80=20=ED=94=84?= =?UTF-8?q?=EB=A1=9C=ED=95=84=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../solitour/user/service/UserService.java | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/main/java/solitour_backend/solitour/user/service/UserService.java b/src/main/java/solitour_backend/solitour/user/service/UserService.java index eef5f0a3..b370a72c 100644 --- a/src/main/java/solitour_backend/solitour/user/service/UserService.java +++ b/src/main/java/solitour_backend/solitour/user/service/UserService.java @@ -86,9 +86,19 @@ public Page retrieveGatheringApplicant(Pageable page @Transactional public void updateUserInfo(Long userId, UpdateUserInfoRequest request) { User user = userRepository.findByUserId(userId); + changeUserProfile(user, request); user.updateUserInfo(request); } + private void changeUserProfile(User user, UpdateUserInfoRequest request) { + String sex = request.getSex(); + if(sex.equals("male")){ + user.updateUserImage(maleProfileUrl); + } else if (sex.equals("female")) { + user.updateUserImage(femaleProfileUrl); + } + } + private void resetUserProfile(User user, String imageUrl, String sex) { checkUserProfile(imageUrl); if (sex.equals("male")) { From 866434dc0eb5bfbba734834a048cdd3ea6134936 Mon Sep 17 00:00:00 2001 From: Donghun Won Date: Sun, 22 Sep 2024 22:57:42 +0900 Subject: [PATCH 349/371] =?UTF-8?q?Fix=20:=20=EC=9C=A0=EC=A0=80=20?= =?UTF-8?q?=ED=94=84=EB=A1=9C=ED=95=84=EC=9D=B4=20=EB=94=94=ED=8F=B4?= =?UTF-8?q?=ED=8A=B8=20=ED=94=84=EB=A1=9C=ED=95=84=EC=9D=BC=EB=95=8C?= =?UTF-8?q?=EB=A7=8C=20=EB=B3=80=EA=B2=BD=20(#205)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../solitour_backend/solitour/user/service/UserService.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/java/solitour_backend/solitour/user/service/UserService.java b/src/main/java/solitour_backend/solitour/user/service/UserService.java index b370a72c..92bcd343 100644 --- a/src/main/java/solitour_backend/solitour/user/service/UserService.java +++ b/src/main/java/solitour_backend/solitour/user/service/UserService.java @@ -92,9 +92,10 @@ public void updateUserInfo(Long userId, UpdateUserInfoRequest request) { private void changeUserProfile(User user, UpdateUserInfoRequest request) { String sex = request.getSex(); - if(sex.equals("male")){ + + if(user.getUserImage().equals(noneProfileUrl) && sex.equals("male")){ user.updateUserImage(maleProfileUrl); - } else if (sex.equals("female")) { + } else if (user.getUserImage().equals(noneProfileUrl) && sex.equals("female")) { user.updateUserImage(femaleProfileUrl); } } From 36d536aa1e6bbed1aad6136ded9e2b6fd3862288 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Mon, 23 Sep 2024 01:40:37 +0900 Subject: [PATCH 350/371] =?UTF-8?q?fix:=20applicatns=20=EB=B6=80=EB=B6=84?= =?UTF-8?q?=20join=20->=20=EC=84=9C=EB=B8=8C=EC=BF=BC=EB=A6=AC=EB=A1=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 --- .../repository/GatheringRepositoryImpl.java | 33 ++++++++----------- 1 file changed, 13 insertions(+), 20 deletions(-) diff --git a/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryImpl.java b/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryImpl.java index 90809047..8d9c7101 100644 --- a/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryImpl.java +++ b/src/main/java/solitour_backend/solitour/gathering/repository/GatheringRepositoryImpl.java @@ -128,31 +128,24 @@ public Page getGatheringPageFilterAndOrder(Pageable page @Override public Page getPageGatheringByTag(Pageable pageable, - GatheringPageRequest gatheringPageRequest, Long userId, + GatheringPageRequest gatheringPageRequest, + Long userId, String decodedTag) { BooleanBuilder booleanBuilder = makeWhereSQL(gatheringPageRequest); + booleanBuilder.and(gatheringTag.tag.name.eq(decodedTag)); long total = from(gathering) - .join(zoneCategoryChild).on(zoneCategoryChild.id.eq(gathering.zoneCategory.id)) - .leftJoin(zoneCategoryParent).on(zoneCategoryParent.id.eq(zoneCategoryChild.parentZoneCategory.id)) - .leftJoin(bookMarkGathering) - .on(bookMarkGathering.gathering.id.eq(gathering.id).and(bookMarkGathering.user.id.eq(userId))) - .leftJoin(gatheringApplicants).on(gatheringApplicants.gathering.id.eq(gathering.id)) - .leftJoin(gatheringTag) - .on(gatheringTag.gathering.id.eq(gathering.id).and(gatheringTag.tag.name.eq(decodedTag))) - .where(booleanBuilder.and(gatheringTag.tag.name.eq(decodedTag))) - .select(gathering.id.count()).fetchCount(); + .leftJoin(gatheringTag).on(gatheringTag.gathering.id.eq(gathering.id)) + .where(booleanBuilder) + .select(gathering.id.count()) + .fetchCount(); List content = from(gathering) .join(zoneCategoryChild).on(zoneCategoryChild.id.eq(gathering.zoneCategory.id)) .leftJoin(zoneCategoryParent).on(zoneCategoryParent.id.eq(zoneCategoryChild.parentZoneCategory.id)) - .leftJoin(bookMarkGathering) - .on(gatheringApplicants.gathering.id.eq(gathering.id).and(gatheringApplicants.gatheringStatus.eq(GatheringStatus.CONSENT))) - .leftJoin(gatheringApplicants).on(gatheringApplicants.gathering.id.eq(gathering.id).and(gatheringApplicants.gatheringStatus.eq(GatheringStatus.CONSENT))) - .leftJoin(gatheringTag) - .on(gatheringTag.gathering.id.eq(gathering.id).and(gatheringTag.tag.name.eq(decodedTag))) - .where(booleanBuilder.and(gatheringTag.tag.name.eq(decodedTag))) - .groupBy(gathering.id, zoneCategoryChild.id, zoneCategoryParent.id, category.id) + .leftJoin(gatheringTag).on(gatheringTag.gathering.id.eq(gathering.id)) + .where(booleanBuilder) + .groupBy(gathering.id, zoneCategoryChild.id, zoneCategoryParent.id) .orderBy(getOrderSpecifier(gatheringPageRequest.getSort(), gathering.id)) .select(Projections.constructor( GatheringBriefResponse.class, @@ -161,10 +154,10 @@ public Page getPageGatheringByTag(Pageable pageable, zoneCategoryParent.name, zoneCategoryChild.name, gathering.viewCount, - bookMarkGathering.user.id.isNotNull(), + isGatheringBookmark(userId, gathering.id), countGreatGatheringByGatheringById(gathering.id), gathering.gatheringCategory.name, - gathering.user.name, + gathering.user.nickname, gathering.scheduleStartDate, gathering.scheduleEndDate, gathering.deadline, @@ -172,7 +165,7 @@ public Page getPageGatheringByTag(Pageable pageable, gathering.startAge, gathering.endAge, gathering.personCount, - gatheringApplicants.count().coalesce(0L).intValue(), + applicantsCountNowConsent(gathering.id), isUserGreatGathering(userId) )) .offset(pageable.getOffset()) From b820b589ab1c772777492ed68c5613fdb5cb2876 Mon Sep 17 00:00:00 2001 From: Donghun Won Date: Mon, 23 Sep 2024 17:33:37 +0900 Subject: [PATCH 351/371] =?UTF-8?q?Fix=20:=20=EB=A7=88=EC=9D=B4=ED=8E=98?= =?UTF-8?q?=EC=9D=B4=EC=A7=80=20=EB=AA=A8=EC=9E=84=20=EC=A1=B0=ED=9A=8C=20?= =?UTF-8?q?=EC=98=A4=EB=A5=98=20=EC=88=98=EC=A0=95=20(#207)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Fix : 삭제된 모임 조회되지 않도록 수정 * Fix : 모임 인원수 오류 수정 자기자신을 인원에 포함하지 않는 문제 여러명의 인원을 1명으로 인식하는 문제 --- .../user/repository/UserRepositoryImpl.java | 25 ++++++++++--------- 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/src/main/java/solitour_backend/solitour/user/repository/UserRepositoryImpl.java b/src/main/java/solitour_backend/solitour/user/repository/UserRepositoryImpl.java index 6a4193bd..0ee5b1d6 100644 --- a/src/main/java/solitour_backend/solitour/user/repository/UserRepositoryImpl.java +++ b/src/main/java/solitour_backend/solitour/user/repository/UserRepositoryImpl.java @@ -5,6 +5,7 @@ import com.querydsl.core.types.dsl.CaseBuilder; import com.querydsl.core.types.dsl.Expressions; import com.querydsl.core.types.dsl.NumberExpression; +import com.querydsl.core.types.dsl.NumberPath; import com.querydsl.core.types.dsl.StringExpression; import com.querydsl.jpa.JPAExpressions; import com.querydsl.jpa.JPQLQuery; @@ -149,7 +150,7 @@ public Page retrieveGatheringHost(Pageable pageable, Lo .on(gatheringApplicants.gathering.id.eq(gathering.id) .and(gatheringApplicants.gatheringStatus.eq(GatheringStatus.CONSENT))) .orderBy(gathering.createdAt.desc()) - .where(gathering.user.id.eq(userId)); + .where(gathering.user.id.eq(userId).and(gathering.isDeleted.eq(false))); List list = query .groupBy(gathering.id, zoneCategoryParent.id, zoneCategoryChild.id, @@ -200,7 +201,7 @@ public Page retrieveGatheringBookmark(Pageable pageable .leftJoin(bookMarkGathering) .on(bookMarkGathering.gathering.id.eq(gathering.id)) .orderBy(gathering.createdAt.desc()) - .where(bookMarkGathering.user.id.eq(userId)); + .where(bookMarkGathering.user.id.eq(userId).and(gathering.isDeleted.eq(false))); List list = query .groupBy(gathering.id, zoneCategoryParent.id, zoneCategoryChild.id, @@ -240,7 +241,7 @@ public Page retrieveGatheringApplicant(Pageable page NumberExpression likeCount = countGreatGatheringByGatheringById(); BooleanExpression isBookMark = isGatheringBookmark(userId); StringExpression gatheringStatus = getGatheringStatus(); - NumberExpression gatheringApplicantCount = countGatheringApplicant(userId); + NumberExpression gatheringApplicantCount = countGatheringApplicant(gathering.id); JPQLQuery query = from(gathering) .leftJoin(zoneCategoryParent) @@ -250,7 +251,7 @@ public Page retrieveGatheringApplicant(Pageable page .leftJoin(gatheringApplicants) .on(gatheringApplicants.gathering.id.eq(gathering.id)) .orderBy(gathering.createdAt.desc()) - .where(gatheringApplicants.user.id.eq(userId).and(gathering.user.id.eq(userId).not())); + .where(gatheringApplicants.user.id.eq(userId).and(gathering.user.id.eq(userId).not()).and(gathering.isDeleted.eq(false))); List list = query .groupBy(gathering.id, zoneCategoryParent.id, zoneCategoryChild.id, @@ -273,7 +274,8 @@ public Page retrieveGatheringApplicant(Pageable page gathering.startAge, gathering.endAge, gathering.personCount, - gatheringApplicantCount, isUserGreatGathering(userId), + gatheringApplicantCount, + isUserGreatGathering(userId), gatheringStatus, gathering.isFinish )) @@ -285,18 +287,17 @@ gatheringApplicantCount, isUserGreatGathering(userId), return new PageImpl<>(list, pageable, total); } - private NumberExpression countGatheringApplicant(Long userId) { + private NumberExpression countGatheringApplicant(NumberPath gatheringId) { QGatheringApplicants gatheringApplicants = QGatheringApplicants.gatheringApplicants; - JPQLQuery countApplicant = JPAExpressions - .select(gatheringApplicants.count()) + JPQLQuery countApplicant = JPAExpressions + .select(gatheringApplicants.count().intValue()) .from(gatheringApplicants) - .where(gatheringApplicants.user.id.eq(userId) + .where(gatheringApplicants.gathering.id.eq(gatheringId) .and(gatheringApplicants.gatheringStatus.eq(GatheringStatus.CONSENT))); - return Expressions.numberTemplate(Long.class, "{0}", countApplicant) - .coalesce(0L) - .intValue(); + return Expressions.numberTemplate(Integer.class, "{0}", countApplicant) + .coalesce(0); } @Override From 43b85b1bf583dd26bfc60db98ef0512feea7d6f7 Mon Sep 17 00:00:00 2001 From: Donghun Won Date: Tue, 24 Sep 2024 17:23:29 +0900 Subject: [PATCH 352/371] =?UTF-8?q?Fix=20:=20main=20ci=EC=8B=9C=20jar=20?= =?UTF-8?q?=ED=8C=8C=EC=9D=BC=20=EB=AC=B8=EB=B2=95=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/deploy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index d29e776c..05e2e3bf 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -69,7 +69,7 @@ jobs: mv /home/ubuntu/solitour-server/tobe/project.jar /home/ubuntu/solitour-server/current/project.jar cd /home/ubuntu/solitour-server/current sudo fuser -k -n tcp 8080 || true - nohup java -jar -Dspring.profiles.active=prod project.jar & > ./output.log 2>&1 & + nohup java -jar -Dspring.profiles.active=prod project.jar > ./output.log 2>&1 & rm -rf /home/ubuntu/solitour-server/tobe - name: SSH로 EC2 접속 From 65bcb22dd0dc1cb5a86ef7d3b5584641f18c5eba Mon Sep 17 00:00:00 2001 From: Donghun Won Date: Wed, 25 Sep 2024 18:27:10 +0900 Subject: [PATCH 353/371] =?UTF-8?q?Fix=20:=20=EC=B9=B4=EC=B9=B4=EC=98=A4?= =?UTF-8?q?=20=ED=9A=8C=EC=9B=90=ED=83=88=ED=87=B4=20=EC=98=A4=EB=A5=98=20?= =?UTF-8?q?=EC=88=98=EC=A0=95=20,=20=EC=B9=B4=EC=B9=B4=EC=98=A4=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80=EC=A0=95=EB=B3=B4=20=EC=9E=88=EC=9D=84?= =?UTF-8?q?=EB=95=8C=20=ED=9A=8C=EC=9B=90=EA=B0=80=EC=9E=85=20(#210)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Feat : 카카오 추가정보 있을때 회원가입 * Fix : 카카오 회원탈퇴 오류 수정 성별이 필드가 비어있을때 조회 사용하는 로직 수정 --- .../auth/controller/OauthController.java | 23 ++++- .../solitour/auth/service/OauthService.java | 96 ++++++++++++++++--- .../solitour/auth/service/TokenService.java | 4 +- .../dto/request/CreateUserInfoRequest.java | 12 +++ 4 files changed, 119 insertions(+), 16 deletions(-) create mode 100644 src/main/java/solitour_backend/solitour/auth/support/kakao/dto/request/CreateUserInfoRequest.java diff --git a/src/main/java/solitour_backend/solitour/auth/controller/OauthController.java b/src/main/java/solitour_backend/solitour/auth/controller/OauthController.java index c745848d..931f75f3 100644 --- a/src/main/java/solitour_backend/solitour/auth/controller/OauthController.java +++ b/src/main/java/solitour_backend/solitour/auth/controller/OauthController.java @@ -4,11 +4,11 @@ import jakarta.servlet.http.Cookie; import jakarta.servlet.http.HttpServletResponse; import lombok.RequiredArgsConstructor; -import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; @@ -18,12 +18,16 @@ import solitour_backend.solitour.auth.entity.Token; import solitour_backend.solitour.auth.entity.TokenRepository; import solitour_backend.solitour.auth.exception.TokenNotExistsException; +import solitour_backend.solitour.auth.exception.UnsupportedLoginTypeException; +import solitour_backend.solitour.auth.exception.UserRevokeErrorException; import solitour_backend.solitour.auth.service.OauthService; import solitour_backend.solitour.auth.service.dto.response.AccessTokenResponse; import solitour_backend.solitour.auth.service.dto.response.LoginResponse; import solitour_backend.solitour.auth.service.dto.response.OauthLinkResponse; import solitour_backend.solitour.auth.support.google.GoogleConnector; import solitour_backend.solitour.auth.support.kakao.KakaoConnector; +import solitour_backend.solitour.auth.support.kakao.dto.request.CreateUserInfoRequest; +import solitour_backend.solitour.auth.support.naver.NaverConnector; import solitour_backend.solitour.user.user_status.UserStatus; @@ -35,6 +39,7 @@ public class OauthController { private final OauthService oauthService; private final KakaoConnector kakaoConnector; private final GoogleConnector googleConnector; + private final NaverConnector naverConnector; private final TokenRepository tokenRepository; @GetMapping(value = "/login", params = {"type", "redirectUrl"}) @@ -43,6 +48,22 @@ public ResponseEntity access(@RequestParam String type, @Requ return ResponseEntity.ok(response); } + @PostMapping(value = "/login/kakao", params = {"code", "redirectUrl"}) + public ResponseEntity kakaoLogin(HttpServletResponse response, + @RequestParam String code, @RequestParam String redirectUrl, + @RequestBody CreateUserInfoRequest createUserInfoRequest) { + LoginResponse loginResponse = oauthService.requestkakaoAccessToken(code, redirectUrl, createUserInfoRequest); + + String accessCookieHeader = setCookieHeader(loginResponse.getAccessToken()); + String refreshCookieHeader = setCookieHeader(loginResponse.getRefreshToken()); + + response.addHeader("Set-Cookie", accessCookieHeader); + response.addHeader("Set-Cookie", refreshCookieHeader); + + return ResponseEntity.ok(loginResponse.getLoginStatus()); + } + + @GetMapping(value = "/login", params = {"type", "code", "redirectUrl"}) public ResponseEntity login(HttpServletResponse response, @RequestParam String type, @RequestParam String code, @RequestParam String redirectUrl) { diff --git a/src/main/java/solitour_backend/solitour/auth/service/OauthService.java b/src/main/java/solitour_backend/solitour/auth/service/OauthService.java index 413b16cd..f7d90dac 100644 --- a/src/main/java/solitour_backend/solitour/auth/service/OauthService.java +++ b/src/main/java/solitour_backend/solitour/auth/service/OauthService.java @@ -14,6 +14,8 @@ import org.springframework.transaction.annotation.Transactional; import solitour_backend.solitour.auth.entity.Token; import solitour_backend.solitour.auth.entity.TokenRepository; +import solitour_backend.solitour.auth.exception.RevokeFailException; +import solitour_backend.solitour.auth.exception.UnsupportedLoginTypeException; import solitour_backend.solitour.auth.service.dto.response.AccessTokenResponse; import solitour_backend.solitour.auth.service.dto.response.LoginResponse; import solitour_backend.solitour.auth.service.dto.response.OauthLinkResponse; @@ -27,6 +29,12 @@ import solitour_backend.solitour.auth.support.kakao.dto.KakaoTokenAndUserResponse; import solitour_backend.solitour.auth.support.kakao.dto.KakaoTokenResponse; import solitour_backend.solitour.auth.support.kakao.dto.KakaoUserResponse; +import solitour_backend.solitour.auth.support.kakao.dto.request.CreateUserInfoRequest; +import solitour_backend.solitour.auth.support.naver.NaverConnector; +import solitour_backend.solitour.auth.support.naver.NaverProvider; +import solitour_backend.solitour.auth.support.naver.dto.NaverTokenAndUserResponse; +import solitour_backend.solitour.auth.support.naver.dto.NaverTokenResponse; +import solitour_backend.solitour.auth.support.naver.dto.NaverUserResponse; import solitour_backend.solitour.image.s3.S3Uploader; import solitour_backend.solitour.user.entity.User; import solitour_backend.solitour.user.exception.BlockedUserException; @@ -49,6 +57,8 @@ public class OauthService { private final KakaoProvider kakaoProvider; private final GoogleConnector googleConnector; private final GoogleProvider googleProvider; + private final NaverConnector naverConnector; + private final NaverProvider naverProvider; private final UserImageService userImageService; private final TokenRepository tokenRepository; private final UserImageRepository userImageRepository; @@ -83,6 +93,25 @@ public LoginResponse requestAccessToken(String type, String code, String redirec return new LoginResponse(accessCookie, refreshCookie, user.getUserStatus()); } + @Transactional + public LoginResponse requestkakaoAccessToken(String code, String redirectUrl, + CreateUserInfoRequest createUserInfoRequest) { + User user = checkAndSaveKakaoUser(code, redirectUrl, createUserInfoRequest); + user.updateLoginTime(); + final int ACCESS_COOKIE_AGE = (int) TimeUnit.MINUTES.toSeconds(30); + final int REFRESH_COOKIE_AGE = (int) TimeUnit.DAYS.toSeconds(30); + + String token = jwtTokenProvider.createAccessToken(user.getId()); + String refreshToken = jwtTokenProvider.createRefreshToken(user.getId()); + + tokenService.synchronizeRefreshToken(user, refreshToken); + + Cookie accessCookie = createCookie("access_token", token, ACCESS_COOKIE_AGE); + Cookie refreshCookie = createCookie("refresh_token", refreshToken, REFRESH_COOKIE_AGE); + + return new LoginResponse(accessCookie, refreshCookie, user.getUserStatus()); + } + private Cookie createCookie(String name, String value, int maxAge) { Cookie cookie = new Cookie(name, value); cookie.setSecure(true); @@ -92,6 +121,23 @@ private Cookie createCookie(String name, String value, int maxAge) { return cookie; } + private User checkAndSaveKakaoUser(String code, String redirectUrl, CreateUserInfoRequest createUserInfoRequest) { + KakaoTokenAndUserResponse response = kakaoConnector.requestKakaoUserInfo(code, redirectUrl); + KakaoTokenResponse tokenResponse = response.getKakaoTokenResponse(); + KakaoUserResponse kakaoUserResponse = response.getKakaoUserResponse(); + + String id = kakaoUserResponse.getId().toString(); + User user = userRepository.findByOauthId(id) + .orElseGet(() -> saveActiveKakaoUser(kakaoUserResponse, createUserInfoRequest)); + + checkUserStatus(user); + + Token token = tokenRepository.findByUserId(user.getId()) + .orElseGet(() -> tokenService.saveToken(tokenResponse.getRefreshToken(), user)); + + return user; + } + private User checkAndSaveUser(String type, String code, String redirectUrl) { if (Objects.equals(type, "kakao")) { KakaoTokenAndUserResponse response = kakaoConnector.requestKakaoUserInfo(code, redirectUrl); @@ -169,8 +215,29 @@ private String getGoogleUserImage(GoogleUserResponse response) { return USER_PROFILE_NONE; } + private User saveActiveKakaoUser(KakaoUserResponse kakaoUserResponse, CreateUserInfoRequest createUserInfoRequest) { + String imageUrl = getDefaultUserImage(createUserInfoRequest.getSex()); + UserImage savedUserImage = userImageService.saveUserImage(imageUrl); + + User user = User.builder() + .userStatus(UserStatus.ACTIVATE) + .oauthId(String.valueOf(kakaoUserResponse.getId())) + .provider("kakao") + .isAdmin(false) + .userImage(savedUserImage) + .name(createUserInfoRequest.getName()) + .sex(createUserInfoRequest.getSex()) + .nickname(RandomNickName.generateRandomNickname()) + .email(kakaoUserResponse.getKakaoAccount().getEmail()) + .name(createUserInfoRequest.getName()) + .age(Integer.valueOf(createUserInfoRequest.getAge())) + .createdAt(LocalDateTime.now()) + .build(); + return userRepository.save(user); + } + private User saveKakaoUser(KakaoUserResponse response) { - String imageUrl = getKakaoUserImage(response); + String imageUrl = getDefaultUserImage(response.getKakaoAccount().getGender()); UserImage savedUserImage = userImageService.saveUserImage(imageUrl); User user = User.builder() @@ -261,22 +328,25 @@ private void changeToDefaultProfile(User user, UserImage userImage) { } private String getDefaultProfile(User user) { - String sex = user.getSex(); - if (sex.equals("male")) { - { + if (user.getSex() != null) { + if (user.getSex().equals("male")) { return USER_PROFILE_MALE; + } else { + return USER_PROFILE_FEMALE; } - } else { - return USER_PROFILE_FEMALE; } + return USER_PROFILE_NONE; } - private void deleteUserProfileFromS3(UserImage userImage, String defaultImageUrl) { - String userImageUrl = userImage.getAddress(); - if (userImageUrl.equals(USER_PROFILE_MALE) || userImageUrl.equals(USER_PROFILE_FEMALE)) { - return; + private void deleteUserProfileFromS3 (UserImage userImage, String defaultImageUrl){ + String userImageUrl = userImage.getAddress(); + if (userImageUrl.equals(USER_PROFILE_MALE) || userImageUrl.equals(USER_PROFILE_FEMALE) + || userImageUrl.equals( + USER_PROFILE_NONE)) { + return; + } + s3Uploader.deleteImage(userImageUrl); + userImage.changeToDefaultProfile(defaultImageUrl); } - s3Uploader.deleteImage(userImageUrl); - userImage.changeToDefaultProfile(defaultImageUrl); + } -} diff --git a/src/main/java/solitour_backend/solitour/auth/service/TokenService.java b/src/main/java/solitour_backend/solitour/auth/service/TokenService.java index 99eebc6b..b4c2758e 100644 --- a/src/main/java/solitour_backend/solitour/auth/service/TokenService.java +++ b/src/main/java/solitour_backend/solitour/auth/service/TokenService.java @@ -30,10 +30,10 @@ public void deleteByMemberId(Long memberId) { } @Transactional - public Token saveToken(KakaoTokenResponse tokenResponse, User user) { + public Token saveToken(String refreshToken, User user) { Token token = Token.builder() .user(user) - .oauthToken(tokenResponse.getRefreshToken()) + .oauthToken(refreshToken) .build(); tokenRepository.save(token); diff --git a/src/main/java/solitour_backend/solitour/auth/support/kakao/dto/request/CreateUserInfoRequest.java b/src/main/java/solitour_backend/solitour/auth/support/kakao/dto/request/CreateUserInfoRequest.java new file mode 100644 index 00000000..ddba8c80 --- /dev/null +++ b/src/main/java/solitour_backend/solitour/auth/support/kakao/dto/request/CreateUserInfoRequest.java @@ -0,0 +1,12 @@ +package solitour_backend.solitour.auth.support.kakao.dto.request; + +import lombok.Getter; +import lombok.NoArgsConstructor; + +@NoArgsConstructor +@Getter +public class CreateUserInfoRequest { + private String name; + private String age; + private String sex; +} From 1a5dfb84eb093ec04e85d1e30f5e98d0caeb0f7f Mon Sep 17 00:00:00 2001 From: Donghun Won Date: Wed, 25 Sep 2024 18:27:23 +0900 Subject: [PATCH 354/371] =?UTF-8?q?Feat=20:=20=EB=84=A4=EC=9D=B4=EB=B2=84?= =?UTF-8?q?=20oauth=20(#211)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 회원가입, 로그인, 로그아웃, 회원탈퇴 --- .../auth/controller/OauthController.java | 19 +-- .../auth/exception/RevokeFailException.java | 7 ++ .../UnsupportedLoginTypeException.java | 7 ++ .../exception/UserRevokeErrorException.java | 7 ++ .../solitour/auth/service/OauthService.java | 78 +++++++++--- .../auth/support/naver/NaverConnector.java | 118 ++++++++++++++++++ .../auth/support/naver/NaverProvider.java | 79 ++++++++++++ .../naver/dto/NaverTokenAndUserResponse.java | 17 +++ .../support/naver/dto/NaverTokenResponse.java | 17 +++ .../support/naver/dto/NaverUserResponse.java | 36 ++++++ .../error/GlobalControllerAdvice.java | 13 +- 11 files changed, 369 insertions(+), 29 deletions(-) create mode 100644 src/main/java/solitour_backend/solitour/auth/exception/RevokeFailException.java create mode 100644 src/main/java/solitour_backend/solitour/auth/exception/UnsupportedLoginTypeException.java create mode 100644 src/main/java/solitour_backend/solitour/auth/exception/UserRevokeErrorException.java create mode 100644 src/main/java/solitour_backend/solitour/auth/support/naver/NaverConnector.java create mode 100644 src/main/java/solitour_backend/solitour/auth/support/naver/NaverProvider.java create mode 100644 src/main/java/solitour_backend/solitour/auth/support/naver/dto/NaverTokenAndUserResponse.java create mode 100644 src/main/java/solitour_backend/solitour/auth/support/naver/dto/NaverTokenResponse.java create mode 100644 src/main/java/solitour_backend/solitour/auth/support/naver/dto/NaverUserResponse.java diff --git a/src/main/java/solitour_backend/solitour/auth/controller/OauthController.java b/src/main/java/solitour_backend/solitour/auth/controller/OauthController.java index 931f75f3..8bec21b7 100644 --- a/src/main/java/solitour_backend/solitour/auth/controller/OauthController.java +++ b/src/main/java/solitour_backend/solitour/auth/controller/OauthController.java @@ -99,8 +99,8 @@ public ResponseEntity reissueAccessToken(HttpServletResponse response, @Authenticated @DeleteMapping() - public ResponseEntity deleteUser(HttpServletResponse response, @AuthenticationPrincipal Long id, - @RequestParam String type) { + public ResponseEntity deleteUser(HttpServletResponse response, @AuthenticationPrincipal Long id, + @RequestParam String type) { Token token = tokenRepository.findByUserId(id) .orElseThrow(() -> new TokenNotExistsException("토큰이 존재하지 않습니다")); String oauthRefreshToken = getOauthAccessToken(type, token.getOauthToken()); @@ -110,11 +110,11 @@ public ResponseEntity deleteUser(HttpServletResponse response, @Authenti oauthService.logout(response, id); oauthService.deleteUser(id); - - return ResponseEntity.ok("User deleted successfully"); } catch (Exception e) { - return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("An error occurred"); + throw new UserRevokeErrorException("회원 탈퇴 중 오류가 발생했습니다"); } + + return ResponseEntity.noContent().build(); } private String setCookieHeader(Cookie cookie) { @@ -128,10 +128,13 @@ private String getOauthAccessToken(String type, String refreshToken) { case "kakao" -> { token = kakaoConnector.refreshToken(refreshToken); } - case "google" -> { - token = googleConnector.refreshToken(refreshToken); + case "naver" -> { + token = naverConnector.refreshToken(refreshToken); } - default -> throw new RuntimeException("Unsupported oauth type"); +// case "google" -> { +// token = googleConnector.refreshToken(refreshToken); +// } + default -> throw new UnsupportedLoginTypeException("지원하지 않는 로그인 타입입니다"); } return token; } diff --git a/src/main/java/solitour_backend/solitour/auth/exception/RevokeFailException.java b/src/main/java/solitour_backend/solitour/auth/exception/RevokeFailException.java new file mode 100644 index 00000000..6bd23ece --- /dev/null +++ b/src/main/java/solitour_backend/solitour/auth/exception/RevokeFailException.java @@ -0,0 +1,7 @@ +package solitour_backend.solitour.auth.exception; + +public class RevokeFailException extends RuntimeException { + public RevokeFailException(String message) { + super(message); + } +} diff --git a/src/main/java/solitour_backend/solitour/auth/exception/UnsupportedLoginTypeException.java b/src/main/java/solitour_backend/solitour/auth/exception/UnsupportedLoginTypeException.java new file mode 100644 index 00000000..4b10d359 --- /dev/null +++ b/src/main/java/solitour_backend/solitour/auth/exception/UnsupportedLoginTypeException.java @@ -0,0 +1,7 @@ +package solitour_backend.solitour.auth.exception; + +public class UnsupportedLoginTypeException extends RuntimeException { + public UnsupportedLoginTypeException(String message) { + super(message); + } +} diff --git a/src/main/java/solitour_backend/solitour/auth/exception/UserRevokeErrorException.java b/src/main/java/solitour_backend/solitour/auth/exception/UserRevokeErrorException.java new file mode 100644 index 00000000..d69a887f --- /dev/null +++ b/src/main/java/solitour_backend/solitour/auth/exception/UserRevokeErrorException.java @@ -0,0 +1,7 @@ +package solitour_backend.solitour.auth.exception; + +public class UserRevokeErrorException extends RuntimeException { + public UserRevokeErrorException(String message) { + super(message); + } +} diff --git a/src/main/java/solitour_backend/solitour/auth/service/OauthService.java b/src/main/java/solitour_backend/solitour/auth/service/OauthService.java index f7d90dac..f507a2aa 100644 --- a/src/main/java/solitour_backend/solitour/auth/service/OauthService.java +++ b/src/main/java/solitour_backend/solitour/auth/service/OauthService.java @@ -151,7 +151,23 @@ private User checkAndSaveUser(String type, String code, String redirectUrl) { checkUserStatus(user); Token token = tokenRepository.findByUserId(user.getId()) - .orElseGet(() -> tokenService.saveToken(tokenResponse, user)); + .orElseGet(() -> tokenService.saveToken(tokenResponse.getRefreshToken(), user)); + + return user; + } + if (Objects.equals(type, "naver")) { + NaverTokenAndUserResponse response = naverConnector.requestNaverUserInfo(code); + NaverTokenResponse tokenResponse = response.getNaverTokenResponse(); + NaverUserResponse naverUserResponse = response.getNaverUserResponse(); + + String id = naverUserResponse.getResponse().getId().toString(); + User user = userRepository.findByOauthId(id) + .orElseGet(() -> saveNaverUser(naverUserResponse)); + + checkUserStatus(user); + + Token token = tokenRepository.findByUserId(user.getId()) + .orElseGet(() -> tokenService.saveToken(tokenResponse.getRefreshToken(), user)); return user; } @@ -162,7 +178,38 @@ private User checkAndSaveUser(String type, String code, String redirectUrl) { return userRepository.findByOauthId(id) .orElseGet(() -> saveGoogleUser(response)); } else { - throw new RuntimeException("지원하지 않는 oauth 타입입니다."); + throw new UnsupportedLoginTypeException("지원하지 않는 oauth 로그인입니다."); + } + } + + private User saveNaverUser(NaverUserResponse naverUserResponse) { + String convertedSex = convertSex(naverUserResponse.getResponse().getGender()); + String imageUrl = getDefaultUserImage(convertedSex); + UserImage savedUserImage = userImageService.saveUserImage(imageUrl); + + User user = User.builder() + .userStatus(UserStatus.ACTIVATE) + .oauthId(String.valueOf(naverUserResponse.getResponse().getId())) + .provider("naver") + .isAdmin(false) + .userImage(savedUserImage) + .nickname(RandomNickName.generateRandomNickname()) + .email(naverUserResponse.getResponse().getEmail()) + .name(naverUserResponse.getResponse().getName()) + .age(Integer.parseInt(naverUserResponse.getResponse().getBirthyear())) + .sex(convertedSex) + .createdAt(LocalDateTime.now()) + .build(); + return userRepository.save(user); + } + + private String convertSex(String gender) { + if (gender.equals("M")) { + return "male"; + } else if (gender.equals("F")) { + return "female"; + } else { + return "none"; } } @@ -175,15 +222,6 @@ private void checkUserStatus(User user) { } } - private void saveToken(KakaoTokenResponse tokenResponse, User user) { - Token token = Token.builder() - .user(user) - .oauthToken(tokenResponse.getRefreshToken()) - .build(); - - tokenRepository.save(token); - } - private User saveGoogleUser(GoogleUserResponse response) { String imageUrl = getGoogleUserImage(response); UserImage savedUserImage = userImageService.saveUserImage(imageUrl); @@ -253,8 +291,8 @@ private User saveKakaoUser(KakaoUserResponse response) { return userRepository.save(user); } - private String getKakaoUserImage(KakaoUserResponse response) { - String gender = response.getKakaoAccount().getGender(); + + private String getDefaultUserImage(String gender) { if (Objects.equals(gender, "male")) { return USER_PROFILE_MALE; } @@ -268,7 +306,8 @@ private String getAuthLink(String type, String redirectUrl) { return switch (type) { case "kakao" -> kakaoProvider.generateAuthUrl(redirectUrl); case "google" -> googleProvider.generateAuthUrl(redirectUrl); - default -> throw new RuntimeException("지원하지 않는 oauth 타입입니다."); + case "naver" -> naverProvider.generateAuthUrl(redirectUrl); + default -> throw new UnsupportedLoginTypeException("지원하지 않는 oauth 로그인입니다."); }; } @@ -298,19 +337,18 @@ private void deleteCookie(String name, String value, HttpServletResponse respons response.addCookie(cookie); } + public void revokeToken(String type, String token) throws IOException { HttpStatusCode responseCode; switch (type) { case "kakao" -> responseCode = kakaoConnector.requestRevoke(token); case "google" -> responseCode = googleConnector.requestRevoke(token); - default -> throw new RuntimeException("Unsupported oauth type"); + case "naver" -> responseCode = naverConnector.requestRevoke(token); + default -> throw new UnsupportedLoginTypeException("지원하지 않는 oauth 로그인입니다."); } - if (responseCode.is2xxSuccessful()) { - System.out.println("Token successfully revoked"); - } else { - System.out.println("Failed to revoke token, response code: " + responseCode); - throw new RuntimeException("Failed to revoke token"); + if (!responseCode.is2xxSuccessful()) { + throw new RevokeFailException("회원탈퇴에 실패하였습니다."); } } diff --git a/src/main/java/solitour_backend/solitour/auth/support/naver/NaverConnector.java b/src/main/java/solitour_backend/solitour/auth/support/naver/NaverConnector.java new file mode 100644 index 00000000..5d47e7bf --- /dev/null +++ b/src/main/java/solitour_backend/solitour/auth/support/naver/NaverConnector.java @@ -0,0 +1,118 @@ +package solitour_backend.solitour.auth.support.naver; + + +import java.io.IOException; +import java.util.Collections; +import java.util.UUID; +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; +import org.springframework.http.HttpStatusCode; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Component; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; +import org.springframework.web.client.RestTemplate; +import solitour_backend.solitour.auth.support.kakao.dto.KakaoUserResponse; +import solitour_backend.solitour.auth.support.naver.dto.NaverTokenAndUserResponse; +import solitour_backend.solitour.auth.support.naver.dto.NaverTokenResponse; +import solitour_backend.solitour.auth.support.naver.dto.NaverUserResponse; + +@Getter +@RequiredArgsConstructor +@Component +public class NaverConnector { + + private static final String BEARER_TYPE = "Bearer"; + private static final RestTemplate REST_TEMPLATE = new RestTemplate(); + + private final NaverProvider provider; + + public NaverTokenAndUserResponse requestNaverUserInfo(String code) { + NaverTokenResponse naverTokenResponse = requestAccessToken(code); + + HttpHeaders headers = new HttpHeaders(); + headers.set("Authorization", String.join(" ", BEARER_TYPE, naverTokenResponse.getAccessToken())); + HttpEntity entity = new HttpEntity<>(headers); + + ResponseEntity responseEntity = REST_TEMPLATE.exchange(provider.getUserInfoUrl(), + HttpMethod.GET, entity, + NaverUserResponse.class); + + return new NaverTokenAndUserResponse(naverTokenResponse, responseEntity.getBody()); + + } + + public NaverTokenResponse requestAccessToken(String code) { + HttpEntity> entity = new HttpEntity<>( + createBody(code), createHeaders()); + + return REST_TEMPLATE.postForEntity( + provider.getAccessTokenUrl(), + entity, + NaverTokenResponse.class).getBody(); + } + + public String refreshToken(String refreshToken) { + HttpEntity> entity = new HttpEntity<>( + createRefreshBody(refreshToken), createHeaders()); + + return REST_TEMPLATE.postForEntity( + provider.getAccessTokenUrl(), + entity, NaverTokenResponse.class).getBody().getAccessToken(); + } + + private HttpHeaders createHeaders() { + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED); + headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON)); + return headers; + } + + private MultiValueMap createBody(String code) { + MultiValueMap body = new LinkedMultiValueMap<>(); + body.add("code", code); + body.add("grant_type", provider.getGrantType()); + body.add("client_id", provider.getClientId()); + body.add("client_secret", provider.getClientSecret()); + body.add("state", UUID.randomUUID().toString()); + return body; + } + + private MultiValueMap createRefreshBody(String refreshToken) { + MultiValueMap body = new LinkedMultiValueMap<>(); + body.add("grant_type", provider.getRefreshGrantType()); + body.add("client_id", provider.getClientId()); + body.add("client_secret", provider.getClientSecret()); + body.add("refresh_token", refreshToken); + return body; + } + + public HttpStatusCode requestRevoke(String token) throws IOException { + HttpEntity> entity = new HttpEntity<>(createRevokeBody(token),createRevokeHeaders(token)); + + ResponseEntity response = REST_TEMPLATE.postForEntity(provider.getAccessTokenUrl(), entity, String.class); + + return response.getStatusCode(); + } + + private MultiValueMap createRevokeBody(String accessToken) { + MultiValueMap body = new LinkedMultiValueMap<>(); + body.add("client_id", provider.getClientId()); + body.add("client_secret", provider.getClientSecret()); + body.add("grant_type", provider.getRevokeGrantType()); + body.add("access_token", accessToken); + body.add("service_provider", provider.getServiceProvider()); + return body; + } + + private HttpHeaders createRevokeHeaders(String token) { + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED); + headers.set("Authorization", String.join(" ", BEARER_TYPE, token)); + return headers; + } +} diff --git a/src/main/java/solitour_backend/solitour/auth/support/naver/NaverProvider.java b/src/main/java/solitour_backend/solitour/auth/support/naver/NaverProvider.java new file mode 100644 index 00000000..3b2e3f80 --- /dev/null +++ b/src/main/java/solitour_backend/solitour/auth/support/naver/NaverProvider.java @@ -0,0 +1,79 @@ +package solitour_backend.solitour.auth.support.naver; + +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; +import java.util.stream.Collectors; +import lombok.Getter; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.http.HttpEntity; +import org.springframework.stereotype.Component; +import org.springframework.util.MultiValueMap; +import solitour_backend.solitour.auth.support.naver.dto.NaverTokenResponse; + +@Getter +@Component +public class NaverProvider { + + private final String clientId; + private final String clientSecret; + private final String authUrl; + private final String accessTokenUrl; + private final String userInfoUrl; + private final String grantType; + private final String refreshGrantType; + private final String revokeGrantType; + private final String serviceProvider; + private final String state = UUID.randomUUID().toString(); + + + public NaverProvider(@Value("${oauth2.naver.client.id}") String clientId, + @Value("${oauth2.naver.client.secret}") String clientSecret, + @Value("${oauth2.naver.url.auth}") String authUrl, + @Value("${oauth2.naver.url.token}") String accessTokenUrl, + @Value("${oauth2.naver.url.userinfo}") String userInfoUrl, + @Value("${oauth2.naver.service-provider}") String serviceProvider, + @Value("${oauth2.naver.grant-type}") String grantType, + @Value("${oauth2.naver.refresh-grant-type}") String refreshGrantType, + @Value("${oauth2.naver.revoke-grant-type}") String revokeGrantType) { + this.clientId = clientId; + this.clientSecret = clientSecret; + this.authUrl = authUrl; + this.accessTokenUrl = accessTokenUrl; + this.userInfoUrl = userInfoUrl; + this.serviceProvider = serviceProvider; + this.grantType = grantType; + this.refreshGrantType = refreshGrantType; + this.revokeGrantType = revokeGrantType; + } + + public String generateTokenUrl(String grantType, String code) { + Map params = new HashMap<>(); + params.put("grant_type", grantType); + params.put("client_id", clientId); + params.put("client_secret", clientSecret); + params.put("code", code); + params.put("state", state); + return authUrl + "?" + concatParams(params); + } + + public String generateAuthUrl(String redirectUrl) { + Map params = new HashMap<>(); + params.put("response_type", "code"); + params.put("client_id", clientId); + params.put("redirect_uri", redirectUrl); + params.put("state", state); + return authUrl + "?" + concatParams(params); + } + + private String concatParams(Map params) { + return params.entrySet() + .stream() + .map(entry -> entry.getKey() + "=" + entry.getValue()) + .collect(Collectors.joining("&")); + } + + public String generateAccessTokenUrl(String code) { + return generateTokenUrl("authorization_code", code); + } +} diff --git a/src/main/java/solitour_backend/solitour/auth/support/naver/dto/NaverTokenAndUserResponse.java b/src/main/java/solitour_backend/solitour/auth/support/naver/dto/NaverTokenAndUserResponse.java new file mode 100644 index 00000000..fcdee937 --- /dev/null +++ b/src/main/java/solitour_backend/solitour/auth/support/naver/dto/NaverTokenAndUserResponse.java @@ -0,0 +1,17 @@ +package solitour_backend.solitour.auth.support.naver.dto; + +import com.fasterxml.jackson.databind.PropertyNamingStrategies; +import com.fasterxml.jackson.databind.annotation.JsonNaming; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class) +@Getter +@NoArgsConstructor +@AllArgsConstructor +public class NaverTokenAndUserResponse { + + private NaverTokenResponse naverTokenResponse; + private NaverUserResponse naverUserResponse; +} diff --git a/src/main/java/solitour_backend/solitour/auth/support/naver/dto/NaverTokenResponse.java b/src/main/java/solitour_backend/solitour/auth/support/naver/dto/NaverTokenResponse.java new file mode 100644 index 00000000..ccb38fb5 --- /dev/null +++ b/src/main/java/solitour_backend/solitour/auth/support/naver/dto/NaverTokenResponse.java @@ -0,0 +1,17 @@ +package solitour_backend.solitour.auth.support.naver.dto; + +import com.fasterxml.jackson.databind.PropertyNamingStrategies; +import com.fasterxml.jackson.databind.annotation.JsonNaming; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class) +@Getter +@NoArgsConstructor +@AllArgsConstructor +public class NaverTokenResponse { + + private String accessToken; + private String refreshToken; +} diff --git a/src/main/java/solitour_backend/solitour/auth/support/naver/dto/NaverUserResponse.java b/src/main/java/solitour_backend/solitour/auth/support/naver/dto/NaverUserResponse.java new file mode 100644 index 00000000..6b4329d3 --- /dev/null +++ b/src/main/java/solitour_backend/solitour/auth/support/naver/dto/NaverUserResponse.java @@ -0,0 +1,36 @@ +package solitour_backend.solitour.auth.support.naver.dto; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import java.util.Date; +import java.util.HashMap; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import lombok.ToString; +import solitour_backend.solitour.auth.support.kakao.dto.KakaoUserResponse.Partner; + +@Getter +@NoArgsConstructor +@JsonIgnoreProperties(ignoreUnknown = true) +public class NaverUserResponse { + private String resultcode; + private String message; + private Response response; + + @Getter + @NoArgsConstructor + public static class Response { + private String id; + private String email; + private String name; + private String nickname; + private String gender; + private String age; + private String birthday; + private String birthyear; + private String mobile; + private String profileImage; + } + +} diff --git a/src/main/java/solitour_backend/solitour/error/GlobalControllerAdvice.java b/src/main/java/solitour_backend/solitour/error/GlobalControllerAdvice.java index d9f9bdf9..a877ef34 100644 --- a/src/main/java/solitour_backend/solitour/error/GlobalControllerAdvice.java +++ b/src/main/java/solitour_backend/solitour/error/GlobalControllerAdvice.java @@ -5,6 +5,8 @@ import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.RestControllerAdvice; import solitour_backend.solitour.auth.exception.TokenNotExistsException; +import solitour_backend.solitour.auth.exception.UnsupportedLoginTypeException; +import solitour_backend.solitour.auth.exception.UserRevokeErrorException; import solitour_backend.solitour.book_mark_gathering.exception.GatheringBookMarkNotExistsException; import solitour_backend.solitour.book_mark_information.exception.InformationBookMarkNotExistsException; import solitour_backend.solitour.category.exception.CategoryNotExistsException; @@ -40,7 +42,8 @@ public class GlobalControllerAdvice { RequestValidationFailedException.class, ImageRequestValidationFailedException.class, GatheringApplicantsManagerException.class, - InformationNotManageException.class + InformationNotManageException.class, + UnsupportedLoginTypeException.class }) public ResponseEntity validationException(Exception exception) { return ResponseEntity @@ -111,5 +114,13 @@ public ResponseEntity unauthorizedException(Exception exception) { .status(HttpStatus.UNAUTHORIZED) .body(exception.getMessage()); } + @ExceptionHandler({ + UserRevokeErrorException.class + }) + public ResponseEntity serverErrorException(Exception exception) { + return ResponseEntity + .status(HttpStatus.INTERNAL_SERVER_ERROR) + .body(exception.getMessage()); + } } From a2df118fd88214b9e0d5f1af222ecead8c535f8b Mon Sep 17 00:00:00 2001 From: Donghun Won Date: Mon, 30 Sep 2024 14:12:13 +0900 Subject: [PATCH 355/371] =?UTF-8?q?Refactor=20:=20=ED=85=8C=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20ci=20,=20=EB=B0=B0=ED=8F=AC=20ci=20=EB=B6=84?= =?UTF-8?q?=EB=A6=AC=20(#212)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Refactor : 테스트 ci , 배포 ci 분리 * Fix : 빌드 캐시 비활성화 * Fix : 로그 출력 추가 * Feat : gradle package, wrapper 캐시 추가 * Fix : 개발서버 포트 변경 --- .github/workflows/deploy.yml | 15 ++++------- .github/workflows/test.yml | 48 ++++++++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+), 10 deletions(-) create mode 100644 .github/workflows/test.yml diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 05e2e3bf..d68a02ee 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -3,8 +3,6 @@ name: Docker Image CI on: push: branches: [ "main", "develop" ] - pull_request: - branches: [ "main", "develop" ] jobs: build: @@ -27,21 +25,18 @@ jobs: echo "${{ secrets.APPLICATION_DEV }}" > ./src/main/resources/application-dev.yml echo "${{ secrets.APPLICATION_PROD }}" > ./src/main/resources/application-prod.yml echo "${{ secrets.APPLICATION_LOCAL }}" > ./src/main/resources/application-local.yml - echo "${{ secrets.APPLICATION_TEST }}" > ./src/main/resources/application-test.yml - - name: gradlew 실행 권한 부여 run: chmod +x ./gradlew - - name: 테스트 및 빌드하기 (main 브랜치) + - name: 빌드하기 (main 브랜치) if: github.ref == 'refs/heads/main' - run: ./gradlew clean build -PspringProfile=prod --warning-mode all --scan + run: ./gradlew clean build -x test -PspringProfile=prod --warning-mode all --scan - - name: 테스트 및 빌드하기 (develop 브랜치) + - name: 빌드하기 (develop 브랜치) if: github.ref == 'refs/heads/develop' run: | - ./gradlew clean test -PspringProfile=test - ./gradlew build -x test -PspringProfile=dev --warning-mode all --scan + ./gradlew clean build -x test -PspringProfile=dev --warning-mode all --scan - name: 빌드된 파일 이름 변경 run: mv ./build/libs/*SNAPSHOT.jar ./project.jar @@ -85,6 +80,6 @@ jobs: mkdir /home/ubuntu/solitour-server/current mv /home/ubuntu/solitour-server/tobe/project.jar /home/ubuntu/solitour-server/current/project.jar cd /home/ubuntu/solitour-server/current - sudo fuser -k -n tcp 8080 || true + sudo fuser -k -n tcp 8081 || true nohup java -jar -Dspring.profiles.active=dev project.jar > ./output.log 2>&1 & rm -rf /home/ubuntu/solitour-server/tobe diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 00000000..c2fd26f4 --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,48 @@ +name: Docker Image CI + +on: + pull_request: + branches: [ "main", "develop" ] + +jobs: + build: + runs-on: ubuntu-latest + steps: + - name: Github Repository 에 올린 파일들을 볼러오기 + uses: actions/checkout@v4 + + - name: JDK 17 버전 설치 + uses: actions/setup-java@v4 + with: + distribution: temurin + java-version: 17 + + - name: application.yml 파일 만들기 + run: | + mkdir -p ./src/main/resources + echo "${{ secrets.APPLICATION_YML }}" > ./src/main/resources/application.yml + echo "${{ secrets.APPLICATION_COMMON }}" > ./src/main/resources/application-common.yml + echo "${{ secrets.APPLICATION_TEST }}" > ./src/main/resources/application-test.yml + + + - name: gradlew 실행 권한 부여 + run: chmod +x ./gradlew + + - name: Gradle packages 캐시 + uses: actions/cache@v3 + with: + path: ~/.gradle/caches + key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }} + restore-keys: | + ${{ runner.os }}-gradle + + - name: Gradle wrapper 캐시 + uses: actions/cache@v3 + with: + path: ~/.gradle/wrapper + key: ${{ runner.os }}-gradle-wrapper-${{ hashFiles('**/gradle/wrapper/gradle-wrapper.properties') }} + + - name: 테스트 + run : ./gradlew clean test -PspringProfile=test --info + + From 8492579d79ec30da233eeb317a6c114a284aabb3 Mon Sep 17 00:00:00 2001 From: Donghun Won Date: Tue, 1 Oct 2024 17:28:50 +0900 Subject: [PATCH 356/371] =?UTF-8?q?Fix=20:=20ci=20=EC=9D=B4=EB=A6=84=20?= =?UTF-8?q?=EC=88=98=EC=A0=95=20(#214)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Refactor : 테스트 ci , 배포 ci 분리 * Fix : 빌드 캐시 비활성화 * Fix : 로그 출력 추가 * Feat : gradle package, wrapper 캐시 추가 * Fix : 개발서버 포트 변경 * Fix : ci 이름 수정 --- .github/workflows/deploy.yml | 2 +- .github/workflows/test.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index d68a02ee..042bcc70 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -1,4 +1,4 @@ -name: Docker Image CI +name: deploy on: push: diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index c2fd26f4..e466f8f9 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -1,4 +1,4 @@ -name: Docker Image CI +name: test on: pull_request: From fa43c9a4525f24e10dbcecc9d11bcdb190c60841 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Wed, 2 Oct 2024 17:30:37 +0900 Subject: [PATCH 357/371] =?UTF-8?q?docs:=20restdocs=20=EA=B4=80=EB=A0=A8?= =?UTF-8?q?=20=EC=84=A4=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 31 +++++++++++++++++++++++++++---- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/build.gradle b/build.gradle index af903924..3b8a8dce 100644 --- a/build.gradle +++ b/build.gradle @@ -18,6 +18,7 @@ configurations { compileOnly { extendsFrom annotationProcessor } + asciidoctorExt } repositories { @@ -54,7 +55,7 @@ dependencies { annotationProcessor "jakarta.persistence:jakarta.persistence-api" runtimeOnly 'com.mysql:mysql-connector-j' - + asciidoctorExt 'org.springframework.restdocs:spring-restdocs-asciidoctor' testImplementation 'com.h2database:h2' testImplementation 'org.springframework.boot:spring-boot-starter-test' testImplementation 'org.springframework.restdocs:spring-restdocs-mockmvc' @@ -71,6 +72,28 @@ tasks.named('asciidoctor') { dependsOn test } -//clean { -// delete file('src/main/generated') -//} \ No newline at end of file +ext { + snippetsDir = file('build/generated-snippets') // (5) +} + +asciidoctor { + configurations 'asciidoctorExt' // (7) + baseDirFollowsSourceFile() // (8) + inputs.dir snippetsDir // (9) + dependsOn test // (10) +} + +asciidoctor.doFirst { + delete file('src/main/resources/docs') // (11) +} + +task copyDocument(type: Copy) { // (12) + dependsOn asciidoctor + from file("build/docs/asciidoc") + into file("src/main/resources/docs") +} + + +build { + dependsOn copyDocument +} \ No newline at end of file From bc9a206f6fd9580af6b143b9f205fde5144d0299 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Wed, 2 Oct 2024 17:31:07 +0900 Subject: [PATCH 358/371] =?UTF-8?q?docs:=20restdocs=20=EA=B4=80=EB=A0=A8?= =?UTF-8?q?=20=EC=84=A4=EC=A0=95(=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=BD=94?= =?UTF-8?q?=EB=93=9C=20=EC=9E=91=EC=84=B1=20=EC=8B=9C=20=EC=98=88=EC=8B=9C?= =?UTF-8?q?)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/InformationControllerTest.java | 42 +++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 src/test/java/solitour_backend/solitour/information/controller/InformationControllerTest.java diff --git a/src/test/java/solitour_backend/solitour/information/controller/InformationControllerTest.java b/src/test/java/solitour_backend/solitour/information/controller/InformationControllerTest.java new file mode 100644 index 00000000..f85f4be7 --- /dev/null +++ b/src/test/java/solitour_backend/solitour/information/controller/InformationControllerTest.java @@ -0,0 +1,42 @@ +package solitour_backend.solitour.information.controller; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.junit.jupiter.MockitoExtension; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.restdocs.RestDocumentationContextProvider; +import org.springframework.restdocs.RestDocumentationExtension; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.setup.MockMvcBuilders; +import org.springframework.web.context.WebApplicationContext; +import solitour_backend.solitour.information.service.InformationService; + +import static org.junit.jupiter.api.Assertions.*; +import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.documentationConfiguration; +import static org.springframework.restdocs.operation.preprocess.Preprocessors.modifyUris; +import static org.springframework.restdocs.operation.preprocess.Preprocessors.prettyPrint; + +@WebMvcTest(InformationController.class) +@ExtendWith({MockitoExtension.class, RestDocumentationExtension.class}) +class InformationControllerTest { + + @Autowired + private MockMvc mockMvc; + + @MockBean + private InformationService informationService; + + @BeforeEach + void setUp(WebApplicationContext webApplicationContext, + RestDocumentationContextProvider restDocumentation) { + + this.mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext) + .apply(documentationConfiguration(restDocumentation) + .operationPreprocessors() + .withRequestDefaults(modifyUris(), prettyPrint()) + .withResponseDefaults(prettyPrint())) + .build(); + } +} \ No newline at end of file From 46ade5d4f7ab2db1409e1663a8b0c33576bdb1b3 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Wed, 2 Oct 2024 17:31:29 +0900 Subject: [PATCH 359/371] =?UTF-8?q?style:=20import=20=EB=AC=B8=20=EC=A0=9C?= =?UTF-8?q?=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../solitour/information/controller/InformationController.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/solitour_backend/solitour/information/controller/InformationController.java b/src/main/java/solitour_backend/solitour/information/controller/InformationController.java index fda63684..29536168 100644 --- a/src/main/java/solitour_backend/solitour/information/controller/InformationController.java +++ b/src/main/java/solitour_backend/solitour/information/controller/InformationController.java @@ -20,7 +20,6 @@ import solitour_backend.solitour.auth.config.Authenticated; import solitour_backend.solitour.auth.config.AuthenticationPrincipal; import solitour_backend.solitour.auth.exception.TokenNotExistsException; -import solitour_backend.solitour.auth.exception.TokenNotValidException; import solitour_backend.solitour.auth.support.CookieExtractor; import solitour_backend.solitour.auth.support.JwtTokenProvider; import solitour_backend.solitour.error.Utils; From 55881e01984e6a48e1770b583a3fb122fc830c16 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Wed, 2 Oct 2024 17:31:48 +0900 Subject: [PATCH 360/371] =?UTF-8?q?docs:=20rest=20docs=20=EA=B4=80?= =?UTF-8?q?=EB=A0=A8=20=EC=84=A4=EC=A0=95=20=ED=8C=8C=EC=9D=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/docs/asciidoc/index.adoc | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 src/docs/asciidoc/index.adoc diff --git a/src/docs/asciidoc/index.adoc b/src/docs/asciidoc/index.adoc new file mode 100644 index 00000000..e8aebec1 --- /dev/null +++ b/src/docs/asciidoc/index.adoc @@ -0,0 +1,11 @@ += Solitour -Resource + +:doctype: book +:toc: left +:toclevels: 3 +:sectnums: +:numbered: + + +// [[api]] +// includ::ee.adoc[] \ No newline at end of file From 66a7d3d04e0403fd239d6a02bdee3d67456bb77f Mon Sep 17 00:00:00 2001 From: Donghun Won Date: Wed, 2 Oct 2024 18:19:04 +0900 Subject: [PATCH 361/371] =?UTF-8?q?Fix=20:=20=EC=9C=A0=EC=A0=80,=20?= =?UTF-8?q?=EC=9D=BC=EA=B8=B0=20=EC=9D=B4=EB=AF=B8=EC=A7=80=20=EC=9E=90?= =?UTF-8?q?=EB=8F=99=EC=82=AD=EC=A0=9C=20=EB=90=98=EC=A7=80=20=EC=95=8A?= =?UTF-8?q?=EA=B2=8C=20=EC=88=98=EC=A0=95=20(#217)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../solitour_backend/solitour/diary/service/DiaryService.java | 1 + .../solitour/user_image/service/UserImageService.java | 1 + 2 files changed, 2 insertions(+) diff --git a/src/main/java/solitour_backend/solitour/diary/service/DiaryService.java b/src/main/java/solitour_backend/solitour/diary/service/DiaryService.java index eb71af52..78c9775e 100644 --- a/src/main/java/solitour_backend/solitour/diary/service/DiaryService.java +++ b/src/main/java/solitour_backend/solitour/diary/service/DiaryService.java @@ -103,6 +103,7 @@ private void updateDiary(Long diaryId, DiaryUpdateRequest request) { private void saveDiaryDayContent(Diary savedDiary, DiaryCreateRequest request) { for (DiaryDayRequest dayRequest : request.getDiaryDayRequests()) { + s3Uploader.markImagePermanent(dayRequest.getDiaryDayContentImages()); DiaryDayContent diaryDayContent = DiaryDayContent.builder() .diary(savedDiary) .content(dayRequest.getContent()) diff --git a/src/main/java/solitour_backend/solitour/user_image/service/UserImageService.java b/src/main/java/solitour_backend/solitour/user_image/service/UserImageService.java index 6f509925..4881516b 100644 --- a/src/main/java/solitour_backend/solitour/user_image/service/UserImageService.java +++ b/src/main/java/solitour_backend/solitour/user_image/service/UserImageService.java @@ -32,6 +32,7 @@ public UserImage saveUserImage(String imageUrl) { public UserImageResponse updateUserProfile(Long userId, MultipartFile userImage) { String userImageUrl = s3Uploader.upload(userImage, IMAGE_PATH, userId); + s3Uploader.markImagePermanent(userImageUrl); return new UserImageResponse(userImageUrl); } From 015bfc51c6777a1938b2d547137f924ad88dc831 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Thu, 3 Oct 2024 16:30:07 +0900 Subject: [PATCH 362/371] =?UTF-8?q?docs:=20=EA=B2=BD=EB=A1=9C=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 --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 9bf4c60f..34494573 100644 --- a/.gitignore +++ b/.gitignore @@ -181,4 +181,4 @@ Temporary Items # 설정 파일 /src/main/resources/**.yml -/src/main/resources +/src/main/resources/**.properties \ No newline at end of file From 8e41611daeade0b26accc64e557275a87e0fa620 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Thu, 3 Oct 2024 16:30:55 +0900 Subject: [PATCH 363/371] =?UTF-8?q?docs:=20restdocs=20=EA=B2=B0=EA=B3=BC?= =?UTF-8?q?=20=ED=8C=8C=EC=9D=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/resources/docs/index.html | 456 +++++++++++++++++++++++++++++ 1 file changed, 456 insertions(+) create mode 100644 src/main/resources/docs/index.html diff --git a/src/main/resources/docs/index.html b/src/main/resources/docs/index.html new file mode 100644 index 00000000..b6b1bc27 --- /dev/null +++ b/src/main/resources/docs/index.html @@ -0,0 +1,456 @@ + + + + + + + +Solitour -Resource + + + + +

+
+ +
+ + + \ No newline at end of file From 1cc6c8d94e73274738b2b92ce86d11ce4f6393c0 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Thu, 3 Oct 2024 16:31:13 +0900 Subject: [PATCH 364/371] =?UTF-8?q?docs:=20rest=20docs=20=EC=B4=88?= =?UTF-8?q?=EA=B8=B0=20=EC=84=A4=EC=A0=95=20-=20=ED=8C=8C=EC=9D=BC=20?= =?UTF-8?q?=EA=B2=BD=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/build.gradle b/build.gradle index 3b8a8dce..7ba6d4dd 100644 --- a/build.gradle +++ b/build.gradle @@ -73,21 +73,21 @@ tasks.named('asciidoctor') { } ext { - snippetsDir = file('build/generated-snippets') // (5) + set('snippetsDir', file("src/docs")) } asciidoctor { - configurations 'asciidoctorExt' // (7) - baseDirFollowsSourceFile() // (8) - inputs.dir snippetsDir // (9) - dependsOn test // (10) + configurations 'asciidoctorExt' + baseDirFollowsSourceFile() + inputs.dir snippetsDir + dependsOn test } asciidoctor.doFirst { - delete file('src/main/resources/docs') // (11) + delete file('src/main/resources/docs') } -task copyDocument(type: Copy) { // (12) +task copyDocument(type: Copy) { dependsOn asciidoctor from file("build/docs/asciidoc") into file("src/main/resources/docs") From 91d2bc148f30ed2cad6ea034740e0518f7c1828c Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Thu, 3 Oct 2024 17:47:30 +0900 Subject: [PATCH 365/371] =?UTF-8?q?fix:=20=EC=A4=91=EB=B3=B5=20=EC=BD=94?= =?UTF-8?q?=EB=93=9C=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/build.gradle b/build.gradle index 7ba6d4dd..bbde3850 100644 --- a/build.gradle +++ b/build.gradle @@ -26,7 +26,7 @@ repositories { } ext { - set('snippetsDir', file("build/generated-snippets")) + set('snippetsDir', file("src/dos")) // 변경된 경로 } dependencies { @@ -35,7 +35,6 @@ dependencies { implementation 'org.springframework.boot:spring-boot-starter-data-jpa' implementation 'org.springframework.boot:spring-boot-starter-validation' - implementation 'io.jsonwebtoken:jjwt-api:0.12.6' runtimeOnly 'io.jsonwebtoken:jjwt-impl:0.12.6' runtimeOnly 'io.jsonwebtoken:jjwt-jackson:0.12.6' @@ -49,7 +48,6 @@ dependencies { annotationProcessor 'org.mapstruct:mapstruct-processor:1.5.5.Final' implementation 'com.querydsl:querydsl-jpa:5.0.0:jakarta' -// queryDsl 라이브러리 annotationProcessor "com.querydsl:querydsl-apt:5.0.0:jakarta" annotationProcessor "jakarta.annotation:jakarta.annotation-api" annotationProcessor "jakarta.persistence:jakarta.persistence-api" @@ -69,18 +67,13 @@ tasks.named('test') { tasks.named('asciidoctor') { inputs.dir snippetsDir - dependsOn test -} - -ext { - set('snippetsDir', file("src/docs")) + // dependsOn test 를 제거하여 순환 종속성을 피합니다. } asciidoctor { configurations 'asciidoctorExt' baseDirFollowsSourceFile() inputs.dir snippetsDir - dependsOn test } asciidoctor.doFirst { @@ -88,12 +81,11 @@ asciidoctor.doFirst { } task copyDocument(type: Copy) { - dependsOn asciidoctor from file("build/docs/asciidoc") into file("src/main/resources/docs") } - +// build 작업에 copyDocument를 추가합니다. build { dependsOn copyDocument } \ No newline at end of file From f95a4bcbce64d635c5954ced12e71aa394084fa2 Mon Sep 17 00:00:00 2001 From: Donghun Won Date: Sat, 5 Oct 2024 23:30:49 +0900 Subject: [PATCH 366/371] =?UTF-8?q?Feat=20:=20=EC=95=BD=EA=B4=80=20?= =?UTF-8?q?=EB=8F=99=EC=9D=98=EC=8B=9C,=20=EB=B9=84=EB=8F=99=EC=9D=98?= =?UTF-8?q?=EC=8B=9C=20=EC=9C=A0=EC=A0=80=20=EC=B6=94=EA=B0=80=EC=A0=95?= =?UTF-8?q?=EB=B3=B4=20=EC=9E=85=EB=A0=A5=20(#223)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../auth/controller/OauthController.java | 1 - .../solitour/auth/entity/Term.java | 45 ++ .../solitour/auth/entity/TermRepository.java | 15 + .../solitour/auth/service/OauthService.java | 24 +- .../user/controller/UserController.java | 19 +- ...Request.java => AgreeUserInfoRequest.java} | 4 +- .../dto/request/DisagreeUserInfoRequest.java | 11 + .../solitour/user/entity/User.java | 14 +- .../user/repository/UserRepository.java | 4 +- .../solitour/user/service/UserService.java | 33 +- .../solitour/user/user_status/UserStatus.java | 1 + src/main/resources/schema.sql | 20 +- src/main/resources/schema_test.sql | 491 ++++++++++-------- 13 files changed, 424 insertions(+), 258 deletions(-) create mode 100644 src/main/java/solitour_backend/solitour/auth/entity/Term.java create mode 100644 src/main/java/solitour_backend/solitour/auth/entity/TermRepository.java rename src/main/java/solitour_backend/solitour/user/dto/request/{UpdateUserInfoRequest.java => AgreeUserInfoRequest.java} (62%) create mode 100644 src/main/java/solitour_backend/solitour/user/dto/request/DisagreeUserInfoRequest.java diff --git a/src/main/java/solitour_backend/solitour/auth/controller/OauthController.java b/src/main/java/solitour_backend/solitour/auth/controller/OauthController.java index 8bec21b7..607502a6 100644 --- a/src/main/java/solitour_backend/solitour/auth/controller/OauthController.java +++ b/src/main/java/solitour_backend/solitour/auth/controller/OauthController.java @@ -85,7 +85,6 @@ public ResponseEntity logout(HttpServletResponse response, @Authentication return ResponseEntity.ok().build(); } - @PostMapping("/token/refresh") public ResponseEntity reissueAccessToken(HttpServletResponse response, @AuthenticationRefreshPrincipal Long memberId) { diff --git a/src/main/java/solitour_backend/solitour/auth/entity/Term.java b/src/main/java/solitour_backend/solitour/auth/entity/Term.java new file mode 100644 index 00000000..93971929 --- /dev/null +++ b/src/main/java/solitour_backend/solitour/auth/entity/Term.java @@ -0,0 +1,45 @@ +package solitour_backend.solitour.auth.entity; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.FetchType; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.OneToOne; +import jakarta.persistence.Table; +import java.time.LocalDateTime; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import solitour_backend.solitour.user.entity.User; + +@Getter +@NoArgsConstructor +@Entity +@Builder +@AllArgsConstructor +@Table(name = "term") +public class Term { + + @Id + @Column(name = "term_id") + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @OneToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "user_id") + private User user; + + @Column(nullable = false, name = "term_condition_agreement") + private Boolean termCondition; + + @Column(nullable = false, name = "term_privacy_agreement") + private Boolean termPrivacy; + + @Column(name="term_created_at") + private LocalDateTime createdAt; + +} diff --git a/src/main/java/solitour_backend/solitour/auth/entity/TermRepository.java b/src/main/java/solitour_backend/solitour/auth/entity/TermRepository.java new file mode 100644 index 00000000..5dcc6ffa --- /dev/null +++ b/src/main/java/solitour_backend/solitour/auth/entity/TermRepository.java @@ -0,0 +1,15 @@ +package solitour_backend.solitour.auth.entity; + +import java.util.Optional; +import org.springframework.data.jpa.repository.Modifying; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.Repository; +import org.springframework.data.repository.query.Param; +import solitour_backend.solitour.user.entity.User; + +public interface TermRepository extends Repository { + void save(Term term); + + @Query("SELECT t FROM Term t WHERE t.user = :user") + Optional findByUser(User user); +} diff --git a/src/main/java/solitour_backend/solitour/auth/service/OauthService.java b/src/main/java/solitour_backend/solitour/auth/service/OauthService.java index f507a2aa..d1f530b4 100644 --- a/src/main/java/solitour_backend/solitour/auth/service/OauthService.java +++ b/src/main/java/solitour_backend/solitour/auth/service/OauthService.java @@ -258,7 +258,7 @@ private User saveActiveKakaoUser(KakaoUserResponse kakaoUserResponse, CreateUser UserImage savedUserImage = userImageService.saveUserImage(imageUrl); User user = User.builder() - .userStatus(UserStatus.ACTIVATE) + .userStatus(UserStatus.PENDING) .oauthId(String.valueOf(kakaoUserResponse.getId())) .provider("kakao") .isAdmin(false) @@ -279,7 +279,7 @@ private User saveKakaoUser(KakaoUserResponse response) { UserImage savedUserImage = userImageService.saveUserImage(imageUrl); User user = User.builder() - .userStatus(UserStatus.INACTIVATE) + .userStatus(UserStatus.PENDING) .oauthId(String.valueOf(response.getId())) .provider("kakao") .isAdmin(false) @@ -376,15 +376,15 @@ private String getDefaultProfile(User user) { return USER_PROFILE_NONE; } - private void deleteUserProfileFromS3 (UserImage userImage, String defaultImageUrl){ - String userImageUrl = userImage.getAddress(); - if (userImageUrl.equals(USER_PROFILE_MALE) || userImageUrl.equals(USER_PROFILE_FEMALE) - || userImageUrl.equals( - USER_PROFILE_NONE)) { - return; - } - s3Uploader.deleteImage(userImageUrl); - userImage.changeToDefaultProfile(defaultImageUrl); + private void deleteUserProfileFromS3(UserImage userImage, String defaultImageUrl) { + String userImageUrl = userImage.getAddress(); + if (userImageUrl.equals(USER_PROFILE_MALE) || userImageUrl.equals(USER_PROFILE_FEMALE) + || userImageUrl.equals( + USER_PROFILE_NONE)) { + return; } - + s3Uploader.deleteImage(userImageUrl); + userImage.changeToDefaultProfile(defaultImageUrl); } + +} diff --git a/src/main/java/solitour_backend/solitour/user/controller/UserController.java b/src/main/java/solitour_backend/solitour/user/controller/UserController.java index 6287361c..8f586a20 100644 --- a/src/main/java/solitour_backend/solitour/user/controller/UserController.java +++ b/src/main/java/solitour_backend/solitour/user/controller/UserController.java @@ -22,7 +22,8 @@ import solitour_backend.solitour.gathering.dto.response.GatheringMypageResponse; import solitour_backend.solitour.information.dto.response.InformationBriefResponse; import solitour_backend.solitour.user.dto.UpdateNicknameRequest; -import solitour_backend.solitour.user.dto.request.UpdateUserInfoRequest; +import solitour_backend.solitour.user.dto.request.AgreeUserInfoRequest; +import solitour_backend.solitour.user.dto.request.DisagreeUserInfoRequest; import solitour_backend.solitour.user.exception.NicknameAlreadyExistsException; import solitour_backend.solitour.user.exception.UserNotExistsException; import solitour_backend.solitour.user.service.UserService; @@ -44,10 +45,18 @@ public ResponseEntity retrieveUserInfo(@AuthenticationPrincipa return ResponseEntity.ok(response); } - @PutMapping("/info") - public ResponseEntity updateUserInfo(@AuthenticationPrincipal Long userId, - @RequestBody UpdateUserInfoRequest request) { - userService.updateUserInfo(userId, request); + @PutMapping("/info/agree") + public ResponseEntity agreeUserInfo(@AuthenticationPrincipal Long userId, + @RequestBody AgreeUserInfoRequest request) { + userService.agreeUserInfo(userId, request); + + return ResponseEntity.noContent().build(); + } + + @PutMapping("/info/disagree") + public ResponseEntity disagreeUserInfo(@AuthenticationPrincipal Long userId, + @RequestBody DisagreeUserInfoRequest request) { + userService.disagreeUserInfo(userId, request); return ResponseEntity.noContent().build(); } diff --git a/src/main/java/solitour_backend/solitour/user/dto/request/UpdateUserInfoRequest.java b/src/main/java/solitour_backend/solitour/user/dto/request/AgreeUserInfoRequest.java similarity index 62% rename from src/main/java/solitour_backend/solitour/user/dto/request/UpdateUserInfoRequest.java rename to src/main/java/solitour_backend/solitour/user/dto/request/AgreeUserInfoRequest.java index 704c56e3..d1b2c5ed 100644 --- a/src/main/java/solitour_backend/solitour/user/dto/request/UpdateUserInfoRequest.java +++ b/src/main/java/solitour_backend/solitour/user/dto/request/AgreeUserInfoRequest.java @@ -5,7 +5,9 @@ @NoArgsConstructor @Getter -public class UpdateUserInfoRequest { +public class AgreeUserInfoRequest { + private Boolean termConditionAgreement; + private Boolean privacyPolicyAgreement; private String name; private String age; private String sex; diff --git a/src/main/java/solitour_backend/solitour/user/dto/request/DisagreeUserInfoRequest.java b/src/main/java/solitour_backend/solitour/user/dto/request/DisagreeUserInfoRequest.java new file mode 100644 index 00000000..0acb13d3 --- /dev/null +++ b/src/main/java/solitour_backend/solitour/user/dto/request/DisagreeUserInfoRequest.java @@ -0,0 +1,11 @@ +package solitour_backend.solitour.user.dto.request; + +import lombok.Getter; +import lombok.NoArgsConstructor; + +@NoArgsConstructor +@Getter +public class DisagreeUserInfoRequest { + private Boolean termConditionAgreement; + private Boolean privacyPolicyAgreement; +} diff --git a/src/main/java/solitour_backend/solitour/user/entity/User.java b/src/main/java/solitour_backend/solitour/user/entity/User.java index 3be37531..f5196a0d 100644 --- a/src/main/java/solitour_backend/solitour/user/entity/User.java +++ b/src/main/java/solitour_backend/solitour/user/entity/User.java @@ -1,5 +1,6 @@ package solitour_backend.solitour.user.entity; +import jakarta.persistence.CascadeType; import jakarta.persistence.Column; import jakarta.persistence.Convert; import jakarta.persistence.Entity; @@ -15,7 +16,9 @@ import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; -import solitour_backend.solitour.user.dto.request.UpdateUserInfoRequest; +import solitour_backend.solitour.auth.entity.Term; +import solitour_backend.solitour.user.dto.request.AgreeUserInfoRequest; +import solitour_backend.solitour.user.dto.request.DisagreeUserInfoRequest; import solitour_backend.solitour.user.user_status.UserStatus; import solitour_backend.solitour.user.user_status.UserStatusConverter; import solitour_backend.solitour.user_image.entity.UserImage; @@ -47,6 +50,9 @@ public class User { @JoinColumn(name = "user_image_id") private UserImage userImage; + @OneToOne(mappedBy = "user",cascade = CascadeType.ALL) + private Term term; + @Column(name = "user_nickname") private String nickname; @@ -105,10 +111,14 @@ public void updateLoginTime() { this.latestLoginAt = LocalDateTime.now(); } - public void updateUserInfo(UpdateUserInfoRequest request) { + public void agreeUserInfo(AgreeUserInfoRequest request) { this.name = request.getName(); this.userStatus = UserStatus.ACTIVATE; this.age = Integer.valueOf(request.getAge()); this.sex = request.getSex(); } + + public void disagreeUserInfo(DisagreeUserInfoRequest request) { + this.userStatus = UserStatus.INACTIVATE; + } } diff --git a/src/main/java/solitour_backend/solitour/user/repository/UserRepository.java b/src/main/java/solitour_backend/solitour/user/repository/UserRepository.java index 059014d9..e518bdb0 100644 --- a/src/main/java/solitour_backend/solitour/user/repository/UserRepository.java +++ b/src/main/java/solitour_backend/solitour/user/repository/UserRepository.java @@ -7,10 +7,10 @@ public interface UserRepository extends JpaRepository, UserRepositoryCustom { - @Query("SELECT u FROM User u JOIN FETCH u.userImage WHERE u.id = :userId AND (u.userStatus = '활성화' OR u.userStatus = '비활성화')") + @Query("SELECT u FROM User u JOIN FETCH u.userImage WHERE u.id = :userId AND u.userStatus NOT IN ('차단', '휴먼','삭제')") User findByUserId(Long userId); - @Query("SELECT u FROM User u JOIN FETCH u.userImage WHERE u.oauthId = :oauthId AND (u.userStatus = '활성화' OR u.userStatus = '비활성화')") + @Query("SELECT u FROM User u JOIN FETCH u.userImage WHERE u.oauthId = :oauthId AND u.userStatus NOT IN ('차단', '휴먼','삭제')") Optional findByOauthId(String oauthId); boolean existsByNickname(String nickname); diff --git a/src/main/java/solitour_backend/solitour/user/service/UserService.java b/src/main/java/solitour_backend/solitour/user/service/UserService.java index 92bcd343..03d06b06 100644 --- a/src/main/java/solitour_backend/solitour/user/service/UserService.java +++ b/src/main/java/solitour_backend/solitour/user/service/UserService.java @@ -1,5 +1,6 @@ package solitour_backend.solitour.user.service; +import java.time.LocalDateTime; import lombok.RequiredArgsConstructor; import org.springframework.beans.factory.annotation.Value; import org.springframework.data.domain.Page; @@ -7,11 +8,14 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.multipart.MultipartFile; +import solitour_backend.solitour.auth.entity.Term; +import solitour_backend.solitour.auth.entity.TermRepository; import solitour_backend.solitour.gathering.dto.response.GatheringApplicantResponse; import solitour_backend.solitour.gathering.dto.response.GatheringMypageResponse; import solitour_backend.solitour.image.s3.S3Uploader; import solitour_backend.solitour.information.dto.response.InformationBriefResponse; -import solitour_backend.solitour.user.dto.request.UpdateUserInfoRequest; +import solitour_backend.solitour.user.dto.request.AgreeUserInfoRequest; +import solitour_backend.solitour.user.dto.request.DisagreeUserInfoRequest; import solitour_backend.solitour.user.entity.User; import solitour_backend.solitour.user.exception.NicknameAlreadyExistsException; import solitour_backend.solitour.user.repository.UserRepository; @@ -26,6 +30,7 @@ public class UserService { private final UserRepository userRepository; private final UserImageService userImageService; + private final TermRepository termRepository; private final S3Uploader s3Uploader; @Value("${user.profile.url.female}") private String femaleProfileUrl; @@ -84,13 +89,33 @@ public Page retrieveGatheringApplicant(Pageable page } @Transactional - public void updateUserInfo(Long userId, UpdateUserInfoRequest request) { + public void agreeUserInfo(Long userId, AgreeUserInfoRequest request) { User user = userRepository.findByUserId(userId); changeUserProfile(user, request); - user.updateUserInfo(request); + if(!termRepository.findByUser(user).isPresent()){ + saveTerm(user, request.getTermConditionAgreement(),request.getPrivacyPolicyAgreement()); + } + user.agreeUserInfo(request); + } + + @Transactional + public void disagreeUserInfo(Long userId, DisagreeUserInfoRequest request) { + User user = userRepository.findByUserId(userId); + saveTerm(user, request.getTermConditionAgreement(),request.getPrivacyPolicyAgreement()); + user.disagreeUserInfo(request); + } + + private void saveTerm(User user, Boolean termCondition, Boolean termPrivacy) { + Term term = Term.builder() + .user(user) + .termCondition(termCondition) + .termPrivacy(termPrivacy) + .createdAt(LocalDateTime.now()) + .build(); + termRepository.save(term); } - private void changeUserProfile(User user, UpdateUserInfoRequest request) { + private void changeUserProfile(User user, AgreeUserInfoRequest request) { String sex = request.getSex(); if(user.getUserImage().equals(noneProfileUrl) && sex.equals("male")){ diff --git a/src/main/java/solitour_backend/solitour/user/user_status/UserStatus.java b/src/main/java/solitour_backend/solitour/user/user_status/UserStatus.java index 3e6759c1..a18f459e 100644 --- a/src/main/java/solitour_backend/solitour/user/user_status/UserStatus.java +++ b/src/main/java/solitour_backend/solitour/user/user_status/UserStatus.java @@ -5,6 +5,7 @@ @Getter public enum UserStatus { + PENDING("대기"), ACTIVATE("활성화"), INACTIVATE("비활성화"), BLOCK("차단"), diff --git a/src/main/resources/schema.sql b/src/main/resources/schema.sql index 80fd873d..04f00ebf 100644 --- a/src/main/resources/schema.sql +++ b/src/main/resources/schema.sql @@ -19,11 +19,13 @@ DROP TABLE IF EXISTS `banner`; DROP TABLE IF EXISTS `notice`; DROP TABLE IF EXISTS `qna_message`; DROP TABLE IF EXISTS `qna`; +DROP TABLE IF EXISTS `term`; DROP TABLE IF EXISTS `user`; DROP TABLE IF EXISTS `user_image`; DROP TABLE IF EXISTS `diary_day_content`; DROP TABLE IF EXISTS `diary`; + CREATE TABLE `user_image` ( `user_image_id` BIGINT NOT NULL AUTO_INCREMENT, @@ -55,8 +57,8 @@ CREATE TABLE `user` CREATE TABLE `token` ( - `token_id` BIGINT NOT NULL AUTO_INCREMENT, - `user_id` BIGINT NOT NULL, + `token_id` BIGINT NOT NULL AUTO_INCREMENT, + `user_id` BIGINT NOT NULL, `refresh_token` VARCHAR(250) NULL, `oauth_token` VARCHAR(250) NULL, CONSTRAINT PK_TOKEN PRIMARY KEY (`token_id`), @@ -311,4 +313,16 @@ CREATE TABLE `diary_day_content` `diary_day_content_image` TEXT DEFAULT NULL, PRIMARY KEY (`diary_day_content_id`), CONSTRAINT `FK_diary_day_content_TO_diary` FOREIGN KEY (`diary_id`) REFERENCES `diary` (`diary_id`) -); \ No newline at end of file +); + + +CREATE TABLE `term` +( + `term_id` BIGINT NOT NULL AUTO_INCREMENT, + `user_id` BIGINT NOT NULL, + `term_condition_agreement` BOOLEAN NOT NULL, + `term_privacy_agreement` BOOLEAN NOT NULL, + `term_created_at` DATETIME NOT NULL, + PRIMARY KEY (`term_id`), + CONSTRAINT `FK_term_TO_user` FOREIGN KEY (`user_id`) REFERENCES `user` (`user_id`) +); diff --git a/src/main/resources/schema_test.sql b/src/main/resources/schema_test.sql index b1b35768..e05c3e18 100644 --- a/src/main/resources/schema_test.sql +++ b/src/main/resources/schema_test.sql @@ -23,233 +23,268 @@ DROP TABLE IF EXISTS "qna_message"; DROP TABLE IF EXISTS "notice"; DROP TABLE IF EXISTS "diary"; DROP TABLE IF EXISTS "diary_day_content"; +DROP TABLE IF EXISTS `term`; -- 테이블 생성 -CREATE TABLE "user_image" ( - "user_image_id" BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY, - "user_image_address" VARCHAR(200) NOT NULL, - "user_image_created_date" DATE NOT NULL -); - -CREATE TABLE "user" ( - "user_id" BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY, - "user_image_id" BIGINT NOT NULL, - "user_status_id" VARCHAR(20) NOT NULL, - "user_oauth_id" VARCHAR(100), - "provider" VARCHAR(10), - "user_nickname" VARCHAR(30), - "user_name" VARCHAR(20), - "user_age" INT, - "user_sex" VARCHAR(10), - "user_email" VARCHAR(30), - "user_phone_number" VARCHAR(13), - "is_admin" BOOLEAN NOT NULL, - "user_latest_login_at" DATETIME, - "user_created_at" DATETIME NOT NULL, - "user_deleted_at" DATETIME, - FOREIGN KEY ("user_image_id") REFERENCES "user_image" ("user_image_id") -); - -CREATE TABLE "token" ( - "token_id" BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY, - "user_id" BIGINT NOT NULL, - "refresh_token" VARCHAR(250) NOT NULL, - FOREIGN KEY ("user_id") REFERENCES "user" ("user_id") -); - -CREATE TABLE "place" ( - "place_id" BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY, - "place_search_id" VARCHAR(30), - "place_name" VARCHAR(30) NOT NULL, - "place_x_axis" DECIMAL(10, 7) NOT NULL, - "place_y_axis" DECIMAL(10, 7) NOT NULL, - "place_address" VARCHAR(50) NOT NULL -); - -CREATE TABLE "zone_category" ( - "zone_category_id" BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY, - "parent_zone_category_id" BIGINT, - "zone_category_name" VARCHAR(20) NOT NULL, - FOREIGN KEY ("parent_zone_category_id") REFERENCES "zone_category" ("zone_category_id") -); - -CREATE TABLE "category" ( - "category_id" BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY, - "parent_category_id" BIGINT, - "category_name" VARCHAR(20) NOT NULL, - FOREIGN KEY ("parent_category_id") REFERENCES "category" ("category_id") -); - -CREATE TABLE "gathering_category" ( - "gathering_category_id" BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY, - "gathering_category_name" VARCHAR(20) NOT NULL -); - -CREATE TABLE "information" ( - "information_id" BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY, - "category_id" BIGINT NOT NULL, - "zone_category_id" BIGINT NOT NULL, - "user_id" BIGINT NOT NULL, - "place_id" BIGINT NOT NULL, - "information_title" VARCHAR(50) NOT NULL, - "information_address" VARCHAR(50) NOT NULL, - "information_created_date" DATETIME NOT NULL, - "information_view_count" INT NOT NULL DEFAULT 0, - "information_content" TEXT, - "information_tip" TEXT, - FOREIGN KEY ("category_id") REFERENCES "category" ("category_id"), - FOREIGN KEY ("zone_category_id") REFERENCES "zone_category" ("zone_category_id"), - FOREIGN KEY ("user_id") REFERENCES "user" ("user_id"), - FOREIGN KEY ("place_id") REFERENCES "place" ("place_id") -); - -CREATE TABLE "gathering" ( - "gathering_id" BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY, - "user_id" BIGINT NOT NULL, - "zone_category_id" BIGINT NOT NULL, - "gathering_category_id" BIGINT NOT NULL, - "place_id" BIGINT NOT NULL, - "gathering_title" VARCHAR(50), - "gathering_content" TEXT, - "gathering_person_count" INT, - "gathering_view_count" INT, - "gathering_created_at" DATETIME, - "gathering_edited_at" DATETIME, - "gathering_schedule_start_date" DATETIME, - "gathering_schedule_end_date" DATETIME, - "gathering_is_finish" BOOLEAN, - "gathering_deadline" DATETIME, - "gathering_allowed_sex" VARCHAR(30) NOT NULL, - "gathering_start_age" INT NOT NULL, - "gathering_end_age" INT NOT NULL, - "gathering_is_deleted" BOOLEAN NOT NULL DEFAULT FALSE, - "gathering_open_chatting_url" VARCHAR(255), - FOREIGN KEY ("user_id") REFERENCES "user" ("user_id"), - FOREIGN KEY ("gathering_category_id") REFERENCES "gathering_category" ("gathering_category_id"), - FOREIGN KEY ("zone_category_id") REFERENCES "zone_category" ("zone_category_id"), - FOREIGN KEY ("place_id") REFERENCES "place" ("place_id") -); - -CREATE TABLE "gathering_applicants" ( - "gathering_applicants_id" BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY, - "gathering_id" BIGINT NOT NULL, - "user_id" BIGINT NOT NULL, - "gathering_applicants_state" VARCHAR(20) NOT NULL, - FOREIGN KEY ("gathering_id") REFERENCES "gathering" ("gathering_id"), - FOREIGN KEY ("user_id") REFERENCES "user" ("user_id") -); - -CREATE TABLE "image" ( - "image_id" BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY, - "image_status_id" VARCHAR(20) NOT NULL, - "information_id" BIGINT NOT NULL, - "image_address" VARCHAR(200) NOT NULL, - "image_created_date" DATE NOT NULL, - FOREIGN KEY ("information_id") REFERENCES "information" ("information_id") -); - -CREATE TABLE "great_information" ( - "great_information_id" BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY, - "user_id" BIGINT NOT NULL, - "information_id" BIGINT NOT NULL, - FOREIGN KEY ("user_id") REFERENCES "user" ("user_id"), - FOREIGN KEY ("information_id") REFERENCES "information" ("information_id"), - UNIQUE ("user_id", "information_id") -); - -CREATE TABLE "great_gathering" ( - "great_gathering_id" BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY, - "user_id" BIGINT NOT NULL, - "gathering_id" BIGINT NOT NULL, - FOREIGN KEY ("user_id") REFERENCES "user" ("user_id"), - FOREIGN KEY ("gathering_id") REFERENCES "gathering" ("gathering_id"), - UNIQUE ("user_id", "gathering_id") -); - -CREATE TABLE "book_mark_information" ( - "book_mark_information_id" BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY, - "user_id" BIGINT NOT NULL, - "information_id" BIGINT NOT NULL, - FOREIGN KEY ("user_id") REFERENCES "user" ("user_id"), - FOREIGN KEY ("information_id") REFERENCES "information" ("information_id"), - UNIQUE ("user_id", "information_id") -); - -CREATE TABLE "book_mark_gathering" ( - "book_mark_gathering_id" BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY, - "user_id" BIGINT NOT NULL, - "gathering_id" BIGINT NOT NULL, - FOREIGN KEY ("user_id") REFERENCES "user" ("user_id"), - FOREIGN KEY ("gathering_id") REFERENCES "gathering" ("gathering_id"), - UNIQUE ("user_id", "gathering_id") -); - -CREATE TABLE "tag" ( - "tag_id" BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY, - "tag_name" VARCHAR(16) NOT NULL -); - -CREATE TABLE "info_tag" ( - "info_tag_id" BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY, - "tag_id" BIGINT NOT NULL, - "information_id" BIGINT NOT NULL, - FOREIGN KEY ("tag_id") REFERENCES "tag" ("tag_id"), - FOREIGN KEY ("information_id") REFERENCES "information" ("information_id"), - UNIQUE ("tag_id", "information_id") -); - -CREATE TABLE "gathering_tag" ( - "gathering_tag_id" BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY, - "tag_id" BIGINT NOT NULL, - "gathering_id" BIGINT NOT NULL, - FOREIGN KEY ("tag_id") REFERENCES "tag" ("tag_id"), - FOREIGN KEY ("gathering_id") REFERENCES "gathering" ("gathering_id"), - UNIQUE ("tag_id", "gathering_id") -); - -CREATE TABLE "banner" ( - "id" BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY, - "name" VARCHAR(255) NOT NULL, - "url" VARCHAR(255) NOT NULL -); - -CREATE TABLE "qna" ( - "qna_id" BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY, - "qna_category_name" VARCHAR(255), - "qna_created_at" DATETIME, - "qna_status" VARCHAR(255), - "qna_title" VARCHAR(255), - "qna_updated_at" DATETIME, - "user_id" BIGINT, - FOREIGN KEY ("user_id") REFERENCES "user" ("user_id") -); - -CREATE TABLE "qna_message" ( - "id" BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY, - "qna_message_content" TEXT, - "qna_message_created_at" DATETIME, - "qna_message_user_id" BIGINT, - "qna_id" BIGINT, - FOREIGN KEY ("qna_id") REFERENCES "qna" ("qna_id"), - FOREIGN KEY ("qna_message_user_id") REFERENCES "user" ("user_id") -); - -CREATE TABLE "notice" ( - "notice_id" BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY, - "notice_category_name" VARCHAR(255), - "notice_content" TEXT, - "notice_created_at" DATETIME, - "notice_is_deleted" BOOLEAN DEFAULT FALSE, - "notice_title" VARCHAR(255) -); - -CREATE TABLE "diary" ( - "diary_id" BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY, - "user_id" BIGINT NOT NULL, - "diary_title" VARCHAR(50) NOT NULL, - "diary_title_image" VARCHAR(200) DEFAULT NULL, - "diary_start_date" DATETIME NOT NULL, - "diary_end_date" DATETIME NOT NULL, - "diary_created_date" DATETIME NOT NULL, - "diary_edited_date" DATETIME DEFAULT NULL -); \ No newline at end of file +CREATE TABLE "user_image" +( + "user_image_id" BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY, + "user_image_address" VARCHAR(200) NOT NULL, + "user_image_created_date" DATE NOT NULL +); + +CREATE TABLE "user" +( + "user_id" BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY, + "user_image_id" BIGINT NOT NULL, + "user_status_id" VARCHAR(20) NOT NULL, + "user_oauth_id" VARCHAR(100), + "provider" VARCHAR(10), + "user_nickname" VARCHAR(30), + "user_name" VARCHAR(20), + "user_age" INT, + "user_sex" VARCHAR(10), + "user_email" VARCHAR(30), + "user_phone_number" VARCHAR(13), + "is_admin" BOOLEAN NOT NULL, + "user_latest_login_at" DATETIME, + "user_created_at" DATETIME NOT NULL, + "user_deleted_at" DATETIME, + FOREIGN KEY ("user_image_id") REFERENCES "user_image" ("user_image_id") +); + +CREATE TABLE "token" +( + "token_id" BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY, + "user_id" BIGINT NOT NULL, + "refresh_token" VARCHAR(250) NOT NULL, + FOREIGN KEY ("user_id") REFERENCES "user" ("user_id") +); + +CREATE TABLE "place" +( + "place_id" BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY, + "place_search_id" VARCHAR(30), + "place_name" VARCHAR(30) NOT NULL, + "place_x_axis" DECIMAL(10, 7) NOT NULL, + "place_y_axis" DECIMAL(10, 7) NOT NULL, + "place_address" VARCHAR(50) NOT NULL +); + +CREATE TABLE "zone_category" +( + "zone_category_id" BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY, + "parent_zone_category_id" BIGINT, + "zone_category_name" VARCHAR(20) NOT NULL, + FOREIGN KEY ("parent_zone_category_id") REFERENCES "zone_category" ("zone_category_id") +); + +CREATE TABLE "category" +( + "category_id" BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY, + "parent_category_id" BIGINT, + "category_name" VARCHAR(20) NOT NULL, + FOREIGN KEY ("parent_category_id") REFERENCES "category" ("category_id") +); + +CREATE TABLE "gathering_category" +( + "gathering_category_id" BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY, + "gathering_category_name" VARCHAR(20) NOT NULL +); + +CREATE TABLE "information" +( + "information_id" BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY, + "category_id" BIGINT NOT NULL, + "zone_category_id" BIGINT NOT NULL, + "user_id" BIGINT NOT NULL, + "place_id" BIGINT NOT NULL, + "information_title" VARCHAR(50) NOT NULL, + "information_address" VARCHAR(50) NOT NULL, + "information_created_date" DATETIME NOT NULL, + "information_view_count" INT NOT NULL DEFAULT 0, + "information_content" TEXT, + "information_tip" TEXT, + FOREIGN KEY ("category_id") REFERENCES "category" ("category_id"), + FOREIGN KEY ("zone_category_id") REFERENCES "zone_category" ("zone_category_id"), + FOREIGN KEY ("user_id") REFERENCES "user" ("user_id"), + FOREIGN KEY ("place_id") REFERENCES "place" ("place_id") +); + +CREATE TABLE "gathering" +( + "gathering_id" BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY, + "user_id" BIGINT NOT NULL, + "zone_category_id" BIGINT NOT NULL, + "gathering_category_id" BIGINT NOT NULL, + "place_id" BIGINT NOT NULL, + "gathering_title" VARCHAR(50), + "gathering_content" TEXT, + "gathering_person_count" INT, + "gathering_view_count" INT, + "gathering_created_at" DATETIME, + "gathering_edited_at" DATETIME, + "gathering_schedule_start_date" DATETIME, + "gathering_schedule_end_date" DATETIME, + "gathering_is_finish" BOOLEAN, + "gathering_deadline" DATETIME, + "gathering_allowed_sex" VARCHAR(30) NOT NULL, + "gathering_start_age" INT NOT NULL, + "gathering_end_age" INT NOT NULL, + "gathering_is_deleted" BOOLEAN NOT NULL DEFAULT FALSE, + "gathering_open_chatting_url" VARCHAR(255), + FOREIGN KEY ("user_id") REFERENCES "user" ("user_id"), + FOREIGN KEY ("gathering_category_id") REFERENCES "gathering_category" ("gathering_category_id"), + FOREIGN KEY ("zone_category_id") REFERENCES "zone_category" ("zone_category_id"), + FOREIGN KEY ("place_id") REFERENCES "place" ("place_id") +); + +CREATE TABLE "gathering_applicants" +( + "gathering_applicants_id" BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY, + "gathering_id" BIGINT NOT NULL, + "user_id" BIGINT NOT NULL, + "gathering_applicants_state" VARCHAR(20) NOT NULL, + FOREIGN KEY ("gathering_id") REFERENCES "gathering" ("gathering_id"), + FOREIGN KEY ("user_id") REFERENCES "user" ("user_id") +); + +CREATE TABLE "image" +( + "image_id" BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY, + "image_status_id" VARCHAR(20) NOT NULL, + "information_id" BIGINT NOT NULL, + "image_address" VARCHAR(200) NOT NULL, + "image_created_date" DATE NOT NULL, + FOREIGN KEY ("information_id") REFERENCES "information" ("information_id") +); + +CREATE TABLE "great_information" +( + "great_information_id" BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY, + "user_id" BIGINT NOT NULL, + "information_id" BIGINT NOT NULL, + FOREIGN KEY ("user_id") REFERENCES "user" ("user_id"), + FOREIGN KEY ("information_id") REFERENCES "information" ("information_id"), + UNIQUE ("user_id", "information_id") +); + +CREATE TABLE "great_gathering" +( + "great_gathering_id" BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY, + "user_id" BIGINT NOT NULL, + "gathering_id" BIGINT NOT NULL, + FOREIGN KEY ("user_id") REFERENCES "user" ("user_id"), + FOREIGN KEY ("gathering_id") REFERENCES "gathering" ("gathering_id"), + UNIQUE ("user_id", "gathering_id") +); + +CREATE TABLE "book_mark_information" +( + "book_mark_information_id" BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY, + "user_id" BIGINT NOT NULL, + "information_id" BIGINT NOT NULL, + FOREIGN KEY ("user_id") REFERENCES "user" ("user_id"), + FOREIGN KEY ("information_id") REFERENCES "information" ("information_id"), + UNIQUE ("user_id", "information_id") +); + +CREATE TABLE "book_mark_gathering" +( + "book_mark_gathering_id" BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY, + "user_id" BIGINT NOT NULL, + "gathering_id" BIGINT NOT NULL, + FOREIGN KEY ("user_id") REFERENCES "user" ("user_id"), + FOREIGN KEY ("gathering_id") REFERENCES "gathering" ("gathering_id"), + UNIQUE ("user_id", "gathering_id") +); + +CREATE TABLE "tag" +( + "tag_id" BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY, + "tag_name" VARCHAR(16) NOT NULL +); + +CREATE TABLE "info_tag" +( + "info_tag_id" BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY, + "tag_id" BIGINT NOT NULL, + "information_id" BIGINT NOT NULL, + FOREIGN KEY ("tag_id") REFERENCES "tag" ("tag_id"), + FOREIGN KEY ("information_id") REFERENCES "information" ("information_id"), + UNIQUE ("tag_id", "information_id") +); + +CREATE TABLE "gathering_tag" +( + "gathering_tag_id" BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY, + "tag_id" BIGINT NOT NULL, + "gathering_id" BIGINT NOT NULL, + FOREIGN KEY ("tag_id") REFERENCES "tag" ("tag_id"), + FOREIGN KEY ("gathering_id") REFERENCES "gathering" ("gathering_id"), + UNIQUE ("tag_id", "gathering_id") +); + +CREATE TABLE "banner" +( + "id" BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY, + "name" VARCHAR(255) NOT NULL, + "url" VARCHAR(255) NOT NULL +); + +CREATE TABLE "qna" +( + "qna_id" BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY, + "qna_category_name" VARCHAR(255), + "qna_created_at" DATETIME, + "qna_status" VARCHAR(255), + "qna_title" VARCHAR(255), + "qna_updated_at" DATETIME, + "user_id" BIGINT, + FOREIGN KEY ("user_id") REFERENCES "user" ("user_id") +); + +CREATE TABLE "qna_message" +( + "id" BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY, + "qna_message_content" TEXT, + "qna_message_created_at" DATETIME, + "qna_message_user_id" BIGINT, + "qna_id" BIGINT, + FOREIGN KEY ("qna_id") REFERENCES "qna" ("qna_id"), + FOREIGN KEY ("qna_message_user_id") REFERENCES "user" ("user_id") +); + +CREATE TABLE "notice" +( + "notice_id" BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY, + "notice_category_name" VARCHAR(255), + "notice_content" TEXT, + "notice_created_at" DATETIME, + "notice_is_deleted" BOOLEAN DEFAULT FALSE, + "notice_title" VARCHAR(255) +); + +CREATE TABLE "diary" +( + "diary_id" BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY, + "user_id" BIGINT NOT NULL, + "diary_title" VARCHAR(50) NOT NULL, + "diary_title_image" VARCHAR(200) DEFAULT NULL, + "diary_start_date" DATETIME NOT NULL, + "diary_end_date" DATETIME NOT NULL, + "diary_created_date" DATETIME NOT NULL, + "diary_edited_date" DATETIME DEFAULT NULL +); + +CREATE TABLE `term` +( + `term_id` BIGINT NOT NULL AUTO_INCREMENT, + `user_id` BIGINT NOT NULL, + `term_condition_agreement` BOOLEAN NOT NULL, + `term_privacy_agreement` BOOLEAN NOT NULL, + `term_created_at` DATETIME NOT NULL, + PRIMARY KEY (`term_id`), + CONSTRAINT `FK_term_TO_user` FOREIGN KEY (`user_id`) REFERENCES `user` (`user_id`) +); From e43d4dcd109defc86b34c525470b725415debf91 Mon Sep 17 00:00:00 2001 From: Donghun Won Date: Mon, 7 Oct 2024 16:14:41 +0900 Subject: [PATCH 367/371] =?UTF-8?q?Fix(#216)=20:=20=EC=9D=BC=EA=B8=B0=20?= =?UTF-8?q?=EC=9D=B4=EB=AF=B8=EC=A7=80=20=ED=95=98=EB=A3=A8=20=EC=A7=80?= =?UTF-8?q?=EB=82=98=EB=A9=B4=20=EC=82=AD=EC=A0=9C=EB=90=98=EB=8A=94=20?= =?UTF-8?q?=EB=AC=B8=EC=A0=9C=20=20(#224)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Fix : 유저, 일기 이미지 자동삭제 되지 않게 수정 * Fix : 일기 내 이미지 url 쉼표로 구분하여 영구화하도록 수정 --- .../solitour/diary/service/DiaryService.java | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/main/java/solitour_backend/solitour/diary/service/DiaryService.java b/src/main/java/solitour_backend/solitour/diary/service/DiaryService.java index 78c9775e..7c90983e 100644 --- a/src/main/java/solitour_backend/solitour/diary/service/DiaryService.java +++ b/src/main/java/solitour_backend/solitour/diary/service/DiaryService.java @@ -94,7 +94,8 @@ public void updateDiary(Long userId, Long diaryId, DiaryUpdateRequest request) { } private void updateDiary(Long diaryId, DiaryUpdateRequest request) { - Diary diary = diaryRepository.findById(diaryId).orElseThrow(() -> new DiaryNotExistsException("해당 일기가 존재하지 않습니다.")); + Diary diary = diaryRepository.findById(diaryId) + .orElseThrow(() -> new DiaryNotExistsException("해당 일기가 존재하지 않습니다.")); deleteDiaryImage(request); diary.getDiaryDayContent().clear(); diary.updateDiary(request); @@ -103,7 +104,7 @@ private void updateDiary(Long diaryId, DiaryUpdateRequest request) { private void saveDiaryDayContent(Diary savedDiary, DiaryCreateRequest request) { for (DiaryDayRequest dayRequest : request.getDiaryDayRequests()) { - s3Uploader.markImagePermanent(dayRequest.getDiaryDayContentImages()); + makeDiaryImagePermanent(dayRequest.getDiaryDayContentImages()); DiaryDayContent diaryDayContent = DiaryDayContent.builder() .diary(savedDiary) .content(dayRequest.getContent()) @@ -115,6 +116,15 @@ private void saveDiaryDayContent(Diary savedDiary, DiaryCreateRequest request) { } } + private void makeDiaryImagePermanent(String diaryDayContentImages) { + if (!diaryDayContentImages.isEmpty()) { + String[] contentImages = diaryDayContentImages.split(","); + for (String contentImage : contentImages) { + s3Uploader.markImagePermanent(contentImage); + } + } + } + private void updateDiaryDayContent(Diary savedDiary, DiaryUpdateRequest request) { diaryDayContentRepository.deleteById(savedDiary.getId()); for (DiaryUpdateDayRequest dayRequest : request.getDiaryDayRequests()) { From 42f64ba204992c1a18f03d34a313efa0913baaf2 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Fri, 11 Oct 2024 11:55:19 +0900 Subject: [PATCH 368/371] =?UTF-8?q?feat:=20toString()=20=EB=A9=94=EC=84=9C?= =?UTF-8?q?=EB=93=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../information/dto/response/InformationBriefResponse.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/solitour_backend/solitour/information/dto/response/InformationBriefResponse.java b/src/main/java/solitour_backend/solitour/information/dto/response/InformationBriefResponse.java index c8332111..24784877 100644 --- a/src/main/java/solitour_backend/solitour/information/dto/response/InformationBriefResponse.java +++ b/src/main/java/solitour_backend/solitour/information/dto/response/InformationBriefResponse.java @@ -2,9 +2,11 @@ import lombok.AllArgsConstructor; import lombok.Getter; +import lombok.ToString; @Getter @AllArgsConstructor +@ToString public class InformationBriefResponse { private Long informationId; From 5f962dcc09762d47270516aeacf456455f0c242a Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Fri, 11 Oct 2024 11:55:40 +0900 Subject: [PATCH 369/371] =?UTF-8?q?fix:=20=ED=8E=98=EC=9D=B4=EC=A7=80?= =?UTF-8?q?=EB=84=A4=EC=9D=B4=EC=85=98=20=EB=A9=94=EC=84=9C=EB=93=9C=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD=20=EB=B0=8F=20=EA=B8=B0=EC=A1=B4=EC=9D=98=20?= =?UTF-8?q?=EB=A9=94=EC=84=9C=EB=93=9C=20=EC=A3=BC=EC=84=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../repository/InformationRepositoryCustom.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/main/java/solitour_backend/solitour/information/repository/InformationRepositoryCustom.java b/src/main/java/solitour_backend/solitour/information/repository/InformationRepositoryCustom.java index 4100ea69..0076f59c 100644 --- a/src/main/java/solitour_backend/solitour/information/repository/InformationRepositoryCustom.java +++ b/src/main/java/solitour_backend/solitour/information/repository/InformationRepositoryCustom.java @@ -14,10 +14,11 @@ public interface InformationRepositoryCustom { String LIKE_COUNT_SORT = "likes"; String VIEW_COUNT_SORT = "views"; + Page getPageInformationFilterAndOrder(Pageable pageable, InformationPageRequest informationPageRequest, Long userId, Long parentCategoryId); - Page getInformationPageFilterAndOrder(Pageable pageable, - InformationPageRequest informationPageRequest, - Long userId, Long parentCategoryId); +// Page getInformationPageFilterAndOrder(Pageable pageable, +// InformationPageRequest informationPageRequest, +// Long userId, Long parentCategoryId); List getInformationRank(); From ce202600478b183ec42fced6073a98e9c95307b8 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Fri, 11 Oct 2024 11:56:00 +0900 Subject: [PATCH 370/371] =?UTF-8?q?fix:=20=ED=8E=98=EC=9D=B4=EC=A7=80?= =?UTF-8?q?=EB=84=A4=EC=9D=B4=EC=85=98=20=EC=BF=BC=EB=A6=AC=EB=AC=B8=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD=EC=9C=BC=EB=A1=9C=20=EC=9D=B8=ED=95=B4=20?= =?UTF-8?q?=EB=A9=94=EC=84=9C=EB=93=9C=20=EB=B3=80=EA=B2=BD=20=EB=B0=8F=20?= =?UTF-8?q?=EA=B8=B0=EC=A1=B4=EC=9D=98=20=EB=A9=94=EC=84=9C=EB=93=9C=20?= =?UTF-8?q?=EC=A3=BC=EC=84=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../repository/InformationRepositoryImpl.java | 171 ++++++++++++++---- 1 file changed, 131 insertions(+), 40 deletions(-) diff --git a/src/main/java/solitour_backend/solitour/information/repository/InformationRepositoryImpl.java b/src/main/java/solitour_backend/solitour/information/repository/InformationRepositoryImpl.java index 67a26578..c7799cbb 100644 --- a/src/main/java/solitour_backend/solitour/information/repository/InformationRepositoryImpl.java +++ b/src/main/java/solitour_backend/solitour/information/repository/InformationRepositoryImpl.java @@ -11,6 +11,7 @@ import java.util.List; import java.util.Objects; +import lombok.extern.slf4j.Slf4j; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageImpl; import org.springframework.data.domain.Pageable; @@ -29,6 +30,7 @@ import solitour_backend.solitour.information.entity.QInformation; import solitour_backend.solitour.zone_category.entity.QZoneCategory; +@Slf4j public class InformationRepositoryImpl extends QuerydslRepositorySupport implements InformationRepositoryCustom { public InformationRepositoryImpl() { @@ -42,47 +44,48 @@ public InformationRepositoryImpl() { QImage image = QImage.image; QGreatInformation greatInformation = QGreatInformation.greatInformation; QCategory category = QCategory.category; + QCategory categoryParent = new QCategory("categoryParent"); QInfoTag infoTag = QInfoTag.infoTag; - - @Override - public Page getInformationPageFilterAndOrder(Pageable pageable, - InformationPageRequest informationPageRequest, - Long userId, Long parentCategoryId) { + public Page getPageInformationFilterAndOrder(Pageable pageable, InformationPageRequest informationPageRequest, Long userId, Long parentCategoryId) { BooleanBuilder whereClause = new BooleanBuilder(); - if (Objects.nonNull(informationPageRequest.getZoneCategoryId())) { whereClause.and( - information.zoneCategory.parentZoneCategory.id.eq(informationPageRequest.getZoneCategoryId())); + zoneCategoryParent.id.eq(informationPageRequest.getZoneCategoryId()) + ); } - BooleanBuilder categoryCondition = new BooleanBuilder(); - if (Objects.nonNull(informationPageRequest.getChildCategoryId())) { - whereClause.and(information.category.id.eq(informationPageRequest.getChildCategoryId())); + whereClause.and(category.id.eq(informationPageRequest.getChildCategoryId())); } else { - categoryCondition.and(category.parentCategory.id.eq(parentCategoryId)); + whereClause.and(categoryParent.id.eq(parentCategoryId)); } - if (Objects.nonNull(informationPageRequest.getSearch())) { String searchKeyword = informationPageRequest.getSearch().trim().replace(" ", ""); whereClause.and(information.title.trim().containsIgnoreCase(searchKeyword)); } - long total = from(information) + .leftJoin(zoneCategoryChild).on(zoneCategoryChild.id.eq(information.zoneCategory.id)) + .leftJoin(zoneCategoryParent).on(zoneCategoryChild.parentZoneCategory.id.eq(zoneCategoryParent.id)) + .leftJoin(category).on(category.id.eq(information.category.id)) + .leftJoin(categoryParent).on(categoryParent.id.eq(category.parentCategory.id)) + .join(image).on(image.information.id.eq(information.id).and(image.imageStatus.eq(ImageStatus.THUMBNAIL))) .where(whereClause) - .select(information.id).fetchCount(); + .distinct() + .fetchCount(); List list = from(information) - .join(zoneCategoryChild).on(zoneCategoryChild.id.eq(information.zoneCategory.id)) - .leftJoin(zoneCategoryParent).on(zoneCategoryParent.id.eq(zoneCategoryChild.parentZoneCategory.id)) - .leftJoin(image) - .on(image.information.id.eq(information.id).and(image.imageStatus.eq(ImageStatus.THUMBNAIL))) - .join(category).on(category.id.eq(information.category.id).and(categoryCondition)) + .leftJoin(zoneCategoryChild).on(zoneCategoryChild.id.eq(information.zoneCategory.id)) + .leftJoin(zoneCategoryParent).on(zoneCategoryChild.parentZoneCategory.id.eq(zoneCategoryParent.id)) + .leftJoin(category).on(category.id.eq(information.category.id)) + .leftJoin(categoryParent).on(categoryParent.id.eq(category.parentCategory.id)) + .leftJoin(image).on(image.information.id.eq(information.id).and(image.imageStatus.eq(ImageStatus.THUMBNAIL))) + .leftJoin(bookMarkInformation).on(bookMarkInformation.information.id.eq(information.id).and(bookMarkInformation.user.id.eq(userId))) + .leftJoin(greatInformation).on(greatInformation.information.id.eq(information.id)) .where(whereClause) - .groupBy(information.id, zoneCategoryChild.id, zoneCategoryParent.id, image.id) - .orderBy(getOrderSpecifier(informationPageRequest.getSort(), information.id)) + .groupBy(information.id, information.createdDate, information.viewCount, zoneCategoryChild.name, bookMarkInformation.id, image.address) + .orderBy(getOrderSpecifiers(informationPageRequest.getSort())) .select(Projections.constructor( InformationBriefResponse.class, information.id, @@ -91,17 +94,104 @@ public Page getInformationPageFilterAndOrder(Pageable zoneCategoryChild.name, information.category.name, information.viewCount, - isInformationBookmark(userId, information.id), + isBookMarkBooleanExpression(bookMarkInformation), image.address, - countGreatInformationByInformationById(information.id), - isUserGreatInformation(userId) + countGreatInformation(greatInformation), + isGreatBooleanExpression(userId, greatInformation) )).offset(pageable.getOffset()) .limit(pageable.getPageSize()) .fetch(); - + log.info("정보 페이지 네이션 총 갯수 : " + total + "\n"); + log.info("정보 들 : "); + log.info(list.toString()); return new PageImpl<>(list, pageable, total); } + private OrderSpecifier getOrderSpecifiers(String sort) { + if (Objects.nonNull(sort)) { + if (Objects.equals(LIKE_COUNT_SORT, sort)) { + return countGreatInformation(greatInformation).desc(); + } else if (Objects.equals(VIEW_COUNT_SORT, sort)) { + return information.viewCount.desc(); + } + } + return information.createdDate.desc(); + } + + private BooleanExpression isBookMarkBooleanExpression(QBookMarkInformation bookMarkInformation) { + return new CaseBuilder() + .when(bookMarkInformation.id.isNotNull()) + .then(true) + .otherwise(false); + } + + private BooleanExpression isGreatBooleanExpression(Long userId, QGreatInformation greatInformation) { + return greatInformation.user.id.eq(userId).count().gt(0); + } + + private NumberExpression countGreatInformation(QGreatInformation greatInformation) { + return greatInformation.id.count().intValue(); + } + +// @Override +// public Page getInformationPageFilterAndOrder(Pageable pageable, +// InformationPageRequest informationPageRequest, +// Long userId, Long parentCategoryId) { +// BooleanBuilder whereClause = new BooleanBuilder(); +// +// if (Objects.nonNull(informationPageRequest.getZoneCategoryId())) { +// whereClause.and( +// information.zoneCategory.parentZoneCategory.id.eq(informationPageRequest.getZoneCategoryId())); +// } +// +// BooleanBuilder categoryCondition = new BooleanBuilder(); +// +// if (Objects.nonNull(informationPageRequest.getChildCategoryId())) { +// whereClause.and(information.category.id.eq(informationPageRequest.getChildCategoryId())); +// } else { +// categoryCondition.and(category.parentCategory.id.eq(parentCategoryId)); +// } +// +// if (Objects.nonNull(informationPageRequest.getSearch())) { +// String searchKeyword = informationPageRequest.getSearch().trim().replace(" ", ""); +// whereClause.and(information.title.trim().containsIgnoreCase(searchKeyword)); +// } +// +// +// long total = from(information) +// .where(whereClause) +// .select(information.id).fetchCount(); +// System.out.println("page 네이션 총 데이터 갯수 : " + total); +// List list = from(information) +// .join(zoneCategoryChild).on(zoneCategoryChild.id.eq(information.zoneCategory.id)) +// .leftJoin(zoneCategoryParent).on(zoneCategoryParent.id.eq(zoneCategoryChild.parentZoneCategory.id)) +// .leftJoin(image) +// .on(image.information.id.eq(information.id).and(image.imageStatus.eq(ImageStatus.THUMBNAIL))) +// .join(category).on(category.id.eq(information.category.id).and(categoryCondition)) +// .where(whereClause) +// .groupBy(information.id, zoneCategoryChild.id, zoneCategoryParent.id, image.id) +// .orderBy(getOrderSpecifier(informationPageRequest.getSort(), information.id)) +// .select(Projections.constructor( +// InformationBriefResponse.class, +// information.id, +// information.title, +// zoneCategoryParent.name, +// zoneCategoryChild.name, +// information.category.name, +// information.viewCount, +// isInformationBookmark(userId, information.id), +// image.address, +// countGreatInformationByInformationById(information.id), +// isUserGreatInformation(userId) +// )).offset(pageable.getOffset()) +// .limit(pageable.getPageSize()) +// .fetch(); +// System.out.println(list.size()); +// System.out.println(list); +// +// return new PageImpl<>(list, pageable, total); +// } + @Override public List getInformationLikeCountFromCreatedIn3(Long userId) { @@ -112,7 +202,7 @@ public List getInformationLikeCountFromCreatedIn3(Long .leftJoin(category).on(category.id.eq(information.category.id)) .where(information.createdDate.after(LocalDateTime.now().minusMonths(3))) .groupBy(information.id, zoneCategoryParent.name, zoneCategoryChild.name, image.address) - .orderBy(countGreatInformationByInformationById(information.id).desc()) + .orderBy(countGreatInformationByInformationByIdSubQuery(information.id).desc()) .select(Projections.constructor( InformationMainResponse.class, information.id, @@ -121,10 +211,10 @@ public List getInformationLikeCountFromCreatedIn3(Long zoneCategoryChild.name, category.parentCategory.name, information.viewCount, - isInformationBookmark(userId, information.id), + isInformationBookmarkSubQuery(userId, information.id), image.address, - countGreatInformationByInformationById(information.id), // 파라미터 전달 - isUserGreatInformation(userId) + countGreatInformationByInformationByIdSubQuery(information.id), // 파라미터 전달 + isUserGreatInformationSubQuery(userId) )).limit(6).fetch(); } @@ -147,17 +237,18 @@ public List getInformationRecommend(Long informationId zoneCategoryChild.name, information.category.name, information.viewCount, - isInformationBookmark(userId, information.id), + isInformationBookmarkSubQuery(userId, information.id), image.address, - countGreatInformationByInformationById(information.id), - isUserGreatInformation(userId) + countGreatInformationByInformationByIdSubQuery(information.id), + isUserGreatInformationSubQuery(userId) )) .limit(3L) .fetch(); } @Override - public Page getInformationPageByTag(Pageable pageable, Long userId, Long parentCategoryId, + public Page getInformationPageByTag(Pageable pageable, Long userId, Long + parentCategoryId, InformationPageRequest informationPageRequest, String decodedTag) { BooleanBuilder whereClause = new BooleanBuilder(); @@ -213,8 +304,8 @@ public Page getInformationPageByTag(Pageable pageable, information.viewCount, bookMarkInformation.user.id.isNotNull(), image.address, - countGreatInformationByInformationById(information.id), - isUserGreatInformation(userId) + countGreatInformationByInformationByIdSubQuery(information.id), + isUserGreatInformationSubQuery(userId) )).offset(pageable.getOffset()) .limit(pageable.getPageSize()) .fetch(); @@ -228,7 +319,7 @@ public List getInformationRank() { .leftJoin(greatInformation) .on(greatInformation.information.id.eq(information.id)) .groupBy(information.id, information.title) - .orderBy(countGreatInformationByInformationById(information.id).desc()) + .orderBy(countGreatInformationByInformationByIdSubQuery(information.id).desc()) .limit(5) .select(Projections.constructor( InformationRankResponse.class, @@ -240,7 +331,7 @@ public List getInformationRank() { private OrderSpecifier getOrderSpecifier(String sort, NumberPath informationId) { if (Objects.nonNull(sort)) { if (Objects.equals(LIKE_COUNT_SORT, sort)) { - return countGreatInformationByInformationById(informationId).desc(); + return countGreatInformationByInformationByIdSubQuery(informationId).desc(); } else if (Objects.equals(VIEW_COUNT_SORT, sort)) { return information.viewCount.desc(); } @@ -248,7 +339,7 @@ private OrderSpecifier getOrderSpecifier(String sort, NumberPath inform return information.createdDate.desc(); } - private NumberExpression countGreatInformationByInformationById(NumberPath informationId) { + private NumberExpression countGreatInformationByInformationByIdSubQuery(NumberPath informationId) { QGreatInformation greatInformationSub = QGreatInformation.greatInformation; JPQLQuery likeCountSubQuery = JPAExpressions .select(greatInformationSub.count()) @@ -260,7 +351,7 @@ private NumberExpression countGreatInformationByInformationById(NumberP .intValue(); } - private BooleanExpression isUserGreatInformation(Long userId) { + private BooleanExpression isUserGreatInformationSubQuery(Long userId) { return new CaseBuilder() .when(JPAExpressions.selectOne() .from(greatInformation) @@ -271,7 +362,7 @@ private BooleanExpression isUserGreatInformation(Long userId) { .otherwise(false); } - private BooleanExpression isInformationBookmark(Long userId, NumberPath informationId) { + private BooleanExpression isInformationBookmarkSubQuery(Long userId, NumberPath informationId) { return new CaseBuilder() .when(JPAExpressions.selectOne() .from(bookMarkInformation) From 70050e11c05529a35aac78c90f01b655fa3edc93 Mon Sep 17 00:00:00 2001 From: hyeonjaez Date: Fri, 11 Oct 2024 11:56:23 +0900 Subject: [PATCH 371/371] =?UTF-8?q?fix:=20=ED=8E=98=EC=9D=B4=EC=A7=80?= =?UTF-8?q?=EB=84=A4=EC=9D=B4=EC=85=98=20=EB=A9=94=EC=84=9C=EB=93=9C=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD=EC=9C=BC=EB=A1=9C=20=EC=9D=B8=ED=95=B4=20ser?= =?UTF-8?q?vice=EC=97=90=EC=84=9C=20=ED=98=B8=EC=B6=9C=ED=95=98=EB=8A=94?= =?UTF-8?q?=20=EB=A9=94=EC=84=9C=EB=93=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../solitour/information/service/InformationService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/solitour_backend/solitour/information/service/InformationService.java b/src/main/java/solitour_backend/solitour/information/service/InformationService.java index 8cfef9ed..f0b04eca 100644 --- a/src/main/java/solitour_backend/solitour/information/service/InformationService.java +++ b/src/main/java/solitour_backend/solitour/information/service/InformationService.java @@ -458,7 +458,7 @@ public Page getPageInformation(Pageable pageable, Long } } - return informationRepository.getInformationPageFilterAndOrder(pageable, informationPageRequest, userId, parentCategoryId); + return informationRepository.getPageInformationFilterAndOrder(pageable, informationPageRequest, userId, parentCategoryId); } public List getRankInformation() {