From 1446b98c427bbe350b82871154021104cdc42997 Mon Sep 17 00:00:00 2001 From: sanghee0820 Date: Wed, 9 Oct 2024 23:04:03 +0900 Subject: [PATCH 01/40] =?UTF-8?q?[feat]=20RequestMapping=20=EC=9C=BC?= =?UTF-8?q?=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 --- .../presentation/InfluencerController.java | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/main/java/team7/inplace/influencer/presentation/InfluencerController.java b/src/main/java/team7/inplace/influencer/presentation/InfluencerController.java index 2fe8ef00..a38778fa 100644 --- a/src/main/java/team7/inplace/influencer/presentation/InfluencerController.java +++ b/src/main/java/team7/inplace/influencer/presentation/InfluencerController.java @@ -26,12 +26,12 @@ public class InfluencerController implements InfluencerControllerApiSpec { private final InfluencerService influencerService; - @GetMapping() + @GetMapping("/influencers") public ResponseEntity getAllInfluencers() { List influencersDtoList = influencerService.getAllInfluencers(); List influencers = influencersDtoList.stream() - .map(InfluencerResponse::from) - .toList(); + .map(InfluencerResponse::from) + .toList(); InfluencerListResponse response = new InfluencerListResponse(influencers); return new ResponseEntity<>(response, HttpStatus.OK); @@ -40,9 +40,9 @@ public ResponseEntity getAllInfluencers() { @PostMapping("/influencers") public ResponseEntity createInfluencer(@RequestBody InfluencerRequest request) { InfluencerCommand influencerCommand = new InfluencerCommand( - request.influencerName(), - request.influencerImgUrl(), - request.influencerJob() + request.influencerName(), + request.influencerImgUrl(), + request.influencerJob() ); Long savedId = influencerService.createInfluencer(influencerCommand); @@ -51,11 +51,11 @@ public ResponseEntity createInfluencer(@RequestBody InfluencerRequest requ @PutMapping("/influencers/{id}") public ResponseEntity updateInfluencer(@PathVariable Long id, - @RequestBody InfluencerRequest request) { + @RequestBody InfluencerRequest request) { InfluencerCommand influencerCommand = new InfluencerCommand( - request.influencerName(), - request.influencerImgUrl(), - request.influencerJob() + request.influencerName(), + request.influencerImgUrl(), + request.influencerJob() ); Long updatedId = influencerService.updateInfluencer(id, influencerCommand); From 4cfea05d35c1ecc97513a8a69602fd988a618997 Mon Sep 17 00:00:00 2001 From: suhyeon7497 Date: Wed, 9 Oct 2024 23:10:37 +0900 Subject: [PATCH 02/40] =?UTF-8?q?[feat]=20tokenRefresh=EB=A5=BC=20?= =?UTF-8?q?=EC=A0=81=EC=9A=A9=ED=95=98=EC=98=80=EC=8A=B5=EB=8B=88=EB=8B=A4?= =?UTF-8?q?.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit redis에 refreshToken이 있으면 재발급합니다. refreshToken이 없을 경우, 잘못된 토큰 에러메세지를 반환합니다. 관련 이슈: #44 --- build.gradle | 1 + .../team7/inplace/InplaceApplication.java | 11 ++++ .../global/exception/code/UserErroCode.java | 30 ++++++++++ .../inplace/security/config/RedisConfig.java | 26 +++++++++ .../config/SecurityHandlerConfig.java | 6 +- .../handler/CustomSuccessHandler.java | 22 ++++--- .../team7/inplace/security/util/JwtUtil.java | 5 +- .../token/application/RefreshTokenFacade.java | 38 +++++++++++++ .../application/RefreshTokenService.java | 30 ++++++++++ .../token/application/dto/TokenCommand.java | 14 +++++ .../inplace/token/domain/RefreshToken.java | 19 +++++++ .../persistence/RefreshTokenRepository.java | 12 ++++ .../presentation/RefreshTokenController.java | 57 +++++++++++++++++++ .../inplace/user/application/UserService.java | 5 +- 14 files changed, 263 insertions(+), 13 deletions(-) create mode 100644 src/main/java/team7/inplace/global/exception/code/UserErroCode.java create mode 100644 src/main/java/team7/inplace/security/config/RedisConfig.java create mode 100644 src/main/java/team7/inplace/token/application/RefreshTokenFacade.java create mode 100644 src/main/java/team7/inplace/token/application/RefreshTokenService.java create mode 100644 src/main/java/team7/inplace/token/application/dto/TokenCommand.java create mode 100644 src/main/java/team7/inplace/token/domain/RefreshToken.java create mode 100644 src/main/java/team7/inplace/token/persistence/RefreshTokenRepository.java create mode 100644 src/main/java/team7/inplace/token/presentation/RefreshTokenController.java diff --git a/build.gradle b/build.gradle index 507c14a6..54c80271 100644 --- a/build.gradle +++ b/build.gradle @@ -26,6 +26,7 @@ repositories { dependencies { implementation 'org.springframework.boot:spring-boot-starter-web' implementation 'org.springframework.boot:spring-boot-starter-data-jpa' + implementation 'org.springframework.boot:spring-boot-starter-data-redis' compileOnly 'org.projectlombok:lombok' annotationProcessor 'org.projectlombok:lombok' implementation 'org.springframework.boot:spring-boot-starter-security' diff --git a/src/main/java/team7/inplace/InplaceApplication.java b/src/main/java/team7/inplace/InplaceApplication.java index 587c3c33..887c1415 100644 --- a/src/main/java/team7/inplace/InplaceApplication.java +++ b/src/main/java/team7/inplace/InplaceApplication.java @@ -3,9 +3,20 @@ import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.context.properties.ConfigurationPropertiesScan; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.FilterType; +import org.springframework.data.jpa.repository.config.EnableJpaRepositories; +import team7.inplace.token.persistence.RefreshTokenRepository; @SpringBootApplication @ConfigurationPropertiesScan +@EnableJpaRepositories( + basePackages = "team7.inplace", + excludeFilters = @ComponentScan.Filter( + type = FilterType.ASSIGNABLE_TYPE, + classes = {RefreshTokenRepository.class} + ) +) public class InplaceApplication { public static void main(String[] args) { diff --git a/src/main/java/team7/inplace/global/exception/code/UserErroCode.java b/src/main/java/team7/inplace/global/exception/code/UserErroCode.java new file mode 100644 index 00000000..f2efcfd4 --- /dev/null +++ b/src/main/java/team7/inplace/global/exception/code/UserErroCode.java @@ -0,0 +1,30 @@ +package team7.inplace.global.exception.code; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import org.springframework.http.HttpStatus; + +@AllArgsConstructor +@Getter +public enum UserErroCode implements ErrorCode { + NOT_FOUND(HttpStatus.NOT_FOUND, "U001", "User is not found"); + + private final HttpStatus status; + private final String code; + private final String message; + + @Override + public HttpStatus httpStatus() { + return null; + } + + @Override + public String code() { + return ""; + } + + @Override + public String message() { + return ""; + } +} diff --git a/src/main/java/team7/inplace/security/config/RedisConfig.java b/src/main/java/team7/inplace/security/config/RedisConfig.java new file mode 100644 index 00000000..425cbcae --- /dev/null +++ b/src/main/java/team7/inplace/security/config/RedisConfig.java @@ -0,0 +1,26 @@ +package team7.inplace.security.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.redis.connection.RedisStandaloneConfiguration; +import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.data.redis.serializer.StringRedisSerializer; + +@Configuration +public class RedisConfig { + + @Bean + LettuceConnectionFactory redisConnectionFactory() { + return new LettuceConnectionFactory(new RedisStandaloneConfiguration("localhost", 6379)); + } + + @Bean + public RedisTemplate redisTemplate() { + RedisTemplate template = new RedisTemplate<>(); + template.setConnectionFactory(redisConnectionFactory()); + template.setKeySerializer(new StringRedisSerializer()); + template.setValueSerializer(new StringRedisSerializer()); + return template; + } +} diff --git a/src/main/java/team7/inplace/security/config/SecurityHandlerConfig.java b/src/main/java/team7/inplace/security/config/SecurityHandlerConfig.java index 6a638218..b8ab828e 100644 --- a/src/main/java/team7/inplace/security/config/SecurityHandlerConfig.java +++ b/src/main/java/team7/inplace/security/config/SecurityHandlerConfig.java @@ -4,6 +4,7 @@ import org.springframework.context.annotation.Configuration; import team7.inplace.security.handler.CustomSuccessHandler; import team7.inplace.security.util.JwtUtil; +import team7.inplace.token.application.RefreshTokenService; import team7.inplace.user.application.UserService; @Configuration @@ -12,8 +13,9 @@ public class SecurityHandlerConfig { @Bean public CustomSuccessHandler customSuccessHandler( JwtUtil jwtUtil, - UserService userService + UserService userService, + RefreshTokenService refreshTokenService ) { - return new CustomSuccessHandler(jwtUtil, userService); + return new CustomSuccessHandler(jwtUtil, userService, refreshTokenService); } } diff --git a/src/main/java/team7/inplace/security/handler/CustomSuccessHandler.java b/src/main/java/team7/inplace/security/handler/CustomSuccessHandler.java index b2e2f4e4..37276d49 100644 --- a/src/main/java/team7/inplace/security/handler/CustomSuccessHandler.java +++ b/src/main/java/team7/inplace/security/handler/CustomSuccessHandler.java @@ -8,6 +8,7 @@ import org.springframework.security.web.authentication.AuthenticationSuccessHandler; import team7.inplace.security.application.dto.CustomOAuth2User; import team7.inplace.security.util.JwtUtil; +import team7.inplace.token.application.RefreshTokenService; import team7.inplace.user.application.UserService; import team7.inplace.user.application.dto.UserCommand; @@ -15,13 +16,15 @@ public class CustomSuccessHandler implements AuthenticationSuccessHandler { private final JwtUtil jwtUtil; private final UserService userService; + private final RefreshTokenService refreshTokenService; public CustomSuccessHandler( JwtUtil jwtUtil, - UserService userService + UserService userService, RefreshTokenService refreshTokenService ) { this.jwtUtil = jwtUtil; this.userService = userService; + this.refreshTokenService = refreshTokenService; } @Override @@ -31,19 +34,22 @@ public void onAuthenticationSuccess( Authentication authentication ) throws IOException { CustomOAuth2User customOAuth2User = (CustomOAuth2User) authentication.getPrincipal(); - addTokenToResponse(response, customOAuth2User); + UserCommand.Info userInfo = userService.getUserByUsername(customOAuth2User.username()); + String accessToken = jwtUtil.createAccessToken(userInfo.username(), userInfo.id(), + userInfo.role().getRoles()); + String refreshToken = jwtUtil.createRefreshToken(userInfo.username(), userInfo.id(), + userInfo.role().getRoles()); + refreshTokenService.saveRefreshToken(userInfo.username(), refreshToken); + addTokenToResponse(response, accessToken, refreshToken); setRedirectUrlToResponse(response, customOAuth2User); } private void addTokenToResponse( HttpServletResponse response, - CustomOAuth2User customOAuth2User + String accessToken, String refreshToken ) { - UserCommand.Info user = userService.getUserByUsername(customOAuth2User.username()); - Cookie accessTokenCookie = createCookie("access_token", - jwtUtil.createAccessToken(user.username(), user.id(), user.role().getRoles())); - Cookie refreshTokenCookie = createCookie("refresh_token", - jwtUtil.createRefreshToken(user.username(), user.id(), user.role().getRoles())); + Cookie accessTokenCookie = createCookie("access_token", accessToken); + Cookie refreshTokenCookie = createCookie("refresh_token", refreshToken); response.addCookie(accessTokenCookie); response.addCookie(refreshTokenCookie); diff --git a/src/main/java/team7/inplace/security/util/JwtUtil.java b/src/main/java/team7/inplace/security/util/JwtUtil.java index e653cbca..3adb4266 100644 --- a/src/main/java/team7/inplace/security/util/JwtUtil.java +++ b/src/main/java/team7/inplace/security/util/JwtUtil.java @@ -57,9 +57,10 @@ public String getUsername(String token) throws InplaceException { } } - public String getTokenType(String token) throws InplaceException { + public boolean isRefreshToken(String token) throws InplaceException { try { - return jwtParser.parseSignedClaims(token).getPayload().get("tokenType", String.class); + return jwtParser.parseSignedClaims(token).getPayload().get("tokenType", String.class) + .equals("refreshToken"); } catch (JwtException | IllegalArgumentException e) { throw InplaceException.of(AuthorizationErrorCode.INVALID_TOKEN); } diff --git a/src/main/java/team7/inplace/token/application/RefreshTokenFacade.java b/src/main/java/team7/inplace/token/application/RefreshTokenFacade.java new file mode 100644 index 00000000..6f2e8796 --- /dev/null +++ b/src/main/java/team7/inplace/token/application/RefreshTokenFacade.java @@ -0,0 +1,38 @@ +package team7.inplace.token.application; + +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Component; +import org.springframework.transaction.annotation.Transactional; +import team7.inplace.global.exception.InplaceException; +import team7.inplace.global.exception.code.AuthorizationErrorCode; +import team7.inplace.security.util.JwtUtil; +import team7.inplace.token.application.dto.TokenCommand; +import team7.inplace.token.application.dto.TokenCommand.ReIssued; +import team7.inplace.user.application.UserService; +import team7.inplace.user.application.dto.UserCommand; + +@Component +@RequiredArgsConstructor +public class RefreshTokenFacade { + + private final JwtUtil jwtUtil; + private final RefreshTokenService refreshTokenService; + private final UserService userService; + + @Transactional + public ReIssued getReIssuedRefreshTokenCookie(String username, String refreshToken) + throws InplaceException { + if (refreshTokenService.isInvalidRefreshToken(refreshToken)) { + throw InplaceException.of(AuthorizationErrorCode.INVALID_TOKEN); + } + + UserCommand.Info userInfo = userService.getUserByUsername(username); + String reIssuedRefreshToken = jwtUtil + .createRefreshToken(userInfo.username(), userInfo.id(), userInfo.role().getRoles()); + String reIssuedAccessToken = jwtUtil + .createAccessToken(userInfo.username(), userInfo.id(), userInfo.role().getRoles()); + refreshTokenService.saveRefreshToken(username, reIssuedRefreshToken); + + return TokenCommand.ReIssued.of(reIssuedRefreshToken, reIssuedAccessToken); + } +} diff --git a/src/main/java/team7/inplace/token/application/RefreshTokenService.java b/src/main/java/team7/inplace/token/application/RefreshTokenService.java new file mode 100644 index 00000000..9c7a452e --- /dev/null +++ b/src/main/java/team7/inplace/token/application/RefreshTokenService.java @@ -0,0 +1,30 @@ +package team7.inplace.token.application; + +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import team7.inplace.global.exception.InplaceException; +import team7.inplace.global.exception.code.AuthorizationErrorCode; +import team7.inplace.security.util.JwtUtil; +import team7.inplace.token.domain.RefreshToken; +import team7.inplace.token.persistence.RefreshTokenRepository; + +@Service +@RequiredArgsConstructor +public class RefreshTokenService { + + private final RefreshTokenRepository refreshTokenRepository; + private final JwtUtil jwtUtil; + + public boolean isInvalidRefreshToken(String refreshToken) throws InplaceException { + String username = jwtUtil.getUsername(refreshToken); + return !refreshTokenRepository.findById(username).orElseThrow(() -> + InplaceException.of(AuthorizationErrorCode.INVALID_TOKEN)) + .getRefreshToken().equals(refreshToken); + } + + public void saveRefreshToken(String username, String token) { + RefreshToken refreshToken = new RefreshToken(username, token); + refreshTokenRepository.save(refreshToken); + } + +} diff --git a/src/main/java/team7/inplace/token/application/dto/TokenCommand.java b/src/main/java/team7/inplace/token/application/dto/TokenCommand.java new file mode 100644 index 00000000..8e33cba9 --- /dev/null +++ b/src/main/java/team7/inplace/token/application/dto/TokenCommand.java @@ -0,0 +1,14 @@ +package team7.inplace.token.application.dto; + +public class TokenCommand { + + public record ReIssued( + String accessToken, + String refreshToken + ) { + + public static ReIssued of(String reIssuedRefreshToken, String reIssuedAccessToken) { + return new ReIssued(reIssuedRefreshToken, reIssuedAccessToken); + } + } +} diff --git a/src/main/java/team7/inplace/token/domain/RefreshToken.java b/src/main/java/team7/inplace/token/domain/RefreshToken.java new file mode 100644 index 00000000..1828a10c --- /dev/null +++ b/src/main/java/team7/inplace/token/domain/RefreshToken.java @@ -0,0 +1,19 @@ +package team7.inplace.token.domain; + +import lombok.AccessLevel; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import org.springframework.data.annotation.Id; +import org.springframework.data.redis.core.RedisHash; + +@Getter +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@AllArgsConstructor +@RedisHash(value = "refreshToken", timeToLive = 60 * 60 * 1000L) +public class RefreshToken { + + @Id + private String username; + private String refreshToken; +} diff --git a/src/main/java/team7/inplace/token/persistence/RefreshTokenRepository.java b/src/main/java/team7/inplace/token/persistence/RefreshTokenRepository.java new file mode 100644 index 00000000..870aceb8 --- /dev/null +++ b/src/main/java/team7/inplace/token/persistence/RefreshTokenRepository.java @@ -0,0 +1,12 @@ +package team7.inplace.token.persistence; + +import java.util.Optional; +import org.springframework.data.repository.CrudRepository; +import org.springframework.stereotype.Repository; +import team7.inplace.token.domain.RefreshToken; + +@Repository +public interface RefreshTokenRepository extends CrudRepository { + + Optional findById(String id); +} diff --git a/src/main/java/team7/inplace/token/presentation/RefreshTokenController.java b/src/main/java/team7/inplace/token/presentation/RefreshTokenController.java new file mode 100644 index 00000000..27a9c7a1 --- /dev/null +++ b/src/main/java/team7/inplace/token/presentation/RefreshTokenController.java @@ -0,0 +1,57 @@ +package team7.inplace.token.presentation; + +import jakarta.servlet.http.Cookie; +import jakarta.servlet.http.HttpServletResponse; +import lombok.RequiredArgsConstructor; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.CookieValue; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; +import team7.inplace.global.exception.InplaceException; +import team7.inplace.global.exception.code.AuthorizationErrorCode; +import team7.inplace.security.util.AuthorizationUtil; +import team7.inplace.security.util.JwtUtil; +import team7.inplace.token.application.RefreshTokenFacade; +import team7.inplace.token.application.dto.TokenCommand.ReIssued; + +@RestController +@RequiredArgsConstructor +public class RefreshTokenController { + + private final JwtUtil jwtUtil; + private final RefreshTokenFacade refreshTokenFacade; + + @GetMapping("/refresh-token") + public ResponseEntity refreshToken(@CookieValue(value = "Authorization") Cookie cookie, + HttpServletResponse response) { + if (cannotRefreshToken(cookie)) { + throw InplaceException.of(AuthorizationErrorCode.INVALID_TOKEN); + } + + String refreshToken = cookie.getValue(); + ReIssued reIssuedToken = refreshTokenFacade.getReIssuedRefreshTokenCookie( + jwtUtil.getUsername(refreshToken), refreshToken); + addTokenToCookie(response, reIssuedToken); + + return ResponseEntity.ok().build(); + } + + private void addTokenToCookie(HttpServletResponse response, ReIssued reIssuedToken) { + Cookie accessTokenCookie = createCookie("access_token", reIssuedToken.accessToken()); + Cookie refreshTokenCookie = createCookie("refresh_token", reIssuedToken.refreshToken()); + response.addCookie(accessTokenCookie); + response.addCookie(refreshTokenCookie); + } + + private boolean cannotRefreshToken(Cookie cookie) { + return AuthorizationUtil.getUserId() == null || !jwtUtil.isRefreshToken(cookie.getValue()); + } + + private Cookie createCookie(String key, String value) { + Cookie cookie = new Cookie(key, value); + cookie.setMaxAge(60 * 60); + cookie.setPath("/"); + cookie.setHttpOnly(true); + return cookie; + } +} diff --git a/src/main/java/team7/inplace/user/application/UserService.java b/src/main/java/team7/inplace/user/application/UserService.java index 8edf6daf..6ed8ff75 100644 --- a/src/main/java/team7/inplace/user/application/UserService.java +++ b/src/main/java/team7/inplace/user/application/UserService.java @@ -2,6 +2,8 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import team7.inplace.global.exception.InplaceException; +import team7.inplace.global.exception.code.UserErroCode; import team7.inplace.user.application.dto.UserCommand; import team7.inplace.user.domain.User; import team7.inplace.user.persistence.UserRepository; @@ -28,6 +30,7 @@ public boolean isExistUser(String username) { @Transactional(readOnly = true) public UserCommand.Info getUserByUsername(String username) { - return UserCommand.Info.of(userRepository.findByUsername(username).orElseThrow()); + return UserCommand.Info.of(userRepository.findByUsername(username) + .orElseThrow(() -> InplaceException.of(UserErroCode.NOT_FOUND))); } } From 0d8f59cb49773695d1345560cb645dc103895219 Mon Sep 17 00:00:00 2001 From: sanghee0820 Date: Wed, 9 Oct 2024 23:10:38 +0900 Subject: [PATCH 03/40] =?UTF-8?q?[feat]=20RequestMapping=20=EC=9C=BC?= =?UTF-8?q?=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 --- .../influencer/presentation/InfluencerController.java | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/main/java/team7/inplace/influencer/presentation/InfluencerController.java b/src/main/java/team7/inplace/influencer/presentation/InfluencerController.java index a38778fa..bcd4a545 100644 --- a/src/main/java/team7/inplace/influencer/presentation/InfluencerController.java +++ b/src/main/java/team7/inplace/influencer/presentation/InfluencerController.java @@ -11,6 +11,7 @@ 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 team7.inplace.influencer.application.InfluencerService; import team7.inplace.influencer.application.dto.InfluencerCommand; @@ -22,11 +23,12 @@ @RequiredArgsConstructor @RestController +@RequestMapping("/influencers") public class InfluencerController implements InfluencerControllerApiSpec { private final InfluencerService influencerService; - @GetMapping("/influencers") + @GetMapping() public ResponseEntity getAllInfluencers() { List influencersDtoList = influencerService.getAllInfluencers(); List influencers = influencersDtoList.stream() @@ -37,7 +39,7 @@ public ResponseEntity getAllInfluencers() { return new ResponseEntity<>(response, HttpStatus.OK); } - @PostMapping("/influencers") + @PostMapping() public ResponseEntity createInfluencer(@RequestBody InfluencerRequest request) { InfluencerCommand influencerCommand = new InfluencerCommand( request.influencerName(), @@ -49,7 +51,7 @@ public ResponseEntity createInfluencer(@RequestBody InfluencerRequest requ return new ResponseEntity<>(savedId, HttpStatus.OK); } - @PutMapping("/influencers/{id}") + @PutMapping("/{id}") public ResponseEntity updateInfluencer(@PathVariable Long id, @RequestBody InfluencerRequest request) { InfluencerCommand influencerCommand = new InfluencerCommand( @@ -62,7 +64,7 @@ public ResponseEntity updateInfluencer(@PathVariable Long id, return new ResponseEntity<>(updatedId, HttpStatus.OK); } - @DeleteMapping("/influencers/{id}") + @DeleteMapping("/{id}") public ResponseEntity deleteInfluencer(@PathVariable Long id) { influencerService.deleteInfluencer(id); From b048c2e1a0bca640cba74faba3713bef26be19a2 Mon Sep 17 00:00:00 2001 From: sanghee0820 Date: Thu, 10 Oct 2024 10:19:14 +0900 Subject: [PATCH 04/40] =?UTF-8?q?[fix]=20=EC=A3=BC=EC=86=8C=EB=A5=BC=20?= =?UTF-8?q?=ED=8C=8C=EC=8B=B1=ED=95=A0=20=EB=95=8C=20=EB=84=88=EB=AC=B4=20?= =?UTF-8?q?=EC=84=B8=EB=B6=80=20=EC=A0=95=EB=B3=B4=EB=A5=BC=20=EB=B0=98?= =?UTF-8?q?=EC=98=81=ED=95=98=EC=A7=80=20=EC=95=8A=EB=8F=84=EB=A1=9D=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 --- .../java/team7/inplace/crawling/application/AddressUtil.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/team7/inplace/crawling/application/AddressUtil.java b/src/main/java/team7/inplace/crawling/application/AddressUtil.java index 5ebd55cb..ad241ebd 100644 --- a/src/main/java/team7/inplace/crawling/application/AddressUtil.java +++ b/src/main/java/team7/inplace/crawling/application/AddressUtil.java @@ -9,7 +9,7 @@ @NoArgsConstructor(access = PRIVATE) public class AddressUtil { - private static final String ADDRESS_REGEX = "[가-힣0-9]+(?:도|시|구|군|읍|면|동|리|로|길)[^#,\\n()]+(?:동|읍|면|리|로|길|호|층|번지)[^#,\\n()]+"; + private static final String ADDRESS_REGEX = "[가-힣0-9]+(?:도|시|구|군|읍|면|동|리|로|길)[^#,\\n()]+(?:동|읍|면|리|로|길)[^#]?"; public static String extractAddress(JsonNode snippet) { From 644aa69c95292add6665c702f1ee3fc64bfe49b7 Mon Sep 17 00:00:00 2001 From: sanghee0820 Date: Thu, 10 Oct 2024 11:01:39 +0900 Subject: [PATCH 05/40] =?UTF-8?q?[fix]=20=EB=A9=94=EB=89=B4=20=EA=B0=80?= =?UTF-8?q?=EA=B2=A9=20=ED=8C=8C=EC=8B=B1=20=EC=95=88=EB=90=98=EB=8A=94=20?= =?UTF-8?q?=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 --- src/main/java/team7/inplace/place/domain/Menu.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/main/java/team7/inplace/place/domain/Menu.java b/src/main/java/team7/inplace/place/domain/Menu.java index 316d6e1c..cd236c03 100644 --- a/src/main/java/team7/inplace/place/domain/Menu.java +++ b/src/main/java/team7/inplace/place/domain/Menu.java @@ -24,7 +24,7 @@ public class Menu { @Column(length = 50) private String menuImgUrl; - + private Menu(Long price, boolean recommend, String menuName) { this.price = price; this.recommend = recommend; @@ -33,7 +33,8 @@ private Menu(Long price, boolean recommend, String menuName) { public static Menu of(String menu) { String[] menus = menu.split("\\|"); - - return new Menu(Long.parseLong(menus[1]), Boolean.parseBoolean(menus[2]), menus[0]); + var price = menus[1].replace(",", ""); + return new Menu(Long.valueOf(price), Boolean.parseBoolean(menus[2]), menus[0]); } + } From 190ebe92b67bd3a0450410012adac2c52ffbddcd Mon Sep 17 00:00:00 2001 From: sanghee0820 Date: Thu, 10 Oct 2024 11:02:05 +0900 Subject: [PATCH 06/40] =?UTF-8?q?[fix]=20=EC=B9=B4=ED=85=8C=EA=B3=A0?= =?UTF-8?q?=EB=A6=AC=EA=B0=80=20db=EC=97=90=20=EC=A7=80=EC=A0=95=EB=90=98?= =?UTF-8?q?=EC=A7=80=20=EC=95=8A=EC=95=98=EC=9D=84=20=EA=B2=BD=EC=9A=B0=20?= =?UTF-8?q?NONE=20=EB=B0=98=ED=99=98=20=ED=95=98=EB=8F=84=EB=A1=9D=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 --- .../team7/inplace/place/domain/Category.java | 26 ++++++++++++++++--- .../team7/inplace/place/domain/Place.java | 2 +- 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/src/main/java/team7/inplace/place/domain/Category.java b/src/main/java/team7/inplace/place/domain/Category.java index 974d1ea7..8469478e 100644 --- a/src/main/java/team7/inplace/place/domain/Category.java +++ b/src/main/java/team7/inplace/place/domain/Category.java @@ -1,8 +1,26 @@ package team7.inplace.place.domain; +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +@Getter +@RequiredArgsConstructor public enum Category { - CAFE, - WESTERN, - JAPANESE, - KOREAN + CAFE("카페"), + WESTERN("양식"), + JAPANESE("일식"), + KOREAN("한식"), + RESTAURANT("음식점"), + NONE("없음"); + + private final String name; + + public static Category of(String name) { + for (Category category : values()) { + if (category.name.equals(name)) { + return category; + } + } + return NONE; + } } diff --git a/src/main/java/team7/inplace/place/domain/Place.java b/src/main/java/team7/inplace/place/domain/Place.java index daa09bdc..1a74c1fa 100644 --- a/src/main/java/team7/inplace/place/domain/Place.java +++ b/src/main/java/team7/inplace/place/domain/Place.java @@ -64,7 +64,7 @@ public Place(String name, String facility, String menuImgsUrl, String category, this.name = name; this.facility = facility; this.menuImgUrl = menuImgsUrl; - this.category = Category.valueOf(category); + this.category = Category.of(category); this.address = Address.of(address); this.coordinate = Coordinate.of(x, y); this.offDays = offDays.stream() From a1355a6091cd7cf38062798d34cda05f34993ff0 Mon Sep 17 00:00:00 2001 From: sanghee0820 Date: Thu, 10 Oct 2024 11:02:24 +0900 Subject: [PATCH 07/40] =?UTF-8?q?[fix]=20=EC=A3=BC=EC=86=8C=20=ED=8C=8C?= =?UTF-8?q?=EC=8B=B1=20=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 --- src/main/java/team7/inplace/place/domain/Address.java | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/main/java/team7/inplace/place/domain/Address.java b/src/main/java/team7/inplace/place/domain/Address.java index 4482278c..4775adab 100644 --- a/src/main/java/team7/inplace/place/domain/Address.java +++ b/src/main/java/team7/inplace/place/domain/Address.java @@ -4,6 +4,7 @@ import jakarta.persistence.Column; import jakarta.persistence.Embeddable; +import java.util.Arrays; import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.NoArgsConstructor; @@ -29,7 +30,11 @@ private Address(String address1, String address2, String address3) { } public static Address of(String address) { - String[] split = address.split("\\|"); - return new Address(split[0], split[1], split[2]); + System.out.println("address: " + address); + String[] split = address.split(" "); + var address1 = split[0]; + var address2 = split[1]; + var address3 = String.join(" ", Arrays.copyOfRange(split, 2, split.length)); + return new Address(address1, address2, address3); } } From eab5c3a47b9d943fe63ada87577a0744dbb844f1 Mon Sep 17 00:00:00 2001 From: sanghee0820 Date: Thu, 10 Oct 2024 11:02:59 +0900 Subject: [PATCH 08/40] =?UTF-8?q?[fix]=20place=EC=97=90=EC=84=9C=20?= =?UTF-8?q?=EC=B9=B4=ED=85=8C=EA=B3=A0=EB=A6=AC=EB=A5=BC=20=EB=B0=98?= =?UTF-8?q?=ED=99=98=ED=95=98=EB=8A=94=20=ED=95=84=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 --- .../inplace/place/application/command/PlacesCommand.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/team7/inplace/place/application/command/PlacesCommand.java b/src/main/java/team7/inplace/place/application/command/PlacesCommand.java index 376f2351..13e1fd50 100644 --- a/src/main/java/team7/inplace/place/application/command/PlacesCommand.java +++ b/src/main/java/team7/inplace/place/application/command/PlacesCommand.java @@ -74,8 +74,8 @@ public static Create from(JsonNode locationNode, JsonNode placeNode) { ? basicInfo.get("facilityInfo").toString() : "N/A"; String menuImgUrl = basicInfo.has("mainphotourl") ? basicInfo.get("mainphotourl").asText() : ""; - String category = basicInfo.has("category") && basicInfo.get("category").has("catename") - ? basicInfo.get("category").get("catename").asText() : "Unknown Category"; + String category = basicInfo.has("category") && basicInfo.get("category").has("cate1name") + ? basicInfo.get("category").get("cate1name").asText() : "Unknown Category"; String address = basicInfo.has("address") && basicInfo.get("address").has("region") && basicInfo.get("address") .get("region").has("newaddrfullname") From 2f3144a2b5d5cc3c2783b16cb1b293f616f03a0c Mon Sep 17 00:00:00 2001 From: sanghee0820 Date: Thu, 10 Oct 2024 11:03:26 +0900 Subject: [PATCH 09/40] =?UTF-8?q?[feat]=20=EC=B9=B4=ED=85=8C=EA=B3=A0?= =?UTF-8?q?=EB=A6=AC=20=EC=B6=94=EA=B0=80=EB=A1=9C=20=EC=9D=B8=ED=95=9C=20?= =?UTF-8?q?=EC=B2=98=EB=A6=AC=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 --- .../team7/inplace/video/application/AliasUtil.java | 4 +++- .../team7/inplace/video/application/Template.java | 11 +++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/main/java/team7/inplace/video/application/AliasUtil.java b/src/main/java/team7/inplace/video/application/AliasUtil.java index 02107fa5..679e8017 100644 --- a/src/main/java/team7/inplace/video/application/AliasUtil.java +++ b/src/main/java/team7/inplace/video/application/AliasUtil.java @@ -6,7 +6,7 @@ @RequiredArgsConstructor(access = AccessLevel.PRIVATE) public final class AliasUtil { - public static String makeAlias(String influencerName, Category category){ + public static String makeAlias(String influencerName, Category category) { String alias = mapTemplateToCategory(category); return influencerName + " " + alias; } @@ -18,6 +18,8 @@ private static String mapTemplateToCategory(Category category) { case WESTERN -> Template.WESTERN.getRandomTemplate(); case JAPANESE -> Template.JAPANESE.getRandomTemplate(); case KOREAN -> Template.KOREAN.getRandomTemplate(); + case RESTAURANT -> Template.RESTAURANT.getRandomTemplate(); + default -> Template.NONE.getRandomTemplate(); }; } } diff --git a/src/main/java/team7/inplace/video/application/Template.java b/src/main/java/team7/inplace/video/application/Template.java index b1f2a0d5..aa9da0a4 100644 --- a/src/main/java/team7/inplace/video/application/Template.java +++ b/src/main/java/team7/inplace/video/application/Template.java @@ -30,6 +30,17 @@ public enum Template { "이(가) 전통 한식을 맛볼 수 있는 한식당입니다.", "이(가) 추천하는 가게에서 정성스럽게 준비된 한식으로 든든한 한 끼를!", "이(가) 극찬! 한식의 깊은 맛을 느껴보세요." + }), + + // 기본 템플릿 + RESTAURANT(new String[]{ + "이(가) 추천하는 맛집! 다양한 메뉴를 즐길 수 있습니다.", + "이(가) 방문한 식당에서 맛있는 음식을 즐겨보세요!", + "이(가) 추천하는 맛집에서 특별한 시간을 보내보세요!" + }), + + NONE(new String[]{ + "" }); // 템플릿 배열을 반환하는 메서드 From c248610160611c76e208c6e5780a81e5994c7f4f Mon Sep 17 00:00:00 2001 From: sanghee0820 Date: Thu, 10 Oct 2024 11:44:11 +0900 Subject: [PATCH 10/40] =?UTF-8?q?[fix]=20placeNode=EA=B0=80=20null?= =?UTF-8?q?=EC=9D=BC=20=EA=B2=BD=EC=9A=B0,=20null=EC=9D=84=20=EB=B0=98?= =?UTF-8?q?=ED=99=98=ED=95=98=EB=8F=84=EB=A1=9D=20=EC=84=A4=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../inplace/crawling/application/dto/CrawlingInfo.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/main/java/team7/inplace/crawling/application/dto/CrawlingInfo.java b/src/main/java/team7/inplace/crawling/application/dto/CrawlingInfo.java index 7ed84962..0bf0a33f 100644 --- a/src/main/java/team7/inplace/crawling/application/dto/CrawlingInfo.java +++ b/src/main/java/team7/inplace/crawling/application/dto/CrawlingInfo.java @@ -2,6 +2,7 @@ import com.fasterxml.jackson.databind.JsonNode; import java.util.List; +import java.util.Objects; import team7.inplace.crawling.client.dto.PlaceNode; import team7.inplace.place.application.command.PlacesCommand; import team7.inplace.video.application.command.VideoCommand; @@ -19,7 +20,12 @@ public List toVideoCommands() { public List toPlacesCommands() { return placeNodes.stream() - .map(placeNode -> PlacesCommand.Create.from(placeNode.locationNode(), placeNode.placeNode())) + .map(placeNode -> { + if (Objects.isNull(placeNode)) { + return null; + } + return PlacesCommand.Create.from(placeNode.locationNode(), placeNode.placeNode()); + }) .toList(); } } From 72e97368b98c7627cadb1afa7516283063ebc300 Mon Sep 17 00:00:00 2001 From: sanghee0820 Date: Thu, 10 Oct 2024 11:50:12 +0900 Subject: [PATCH 11/40] =?UTF-8?q?[fix]=20document=EA=B0=80=20=EC=9E=88?= =?UTF-8?q?=EC=A7=80=EB=A7=8C,=20=EC=A0=95=EB=B3=B4=EA=B0=80=20=EC=97=86?= =?UTF-8?q?=EB=8A=94=20=EA=B2=BD=EC=9A=B0=20=EC=A0=9C=EC=99=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/team7/inplace/crawling/client/KakaoMapClient.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/team7/inplace/crawling/client/KakaoMapClient.java b/src/main/java/team7/inplace/crawling/client/KakaoMapClient.java index b56fc71f..d7446d89 100644 --- a/src/main/java/team7/inplace/crawling/client/KakaoMapClient.java +++ b/src/main/java/team7/inplace/crawling/client/KakaoMapClient.java @@ -24,8 +24,9 @@ public class KakaoMapClient { private final RestTemplate restTemplate; public PlaceNode search(String address, String category) { + log.info("KakaoMapClient search address: {}, category: {}", address, category); var locationInfo = getLocateInfo(address, category); - var placeId = locationInfo.has("documents") ? + var placeId = locationInfo.has("documents") && locationInfo.get("documents").hasNonNull(1) ? locationInfo.get("documents").get(0).get("id").asText() : null; if (Objects.isNull(placeId)) { return null; From c34720a9e16c0338faa6be996ea17db6ed568243 Mon Sep 17 00:00:00 2001 From: sanghee0820 Date: Thu, 10 Oct 2024 11:50:40 +0900 Subject: [PATCH 12/40] =?UTF-8?q?[feat]=20price=20=EC=A0=95=EB=B3=B4?= =?UTF-8?q?=EA=B0=80=20=EB=8B=A4=EC=96=91=ED=95=B4=20String=ED=98=95?= =?UTF-8?q?=EC=9C=BC=EB=A1=9C=20=EC=A0=80=EC=9E=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/team7/inplace/place/domain/Menu.java | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/main/java/team7/inplace/place/domain/Menu.java b/src/main/java/team7/inplace/place/domain/Menu.java index cd236c03..f23bfb8f 100644 --- a/src/main/java/team7/inplace/place/domain/Menu.java +++ b/src/main/java/team7/inplace/place/domain/Menu.java @@ -13,7 +13,7 @@ @EqualsAndHashCode @NoArgsConstructor(access = AccessLevel.PROTECTED) public class Menu { - private Long price; + private String price; @ColumnDefault("false") @Column(nullable = false) @@ -25,7 +25,7 @@ public class Menu { @Column(length = 50) private String menuImgUrl; - private Menu(Long price, boolean recommend, String menuName) { + private Menu(String price, boolean recommend, String menuName) { this.price = price; this.recommend = recommend; this.menuName = menuName; @@ -33,8 +33,7 @@ private Menu(Long price, boolean recommend, String menuName) { public static Menu of(String menu) { String[] menus = menu.split("\\|"); - var price = menus[1].replace(",", ""); - return new Menu(Long.valueOf(price), Boolean.parseBoolean(menus[2]), menus[0]); + return new Menu(menus[1], Boolean.parseBoolean(menus[2]), menus[0]); } } From 81410ce5a40a0cfa1bff0028143beb997f4a46cd Mon Sep 17 00:00:00 2001 From: suhyeon7497 Date: Thu, 10 Oct 2024 19:22:17 +0900 Subject: [PATCH 13/40] [feat] cors setting MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit cors setting 관련이슈 : #44 --- .../inplace/security/config/CorsConfig.java | 17 ++++++++++ .../inplace/security/config/CorsTest.java | 32 +++++++++++++++++++ .../inplace/security/util/JwtUtilTest.java | 2 -- 3 files changed, 49 insertions(+), 2 deletions(-) create mode 100644 src/main/java/team7/inplace/security/config/CorsConfig.java create mode 100644 src/test/java/team7/inplace/security/config/CorsTest.java diff --git a/src/main/java/team7/inplace/security/config/CorsConfig.java b/src/main/java/team7/inplace/security/config/CorsConfig.java new file mode 100644 index 00000000..98fbc3ef --- /dev/null +++ b/src/main/java/team7/inplace/security/config/CorsConfig.java @@ -0,0 +1,17 @@ +package team7.inplace.security.config; + +import org.springframework.context.annotation.Configuration; +import org.springframework.web.servlet.config.annotation.CorsRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +@Configuration +public class CorsConfig implements WebMvcConfigurer { + + @Override + public void addCorsMappings(CorsRegistry registry) { + registry.addMapping("/**") + .allowedOriginPatterns("*") + .allowedMethods("GET", "POST", "PUT", "DELETE") + .allowCredentials(true); + } +} diff --git a/src/test/java/team7/inplace/security/config/CorsTest.java b/src/test/java/team7/inplace/security/config/CorsTest.java new file mode 100644 index 00000000..a4741e60 --- /dev/null +++ b/src/test/java/team7/inplace/security/config/CorsTest.java @@ -0,0 +1,32 @@ +package team7.inplace.security.config; + +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.options; +import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.http.HttpHeaders; +import org.springframework.test.web.servlet.MockMvc; + +@SpringBootTest +@AutoConfigureMockMvc +class CorsTest { + + @Autowired + private MockMvc mockMvc; + + @Test + void cors() throws Exception { + mockMvc.perform( + options("/login") + .header(HttpHeaders.ORIGIN, "http://localhost:1234") + .header(HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD, "GET") + .header(HttpHeaders.ACCESS_CONTROL_ALLOW_CREDENTIALS, "true") + ) + .andExpect(status().isOk()) + .andDo(print()); + } +} diff --git a/src/test/java/team7/inplace/security/util/JwtUtilTest.java b/src/test/java/team7/inplace/security/util/JwtUtilTest.java index effb509a..9e8cd2f5 100644 --- a/src/test/java/team7/inplace/security/util/JwtUtilTest.java +++ b/src/test/java/team7/inplace/security/util/JwtUtilTest.java @@ -55,11 +55,9 @@ void getInfoTests() { assertAll( () -> assertThat(jwtUtil.getUsername(accessToken)).isEqualTo(username), () -> assertThat(jwtUtil.getId(accessToken)).isEqualTo(userId), - () -> assertThat(jwtUtil.getTokenType(accessToken)).isEqualTo("accessToken"), () -> assertThat(jwtUtil.getRoles(accessToken)).isEqualTo(Role.USER.getRoles()), () -> assertThat(jwtUtil.getUsername(refreshToken)).isEqualTo(username), () -> assertThat(jwtUtil.getId(refreshToken)).isEqualTo(userId), - () -> assertThat(jwtUtil.getTokenType(refreshToken)).isEqualTo("refreshToken"), () -> assertThat(jwtUtil.getRoles(refreshToken)).isEqualTo(Role.USER.getRoles()) ); } From 5574cdea68a99c2d024fa1f41e59884c37a09653 Mon Sep 17 00:00:00 2001 From: sanghee0820 Date: Thu, 10 Oct 2024 19:24:36 +0900 Subject: [PATCH 14/40] =?UTF-8?q?[fix]=20place=EB=A5=BC=20nullable=20?= =?UTF-8?q?=ED=95=98=EB=8F=84=EB=A1=9D=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/team7/inplace/video/domain/Video.java | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/main/java/team7/inplace/video/domain/Video.java b/src/main/java/team7/inplace/video/domain/Video.java index 3b2eada2..08f07438 100644 --- a/src/main/java/team7/inplace/video/domain/Video.java +++ b/src/main/java/team7/inplace/video/domain/Video.java @@ -11,7 +11,6 @@ import jakarta.persistence.ManyToOne; import lombok.Getter; import lombok.NoArgsConstructor; -import lombok.NonNull; import lombok.RequiredArgsConstructor; import team7.inplace.influencer.domain.Influencer; import team7.inplace.place.domain.Place; @@ -26,17 +25,14 @@ public class Video { private Long id; @Column(name = "video_url", nullable = false, columnDefinition = "TEXT") - @NonNull private String videoUrl; @ManyToOne @JoinColumn(name = "influencer_id", nullable = false) - @NonNull private Influencer influencer; @ManyToOne - @JoinColumn(name = "place_id", nullable = false) - @NonNull + @JoinColumn(name = "place_id") private Place place; private Video(Influencer influencer, Place place, String videoUrl) { From c09392a6dd29b4c7412524f5ae3969863f1084a2 Mon Sep 17 00:00:00 2001 From: sanghee0820 Date: Thu, 10 Oct 2024 19:25:58 +0900 Subject: [PATCH 15/40] =?UTF-8?q?[fix]=20null=EC=B2=B4=ED=81=AC=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 --- .../inplace/place/application/command/PlacesCommand.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main/java/team7/inplace/place/application/command/PlacesCommand.java b/src/main/java/team7/inplace/place/application/command/PlacesCommand.java index 13e1fd50..d64ef856 100644 --- a/src/main/java/team7/inplace/place/application/command/PlacesCommand.java +++ b/src/main/java/team7/inplace/place/application/command/PlacesCommand.java @@ -66,6 +66,10 @@ public Place toEntity() { } public static Create from(JsonNode locationNode, JsonNode placeNode) { + if (Objects.isNull(locationNode) || Objects.isNull(placeNode)) { + return null; + } + var basicInfo = placeNode.get("basicInfo"); String placeName = From 08419a5f3f015942f87f0480c2be35f9402cb298 Mon Sep 17 00:00:00 2001 From: sanghee0820 Date: Thu, 10 Oct 2024 19:26:26 +0900 Subject: [PATCH 16/40] =?UTF-8?q?[feat]=20price=EB=A5=BC=20String=20?= =?UTF-8?q?=ED=98=95=EC=9C=BC=EB=A1=9C=20=EB=B3=80=ED=99=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../team7/inplace/place/application/dto/PlaceDetailInfo.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/team7/inplace/place/application/dto/PlaceDetailInfo.java b/src/main/java/team7/inplace/place/application/dto/PlaceDetailInfo.java index a68cfee7..93410b68 100644 --- a/src/main/java/team7/inplace/place/application/dto/PlaceDetailInfo.java +++ b/src/main/java/team7/inplace/place/application/dto/PlaceDetailInfo.java @@ -52,7 +52,7 @@ public static MenuInfos of(List menus) { .toList(); List menuList = menus.stream() - .map(menu -> new MenuInfo(menu.getPrice().intValue(), menu.isRecommend(), + .map(menu -> new MenuInfo(menu.getPrice(), menu.isRecommend(), menu.getMenuName())) .toList(); @@ -60,7 +60,7 @@ public static MenuInfos of(List menus) { } public record MenuInfo( - Integer price, + String price, Boolean recommend, String menuName ) { From 6106851fe37662856aa52eba445b5dda44539399 Mon Sep 17 00:00:00 2001 From: BaeJunho Date: Thu, 10 Oct 2024 19:32:08 +0900 Subject: [PATCH 17/40] =?UTF-8?q?[refactor]=20video=20url=20=ED=98=95?= =?UTF-8?q?=EC=8B=9D=20=EB=B3=80=ED=99=98=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../team7/inplace/video/presentation/dto/VideoResponse.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/team7/inplace/video/presentation/dto/VideoResponse.java b/src/main/java/team7/inplace/video/presentation/dto/VideoResponse.java index c7871a86..89003f8c 100644 --- a/src/main/java/team7/inplace/video/presentation/dto/VideoResponse.java +++ b/src/main/java/team7/inplace/video/presentation/dto/VideoResponse.java @@ -14,8 +14,8 @@ public static VideoResponse from(VideoInfo videoInfo) { return new VideoResponse( videoInfo.videoId(), videoInfo.videoAlias(), - videoInfo.videoUrl(), + "https://www.youtube.com/watch?v=" + videoInfo.videoUrl(), videoInfo.place() ); } -} +} \ No newline at end of file From 39423ed83c911333b1d150f7dec69255441eb628 Mon Sep 17 00:00:00 2001 From: BaeJunho Date: Thu, 10 Oct 2024 19:32:48 +0900 Subject: [PATCH 18/40] =?UTF-8?q?[refactor]=20place=20nullable=20=3D=20tru?= =?UTF-8?q?e=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 장소가 아직 입려되지 않은 비디오 엔티티가 있을 수 있기 때문에 --- src/main/java/team7/inplace/video/domain/Video.java | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/main/java/team7/inplace/video/domain/Video.java b/src/main/java/team7/inplace/video/domain/Video.java index 3b2eada2..1d653adb 100644 --- a/src/main/java/team7/inplace/video/domain/Video.java +++ b/src/main/java/team7/inplace/video/domain/Video.java @@ -19,24 +19,20 @@ @Entity @Getter @NoArgsConstructor(access = PROTECTED) -@RequiredArgsConstructor public class Video { @Id @GeneratedValue(strategy = IDENTITY) private Long id; @Column(name = "video_url", nullable = false, columnDefinition = "TEXT") - @NonNull private String videoUrl; @ManyToOne @JoinColumn(name = "influencer_id", nullable = false) - @NonNull private Influencer influencer; @ManyToOne - @JoinColumn(name = "place_id", nullable = false) - @NonNull + @JoinColumn(name = "place_id") private Place place; private Video(Influencer influencer, Place place, String videoUrl) { From 0e89f7b1e5f71b7206c3f2d124da7b42221465d6 Mon Sep 17 00:00:00 2001 From: suhyeon7497 Date: Thu, 10 Oct 2024 19:35:40 +0900 Subject: [PATCH 19/40] =?UTF-8?q?[chore]=20cookie=20key=20=EC=9D=B4?= =?UTF-8?q?=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 관련 이슈: #44 --- .../team7/inplace/security/filter/AuthorizationFilter.java | 4 ++-- .../inplace/token/presentation/RefreshTokenController.java | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/team7/inplace/security/filter/AuthorizationFilter.java b/src/main/java/team7/inplace/security/filter/AuthorizationFilter.java index ae96bd9a..727a1c3d 100644 --- a/src/main/java/team7/inplace/security/filter/AuthorizationFilter.java +++ b/src/main/java/team7/inplace/security/filter/AuthorizationFilter.java @@ -43,14 +43,14 @@ protected void doFilterInternal( private boolean hasNoTokenCookie(HttpServletRequest request) { return Optional.ofNullable(request.getCookies()) .flatMap(cookies -> Arrays.stream(cookies) - .filter(cookie -> cookie.getName().equals("Authorization")) + .filter(cookie -> cookie.getName().equals("access_token")) .findAny()) .isEmpty(); } private Cookie getTokenCookie(HttpServletRequest request) throws InplaceException { return Arrays.stream(request.getCookies()) - .filter(cookie -> cookie.getName().equals("Authorization")) + .filter(cookie -> cookie.getName().equals("access_token")) .findAny() .orElse(null); } diff --git a/src/main/java/team7/inplace/token/presentation/RefreshTokenController.java b/src/main/java/team7/inplace/token/presentation/RefreshTokenController.java index 27a9c7a1..0ced96c7 100644 --- a/src/main/java/team7/inplace/token/presentation/RefreshTokenController.java +++ b/src/main/java/team7/inplace/token/presentation/RefreshTokenController.java @@ -22,7 +22,7 @@ public class RefreshTokenController { private final RefreshTokenFacade refreshTokenFacade; @GetMapping("/refresh-token") - public ResponseEntity refreshToken(@CookieValue(value = "Authorization") Cookie cookie, + public ResponseEntity refreshToken(@CookieValue(value = "refresh_token") Cookie cookie, HttpServletResponse response) { if (cannotRefreshToken(cookie)) { throw InplaceException.of(AuthorizationErrorCode.INVALID_TOKEN); From 333751ae4e593dddd4f12c0e923e26cc20d03e5f Mon Sep 17 00:00:00 2001 From: sanghee0820 Date: Thu, 10 Oct 2024 19:43:15 +0900 Subject: [PATCH 20/40] =?UTF-8?q?[feat]=20RequiredArgsConstructor=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 --- src/main/java/team7/inplace/video/domain/Video.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/main/java/team7/inplace/video/domain/Video.java b/src/main/java/team7/inplace/video/domain/Video.java index 08f07438..303982ac 100644 --- a/src/main/java/team7/inplace/video/domain/Video.java +++ b/src/main/java/team7/inplace/video/domain/Video.java @@ -11,14 +11,12 @@ import jakarta.persistence.ManyToOne; import lombok.Getter; import lombok.NoArgsConstructor; -import lombok.RequiredArgsConstructor; import team7.inplace.influencer.domain.Influencer; import team7.inplace.place.domain.Place; @Entity @Getter @NoArgsConstructor(access = PROTECTED) -@RequiredArgsConstructor public class Video { @Id @GeneratedValue(strategy = IDENTITY) From 5e163e866754959e9df0803272156f63ae847dd6 Mon Sep 17 00:00:00 2001 From: sanghee0820 Date: Thu, 10 Oct 2024 19:43:44 +0900 Subject: [PATCH 21/40] =?UTF-8?q?[feat]=20Enumerate=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/team7/inplace/crawling/domain/YoutubeChannel.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main/java/team7/inplace/crawling/domain/YoutubeChannel.java b/src/main/java/team7/inplace/crawling/domain/YoutubeChannel.java index 00f94f9e..1fadeab8 100644 --- a/src/main/java/team7/inplace/crawling/domain/YoutubeChannel.java +++ b/src/main/java/team7/inplace/crawling/domain/YoutubeChannel.java @@ -1,6 +1,9 @@ package team7.inplace.crawling.domain; +import static jakarta.persistence.EnumType.STRING; + import jakarta.persistence.Entity; +import jakarta.persistence.Enumerated; import jakarta.persistence.GeneratedValue; import jakarta.persistence.GenerationType; import jakarta.persistence.Id; @@ -22,6 +25,7 @@ public class YoutubeChannel { private String playListUUID; private String lastVideoUUID; + @Enumerated(value = STRING) private ChannelType channelType; public String getChannelTypeCode() { From 46ab086ebc7d5d98d2df77d9144d08ecb178278f Mon Sep 17 00:00:00 2001 From: BaeJunho Date: Thu, 10 Oct 2024 20:08:28 +0900 Subject: [PATCH 22/40] =?UTF-8?q?[chore]=20=EB=88=84=EB=9D=BD=EB=90=9C=20?= =?UTF-8?q?=EC=96=B4=EB=85=B8=ED=85=8C=EC=9D=B4=EC=85=98=20=EC=82=BD?= =?UTF-8?q?=EC=9E=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../team7/inplace/influencer/application/InfluencerService.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/team7/inplace/influencer/application/InfluencerService.java b/src/main/java/team7/inplace/influencer/application/InfluencerService.java index 250d62d5..d8628289 100644 --- a/src/main/java/team7/inplace/influencer/application/InfluencerService.java +++ b/src/main/java/team7/inplace/influencer/application/InfluencerService.java @@ -55,6 +55,7 @@ public void deleteInfluencer(Long id) { influencerRepository.delete(influencer); } + @Transactional public void likeToInfluencer(InfluencerRequestParam param) { String username = AuthorizationUtil.getUsername(); if (StringUtils.hasText(username)) { From 9ac0c407f920b2bd7a5900602db4e02d7de63bac Mon Sep 17 00:00:00 2001 From: suhyeon7497 Date: Thu, 10 Oct 2024 20:13:39 +0900 Subject: [PATCH 23/40] =?UTF-8?q?[refactor]=20=EC=88=98=EC=A0=95=20?= =?UTF-8?q?=EC=82=AC=ED=95=AD=20=EB=B0=98=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 관련 이슈: #44 --- .../config/SecurityHandlerConfig.java | 6 ++++-- .../security/config/SecurityUtilConfig.java | 6 ++++++ .../handler/CustomSuccessHandler.java | 20 ++++++++----------- .../inplace/security/util/CookieUtil.java | 14 +++++++++++++ .../application/RefreshTokenService.java | 4 ++-- .../persistence/RefreshTokenRepository.java | 2 -- .../presentation/RefreshTokenController.java | 18 ++++++++--------- 7 files changed, 42 insertions(+), 28 deletions(-) create mode 100644 src/main/java/team7/inplace/security/util/CookieUtil.java diff --git a/src/main/java/team7/inplace/security/config/SecurityHandlerConfig.java b/src/main/java/team7/inplace/security/config/SecurityHandlerConfig.java index b8ab828e..6ad12a52 100644 --- a/src/main/java/team7/inplace/security/config/SecurityHandlerConfig.java +++ b/src/main/java/team7/inplace/security/config/SecurityHandlerConfig.java @@ -3,6 +3,7 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import team7.inplace.security.handler.CustomSuccessHandler; +import team7.inplace.security.util.CookieUtil; import team7.inplace.security.util.JwtUtil; import team7.inplace.token.application.RefreshTokenService; import team7.inplace.user.application.UserService; @@ -14,8 +15,9 @@ public class SecurityHandlerConfig { public CustomSuccessHandler customSuccessHandler( JwtUtil jwtUtil, UserService userService, - RefreshTokenService refreshTokenService + RefreshTokenService refreshTokenService, + CookieUtil cookieUtil ) { - return new CustomSuccessHandler(jwtUtil, userService, refreshTokenService); + return new CustomSuccessHandler(jwtUtil, userService, refreshTokenService, cookieUtil); } } diff --git a/src/main/java/team7/inplace/security/config/SecurityUtilConfig.java b/src/main/java/team7/inplace/security/config/SecurityUtilConfig.java index bc3799f5..3e3de553 100644 --- a/src/main/java/team7/inplace/security/config/SecurityUtilConfig.java +++ b/src/main/java/team7/inplace/security/config/SecurityUtilConfig.java @@ -2,6 +2,7 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import team7.inplace.security.util.CookieUtil; import team7.inplace.security.util.JwtUtil; @Configuration @@ -11,4 +12,9 @@ public class SecurityUtilConfig { public JwtUtil jwtUtil(JwtProperties jwtProperties) { return new JwtUtil(jwtProperties); } + + @Bean + public CookieUtil cookieUtil() { + return new CookieUtil(); + } } diff --git a/src/main/java/team7/inplace/security/handler/CustomSuccessHandler.java b/src/main/java/team7/inplace/security/handler/CustomSuccessHandler.java index 37276d49..8264e480 100644 --- a/src/main/java/team7/inplace/security/handler/CustomSuccessHandler.java +++ b/src/main/java/team7/inplace/security/handler/CustomSuccessHandler.java @@ -7,6 +7,7 @@ import org.springframework.security.core.Authentication; import org.springframework.security.web.authentication.AuthenticationSuccessHandler; import team7.inplace.security.application.dto.CustomOAuth2User; +import team7.inplace.security.util.CookieUtil; import team7.inplace.security.util.JwtUtil; import team7.inplace.token.application.RefreshTokenService; import team7.inplace.user.application.UserService; @@ -17,14 +18,18 @@ public class CustomSuccessHandler implements AuthenticationSuccessHandler { private final JwtUtil jwtUtil; private final UserService userService; private final RefreshTokenService refreshTokenService; + private final CookieUtil cookieUtil; public CustomSuccessHandler( JwtUtil jwtUtil, - UserService userService, RefreshTokenService refreshTokenService + UserService userService, + RefreshTokenService refreshTokenService, + CookieUtil cookieUtil ) { this.jwtUtil = jwtUtil; this.userService = userService; this.refreshTokenService = refreshTokenService; + this.cookieUtil = cookieUtil; } @Override @@ -48,8 +53,8 @@ private void addTokenToResponse( HttpServletResponse response, String accessToken, String refreshToken ) { - Cookie accessTokenCookie = createCookie("access_token", accessToken); - Cookie refreshTokenCookie = createCookie("refresh_token", refreshToken); + Cookie accessTokenCookie = cookieUtil.createCookie("access_token", accessToken); + Cookie refreshTokenCookie = cookieUtil.createCookie("refresh_token", refreshToken); response.addCookie(accessTokenCookie); response.addCookie(refreshTokenCookie); @@ -65,13 +70,4 @@ private void setRedirectUrlToResponse( } response.sendRedirect("http://localhost:8080/auth"); } - - private Cookie createCookie(String key, String value) { - Cookie cookie = new Cookie(key, value); - cookie.setMaxAge(60 * 60); - cookie.setPath("/"); - cookie.setHttpOnly(true); - return cookie; - } - } diff --git a/src/main/java/team7/inplace/security/util/CookieUtil.java b/src/main/java/team7/inplace/security/util/CookieUtil.java new file mode 100644 index 00000000..068f8a91 --- /dev/null +++ b/src/main/java/team7/inplace/security/util/CookieUtil.java @@ -0,0 +1,14 @@ +package team7.inplace.security.util; + +import jakarta.servlet.http.Cookie; + +public class CookieUtil { + + public Cookie createCookie(String key, String value) { + Cookie cookie = new Cookie(key, value); + cookie.setMaxAge(60 * 60); + cookie.setPath("/"); + cookie.setHttpOnly(true); + return cookie; + } +} diff --git a/src/main/java/team7/inplace/token/application/RefreshTokenService.java b/src/main/java/team7/inplace/token/application/RefreshTokenService.java index 9c7a452e..2cd94d0d 100644 --- a/src/main/java/team7/inplace/token/application/RefreshTokenService.java +++ b/src/main/java/team7/inplace/token/application/RefreshTokenService.java @@ -17,8 +17,8 @@ public class RefreshTokenService { public boolean isInvalidRefreshToken(String refreshToken) throws InplaceException { String username = jwtUtil.getUsername(refreshToken); - return !refreshTokenRepository.findById(username).orElseThrow(() -> - InplaceException.of(AuthorizationErrorCode.INVALID_TOKEN)) + return !refreshTokenRepository.findById(username) + .orElseThrow(() -> InplaceException.of(AuthorizationErrorCode.INVALID_TOKEN)) .getRefreshToken().equals(refreshToken); } diff --git a/src/main/java/team7/inplace/token/persistence/RefreshTokenRepository.java b/src/main/java/team7/inplace/token/persistence/RefreshTokenRepository.java index 870aceb8..e62d5b12 100644 --- a/src/main/java/team7/inplace/token/persistence/RefreshTokenRepository.java +++ b/src/main/java/team7/inplace/token/persistence/RefreshTokenRepository.java @@ -1,6 +1,5 @@ package team7.inplace.token.persistence; -import java.util.Optional; import org.springframework.data.repository.CrudRepository; import org.springframework.stereotype.Repository; import team7.inplace.token.domain.RefreshToken; @@ -8,5 +7,4 @@ @Repository public interface RefreshTokenRepository extends CrudRepository { - Optional findById(String id); } diff --git a/src/main/java/team7/inplace/token/presentation/RefreshTokenController.java b/src/main/java/team7/inplace/token/presentation/RefreshTokenController.java index 0ced96c7..e3d241dd 100644 --- a/src/main/java/team7/inplace/token/presentation/RefreshTokenController.java +++ b/src/main/java/team7/inplace/token/presentation/RefreshTokenController.java @@ -3,6 +3,7 @@ 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.CookieValue; import org.springframework.web.bind.annotation.GetMapping; @@ -10,6 +11,7 @@ import team7.inplace.global.exception.InplaceException; import team7.inplace.global.exception.code.AuthorizationErrorCode; import team7.inplace.security.util.AuthorizationUtil; +import team7.inplace.security.util.CookieUtil; import team7.inplace.security.util.JwtUtil; import team7.inplace.token.application.RefreshTokenFacade; import team7.inplace.token.application.dto.TokenCommand.ReIssued; @@ -20,6 +22,7 @@ public class RefreshTokenController { private final JwtUtil jwtUtil; private final RefreshTokenFacade refreshTokenFacade; + private final CookieUtil cookieUtil; @GetMapping("/refresh-token") public ResponseEntity refreshToken(@CookieValue(value = "refresh_token") Cookie cookie, @@ -33,12 +36,14 @@ public ResponseEntity refreshToken(@CookieValue(value = "refresh_token") C jwtUtil.getUsername(refreshToken), refreshToken); addTokenToCookie(response, reIssuedToken); - return ResponseEntity.ok().build(); + return new ResponseEntity<>(HttpStatus.OK); } private void addTokenToCookie(HttpServletResponse response, ReIssued reIssuedToken) { - Cookie accessTokenCookie = createCookie("access_token", reIssuedToken.accessToken()); - Cookie refreshTokenCookie = createCookie("refresh_token", reIssuedToken.refreshToken()); + Cookie accessTokenCookie = cookieUtil.createCookie("access_token", + reIssuedToken.accessToken()); + Cookie refreshTokenCookie = cookieUtil.createCookie("refresh_token", + reIssuedToken.refreshToken()); response.addCookie(accessTokenCookie); response.addCookie(refreshTokenCookie); } @@ -47,11 +52,4 @@ private boolean cannotRefreshToken(Cookie cookie) { return AuthorizationUtil.getUserId() == null || !jwtUtil.isRefreshToken(cookie.getValue()); } - private Cookie createCookie(String key, String value) { - Cookie cookie = new Cookie(key, value); - cookie.setMaxAge(60 * 60); - cookie.setPath("/"); - cookie.setHttpOnly(true); - return cookie; - } } From 9f4bc4500b464e203ce4450c13d4064f1c29082c Mon Sep 17 00:00:00 2001 From: sanghee0820 Date: Thu, 10 Oct 2024 20:31:10 +0900 Subject: [PATCH 24/40] =?UTF-8?q?[feat]=20menu=20img=EC=99=80=20descriptio?= =?UTF-8?q?n=EC=9D=84=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../application/command/PlacesCommand.java | 18 +++++++++++------- .../java/team7/inplace/place/domain/Menu.java | 9 ++++++--- 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/src/main/java/team7/inplace/place/application/command/PlacesCommand.java b/src/main/java/team7/inplace/place/application/command/PlacesCommand.java index d64ef856..1b20da31 100644 --- a/src/main/java/team7/inplace/place/application/command/PlacesCommand.java +++ b/src/main/java/team7/inplace/place/application/command/PlacesCommand.java @@ -69,7 +69,7 @@ public static Create from(JsonNode locationNode, JsonNode placeNode) { if (Objects.isNull(locationNode) || Objects.isNull(placeNode)) { return null; } - + var basicInfo = placeNode.get("basicInfo"); String placeName = @@ -186,21 +186,25 @@ public String toEntityParams() { public record Menu( String menuName, String menuPrice, - boolean recommend + boolean recommend, + String menuImgUrl, + String description ) { public static Menu from(JsonNode menuNode) { if (Objects.isNull(menuNode)) { - return new Menu("Unknown Menu", "0", false); + return new Menu("Unknown Menu", "0", false, "", ""); } - String menuName = menuNode.has("menu") ? menuNode.get("menu").asText() : "Unknown Menu"; - String menuPrice = menuNode.has("price") ? menuNode.get("price").asText() : "0"; + String menuName = menuNode.has("menu") ? menuNode.get("menu").asText() : " "; + String menuPrice = menuNode.has("price") ? menuNode.get("price").asText() : " "; boolean recommend = menuNode.has("recommend") && menuNode.get("recommend").asBoolean(); + String menuImgUrl = menuNode.has("img") ? menuNode.get("img").asText() : " "; + String description = menuNode.has("desc") ? menuNode.get("desc").asText() : " "; - return new Menu(menuName, menuPrice, recommend); + return new Menu(menuName, menuPrice, recommend, menuImgUrl, description); } public String toEntityParams() { - return menuName + "|" + menuPrice + "|" + recommend; + return menuName + "|" + menuPrice + "|" + recommend + "|" + menuImgUrl + "|" + description; } } } diff --git a/src/main/java/team7/inplace/place/domain/Menu.java b/src/main/java/team7/inplace/place/domain/Menu.java index f23bfb8f..1b8cee65 100644 --- a/src/main/java/team7/inplace/place/domain/Menu.java +++ b/src/main/java/team7/inplace/place/domain/Menu.java @@ -22,18 +22,21 @@ public class Menu { @Column(length = 50, nullable = false) private String menuName; - @Column(length = 50) private String menuImgUrl; - private Menu(String price, boolean recommend, String menuName) { + private String description; + + private Menu(String price, boolean recommend, String menuName, String menuImgUrl, String description) { this.price = price; this.recommend = recommend; this.menuName = menuName; + this.menuImgUrl = menuImgUrl; + this.description = description; } public static Menu of(String menu) { String[] menus = menu.split("\\|"); - return new Menu(menus[1], Boolean.parseBoolean(menus[2]), menus[0]); + return new Menu(menus[1], Boolean.parseBoolean(menus[2]), menus[0], menus[3], menus[4]); } } From 6a1ed7d93d34fbccda7e169a9461a03b62c0c84c Mon Sep 17 00:00:00 2001 From: sanghee0820 Date: Thu, 10 Oct 2024 20:52:55 +0900 Subject: [PATCH 25/40] =?UTF-8?q?[feat]=20JsonNode=EC=99=80=20String=20?= =?UTF-8?q?=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../inplace/crawling/application/AddressUtil.java | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/main/java/team7/inplace/crawling/application/AddressUtil.java b/src/main/java/team7/inplace/crawling/application/AddressUtil.java index ad241ebd..cfe07276 100644 --- a/src/main/java/team7/inplace/crawling/application/AddressUtil.java +++ b/src/main/java/team7/inplace/crawling/application/AddressUtil.java @@ -8,15 +8,19 @@ import lombok.NoArgsConstructor; @NoArgsConstructor(access = PRIVATE) -public class AddressUtil { - private static final String ADDRESS_REGEX = "[가-힣0-9]+(?:도|시|구|군|읍|면|동|리|로|길)[^#,\\n()]+(?:동|읍|면|리|로|길)[^#]?"; +public final class AddressUtil { + private static final String ADDRESS_REGEX = "[가-힣0-9]+(?:도|시|구|군|읍|면|동|리|로|길)\\s*[0-9]*(?:동|읍|면|리|로|길)?\\s*[0-9]+"; - public static String extractAddress(JsonNode snippet) { + public static String extractAddressFromJsonNode(JsonNode snippet) { String videoDescription = snippet.path("description").asText(); + return extractAddressFromString(videoDescription); + } + + public static String extractAddressFromString(String string) { Pattern pattern = Pattern.compile(ADDRESS_REGEX); - Matcher matcher = pattern.matcher(videoDescription); + Matcher matcher = pattern.matcher(string); if (matcher.find()) { return matcher.group(); } From e10ed326e998f6c6cb83c1d56f7fe0bcd0b372a1 Mon Sep 17 00:00:00 2001 From: sanghee0820 Date: Thu, 10 Oct 2024 21:01:47 +0900 Subject: [PATCH 26/40] =?UTF-8?q?[fix]=20=ED=94=84=EB=A6=B0=EB=AC=B8=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 --- src/main/java/team7/inplace/place/domain/Address.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/java/team7/inplace/place/domain/Address.java b/src/main/java/team7/inplace/place/domain/Address.java index 4775adab..2212008b 100644 --- a/src/main/java/team7/inplace/place/domain/Address.java +++ b/src/main/java/team7/inplace/place/domain/Address.java @@ -30,11 +30,10 @@ private Address(String address1, String address2, String address3) { } public static Address of(String address) { - System.out.println("address: " + address); String[] split = address.split(" "); var address1 = split[0]; var address2 = split[1]; var address3 = String.join(" ", Arrays.copyOfRange(split, 2, split.length)); return new Address(address1, address2, address3); } -} +} \ No newline at end of file From eb76ff5895f99ce5206ec3a5e6c23ea45b2987e1 Mon Sep 17 00:00:00 2001 From: sanghee0820 Date: Thu, 10 Oct 2024 21:02:17 +0900 Subject: [PATCH 27/40] =?UTF-8?q?[test]=20=EC=A3=BC=EC=86=8C=20=ED=8C=8C?= =?UTF-8?q?=EC=8B=B1=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../crawling/application/AddressUtilTest.java | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 src/test/java/team7/inplace/crawling/application/AddressUtilTest.java diff --git a/src/test/java/team7/inplace/crawling/application/AddressUtilTest.java b/src/test/java/team7/inplace/crawling/application/AddressUtilTest.java new file mode 100644 index 00000000..6adcf7cf --- /dev/null +++ b/src/test/java/team7/inplace/crawling/application/AddressUtilTest.java @@ -0,0 +1,27 @@ +package team7.inplace.crawling.application; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +class AddressUtilTest { + + @DisplayName("주소 추출 테스트 1") + @Test + void extractAddressFromJsonNodeTest1() { + // given + final String description = """ + [참조은 생고기] + 대구 북구 복현로 78 (복현2동 266-9) + """; + final String address = "대구 북구 복현로 78"; + + // when + String result = AddressUtil.extractAddressFromString(description); + + // then + assertEquals(address, result); + } + +} \ No newline at end of file From 47b40212dc3ee47a518aaf51579c61c43667a943 Mon Sep 17 00:00:00 2001 From: sanghee0820 Date: Thu, 10 Oct 2024 21:02:37 +0900 Subject: [PATCH 28/40] =?UTF-8?q?[fix]=20null=ED=99=95=EC=9D=B8=20?= =?UTF-8?q?=EB=A1=9C=EC=A7=81=EC=9D=84=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../inplace/place/application/command/PlacesCommand.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/main/java/team7/inplace/place/application/command/PlacesCommand.java b/src/main/java/team7/inplace/place/application/command/PlacesCommand.java index 1b20da31..5d7d4559 100644 --- a/src/main/java/team7/inplace/place/application/command/PlacesCommand.java +++ b/src/main/java/team7/inplace/place/application/command/PlacesCommand.java @@ -96,8 +96,12 @@ public static Create from(JsonNode locationNode, JsonNode placeNode) { ? locationNode.get("documents").get(0).get("y").asText() : "0.0"; var timeList = basicInfo.has("openHour") ? basicInfo.get("openHour") : null; - var openPeriods = extractOpenPeriods(timeList.has("periodList") ? timeList.get("periodList") : null); - var offDays = extractOffDays(timeList.has("offdayList") ? timeList.get("offdayList") : null); + List openPeriods = Objects.nonNull(timeList) ? + extractOpenPeriods(timeList.has("periodList") ? timeList.get("periodList") : null) + : new ArrayList<>(); + List offDays = Objects.nonNull(timeList) ? + extractOffDays(timeList.has("offdayList") ? timeList.get("offdayList") : null) : new ArrayList<>(); + var menus = extractMenus(placeNode.has("menuInfo") ? placeNode.get("menuInfo") : null); var menuUpdatedAt = placeNode.has("menuInfo") && placeNode.get("menuInfo").has("menuUpdatedAt") ? LocalDateTime.parse(placeNode.get("menuInfo").get("timeexp").asText()) From 10efe63e19383154c08b92948e3a2d856c5089eb Mon Sep 17 00:00:00 2001 From: sanghee0820 Date: Thu, 10 Oct 2024 21:02:54 +0900 Subject: [PATCH 29/40] =?UTF-8?q?[feat]=20JsonNode=EC=99=80=20String=20?= =?UTF-8?q?=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../inplace/crawling/application/YoutubeCrawlingService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/team7/inplace/crawling/application/YoutubeCrawlingService.java b/src/main/java/team7/inplace/crawling/application/YoutubeCrawlingService.java index 9a3020d1..9b207d73 100644 --- a/src/main/java/team7/inplace/crawling/application/YoutubeCrawlingService.java +++ b/src/main/java/team7/inplace/crawling/application/YoutubeCrawlingService.java @@ -32,7 +32,7 @@ public List crawlAllVideos() { var videoSnippets = youtubeClient.getVideos(channel.getPlayListUUID(), channel.getLastVideoUUID()); var videoAddresses = videoSnippets.stream() - .map(AddressUtil::extractAddress) + .map(AddressUtil::extractAddressFromJsonNode) .toList(); var placeNodes = videoAddresses.stream() From b667945f0dbb28ebe212dd37405bb2f55778ea44 Mon Sep 17 00:00:00 2001 From: dong_yxxn Date: Thu, 10 Oct 2024 21:03:39 +0900 Subject: [PATCH 30/40] =?UTF-8?q?[refactor]:=20MenuInfos-menuList=20?= =?UTF-8?q?=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - menuList 제거함, menu VO 변경에 맞춰, menuImgUrl, description 필드 추가 관련 이슈: #7 --- .../application/dto/PlaceDetailInfo.java | 81 +++++++++---------- .../inplace/place/config/QueryDslConfig.java | 2 + .../persistence/PlaceCustomRepository.java | 2 + .../PlaceCustomRepositoryImpl.java | 2 + 4 files changed, 45 insertions(+), 42 deletions(-) create mode 100644 src/main/java/team7/inplace/place/config/QueryDslConfig.java create mode 100644 src/main/java/team7/inplace/place/persistence/PlaceCustomRepository.java create mode 100644 src/main/java/team7/inplace/place/persistence/PlaceCustomRepositoryImpl.java diff --git a/src/main/java/team7/inplace/place/application/dto/PlaceDetailInfo.java b/src/main/java/team7/inplace/place/application/dto/PlaceDetailInfo.java index a68cfee7..91ff1a02 100644 --- a/src/main/java/team7/inplace/place/application/dto/PlaceDetailInfo.java +++ b/src/main/java/team7/inplace/place/application/dto/PlaceDetailInfo.java @@ -11,22 +11,22 @@ import team7.inplace.video.domain.Video; public record PlaceDetailInfo( - PlaceInfo placeInfo, - JsonNode facilityInfo, - MenuInfos menuInfos, - OpenHour openHour, - PlaceLikes placeLikes, - String videoUrl + PlaceInfo placeInfo, + JsonNode facilityInfo, + MenuInfos menuInfos, + OpenHour openHour, + PlaceLikes placeLikes, + String videoUrl ) { public static PlaceDetailInfo from(Place place, Influencer influencer, Video video) { return new PlaceDetailInfo( - PlaceInfo.of(place, influencer.getName()), - facilityTree(place.getFacility()), - MenuInfos.of(place.getMenus()), - OpenHour.of(place.getOpenPeriods(), place.getOffDays()), - PlaceLikes.of(null), //추후 추가 예정 - video.getVideoUrl() + PlaceInfo.of(place, influencer.getName()), + facilityTree(place.getFacility()), + MenuInfos.of(place.getMenus()), + OpenHour.of(place.getOpenPeriods(), place.getOffDays()), + PlaceLikes.of(null), //추후 추가 예정 + video.getVideoUrl() ); } @@ -41,73 +41,70 @@ private static JsonNode facilityTree(String facility) { public record MenuInfos( - List menuImgUrls, - List menuList, - LocalDateTime timeExp + List menuList, + LocalDateTime timeExp ) { public static MenuInfos of(List menus) { - List menuImgUrls = menus.stream() - .map(Menu::getMenuImgUrl) // 메뉴 이미지 URL을 추출 - .toList(); - List menuList = menus.stream() - .map(menu -> new MenuInfo(menu.getPrice().intValue(), menu.isRecommend(), - menu.getMenuName())) - .toList(); + .map(menu -> new MenuInfo(menu.getPrice().intValue(), menu.isRecommend(), + menu.getMenuName(), menu.getMenuImgUrl(), menu.getDescription())) + .toList(); - return new MenuInfos(menuImgUrls, menuList, LocalDateTime.now()); + return new MenuInfos(menuList, LocalDateTime.now()); } public record MenuInfo( - Integer price, - Boolean recommend, - String menuName + Integer price, + Boolean recommend, + String menuName, + String menuImgUrl, + String description ) { } } public record OpenHour( - List periodList, - List offdayList + List periodList, + List offdayList ) { public static OpenHour of(List openTimes, - List closeTimes + List closeTimes ) { List periods = openTimes.stream() - .map(time -> new Period(time.getTimeName(), time.getTimeSE(), time.getDayOfWeek())) - .toList(); + .map(time -> new Period(time.getTimeName(), time.getTimeSE(), time.getDayOfWeek())) + .toList(); List offDays = closeTimes.stream() - .map(closeTime -> new OffDay(closeTime.getHolidayName(), closeTime.getWeekAndDay(), - closeTime.getTemporaryHolidays())) - .toList(); + .map(closeTime -> new OffDay(closeTime.getHolidayName(), closeTime.getWeekAndDay(), + closeTime.getTemporaryHolidays())) + .toList(); return new OpenHour(periods, offDays); } public record Period( - String timeName, - String timeSE, - String dayOfWeek + String timeName, + String timeSE, + String dayOfWeek ) { } public record OffDay( - String holidayName, - String weekAndDay, - String temporaryHolidays + String holidayName, + String weekAndDay, + String temporaryHolidays ) { } } public record PlaceLikes( - Integer like, - Integer dislike + Integer like, + Integer dislike ) { public static PlaceLikes of(Boolean likes) { diff --git a/src/main/java/team7/inplace/place/config/QueryDslConfig.java b/src/main/java/team7/inplace/place/config/QueryDslConfig.java new file mode 100644 index 00000000..005f817e --- /dev/null +++ b/src/main/java/team7/inplace/place/config/QueryDslConfig.java @@ -0,0 +1,2 @@ +package team7.inplace.place.config;public class QueryDslConfig { +} diff --git a/src/main/java/team7/inplace/place/persistence/PlaceCustomRepository.java b/src/main/java/team7/inplace/place/persistence/PlaceCustomRepository.java new file mode 100644 index 00000000..b294a6c6 --- /dev/null +++ b/src/main/java/team7/inplace/place/persistence/PlaceCustomRepository.java @@ -0,0 +1,2 @@ +package team7.inplace.place.persistence;public interface PlaceCustomRepository { +} diff --git a/src/main/java/team7/inplace/place/persistence/PlaceCustomRepositoryImpl.java b/src/main/java/team7/inplace/place/persistence/PlaceCustomRepositoryImpl.java new file mode 100644 index 00000000..23054279 --- /dev/null +++ b/src/main/java/team7/inplace/place/persistence/PlaceCustomRepositoryImpl.java @@ -0,0 +1,2 @@ +package team7.inplace.place.persistence;public class PlaceCustomRepositoryImpl { +} From 3710c6a5305f65a158275562c9e5e5c6515cc2b4 Mon Sep 17 00:00:00 2001 From: suhyeon7497 Date: Fri, 11 Oct 2024 19:08:23 +0900 Subject: [PATCH 31/40] =?UTF-8?q?[refactor]=20ErrorCode=EB=8A=94=20getter?= =?UTF-8?q?=EB=A5=BC=20=EC=82=AC=EC=9A=A9=ED=95=98=EC=A7=80=20=EC=95=8A?= =?UTF-8?q?=EB=8A=94=EB=8B=A4.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 관련 이슈: #2 --- .../java/team7/inplace/global/exception/code/UserErroCode.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/main/java/team7/inplace/global/exception/code/UserErroCode.java b/src/main/java/team7/inplace/global/exception/code/UserErroCode.java index f2efcfd4..32a61c92 100644 --- a/src/main/java/team7/inplace/global/exception/code/UserErroCode.java +++ b/src/main/java/team7/inplace/global/exception/code/UserErroCode.java @@ -1,11 +1,9 @@ package team7.inplace.global.exception.code; import lombok.AllArgsConstructor; -import lombok.Getter; import org.springframework.http.HttpStatus; @AllArgsConstructor -@Getter public enum UserErroCode implements ErrorCode { NOT_FOUND(HttpStatus.NOT_FOUND, "U001", "User is not found"); From d7e309aaf5fae0890e9adf58980a7df0a96f4ec6 Mon Sep 17 00:00:00 2001 From: suhyeon7497 Date: Fri, 11 Oct 2024 19:12:15 +0900 Subject: [PATCH 32/40] [feat] UserErrorCode MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit getmethod 빼먹은 부분 을 추가 하였습니다. 관련 이슈 : #44 --- .../team7/inplace/global/exception/code/UserErroCode.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/team7/inplace/global/exception/code/UserErroCode.java b/src/main/java/team7/inplace/global/exception/code/UserErroCode.java index 32a61c92..afb2d576 100644 --- a/src/main/java/team7/inplace/global/exception/code/UserErroCode.java +++ b/src/main/java/team7/inplace/global/exception/code/UserErroCode.java @@ -13,16 +13,16 @@ public enum UserErroCode implements ErrorCode { @Override public HttpStatus httpStatus() { - return null; + return status; } @Override public String code() { - return ""; + return code; } @Override public String message() { - return ""; + return message; } } From c37ed80ef03254201bb1d1ba051624a315f359d2 Mon Sep 17 00:00:00 2001 From: dong_yxxn Date: Fri, 11 Oct 2024 19:14:25 +0900 Subject: [PATCH 33/40] =?UTF-8?q?[refactor]:=20queryDslConfig=20global=20?= =?UTF-8?q?=ED=8C=A8=ED=82=A4=EC=A7=80=EB=A1=9C=20=EC=9D=B4=EB=8F=99?= =?UTF-8?q?=ED=95=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 관련 이슈: #7 --- .../global/queryDsl/QueryDslConfig.java | 20 +++++++++++++++++++ .../inplace/place/config/QueryDslConfig.java | 2 -- 2 files changed, 20 insertions(+), 2 deletions(-) create mode 100644 src/main/java/team7/inplace/global/queryDsl/QueryDslConfig.java delete mode 100644 src/main/java/team7/inplace/place/config/QueryDslConfig.java diff --git a/src/main/java/team7/inplace/global/queryDsl/QueryDslConfig.java b/src/main/java/team7/inplace/global/queryDsl/QueryDslConfig.java new file mode 100644 index 00000000..73fab4eb --- /dev/null +++ b/src/main/java/team7/inplace/global/queryDsl/QueryDslConfig.java @@ -0,0 +1,20 @@ +package team7.inplace.global.queryDsl; + +import com.querydsl.jpa.impl.JPAQueryFactory; +import jakarta.persistence.EntityManager; +import jakarta.persistence.PersistenceContext; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class QueryDslConfig { + + @PersistenceContext + private EntityManager entityManager; + + @Bean + public JPAQueryFactory jpaQueryFactory() { + return new JPAQueryFactory(entityManager); + } + +} diff --git a/src/main/java/team7/inplace/place/config/QueryDslConfig.java b/src/main/java/team7/inplace/place/config/QueryDslConfig.java deleted file mode 100644 index 005f817e..00000000 --- a/src/main/java/team7/inplace/place/config/QueryDslConfig.java +++ /dev/null @@ -1,2 +0,0 @@ -package team7.inplace.place.config;public class QueryDslConfig { -} From 47f589d7d8dbb8f89c02dd3c3f0611edcc941cbb Mon Sep 17 00:00:00 2001 From: BaeJunho Date: Fri, 11 Oct 2024 19:15:35 +0900 Subject: [PATCH 34/40] =?UTF-8?q?[refactor]=20error=20code=20=ED=98=95?= =?UTF-8?q?=EC=8B=9D=20=ED=86=B5=EC=9D=BC=20=EB=B0=8F=20Place=20error=20co?= =?UTF-8?q?de=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../global/exception/code/PlaceErrorCode.java | 31 +++++++++++++++++++ .../global/exception/code/VideoErrorCode.java | 2 +- 2 files changed, 32 insertions(+), 1 deletion(-) create mode 100644 src/main/java/team7/inplace/global/exception/code/PlaceErrorCode.java diff --git a/src/main/java/team7/inplace/global/exception/code/PlaceErrorCode.java b/src/main/java/team7/inplace/global/exception/code/PlaceErrorCode.java new file mode 100644 index 00000000..e9bbe2de --- /dev/null +++ b/src/main/java/team7/inplace/global/exception/code/PlaceErrorCode.java @@ -0,0 +1,31 @@ +package team7.inplace.global.exception.code; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import org.springframework.http.HttpStatus; + + +@AllArgsConstructor +@Getter +public enum PlaceErrorCode implements ErrorCode{ + NOT_FOUND(HttpStatus.NOT_FOUND, "P001", "Can't find such place info"); + + private final HttpStatus httpStatus; + private final String errorCode; + private final String message; + + @Override + public HttpStatus httpStatus() { + return httpStatus; + } + + @Override + public String code() { + return errorCode; + } + + @Override + public String message() { + return message; + } +} diff --git a/src/main/java/team7/inplace/global/exception/code/VideoErrorCode.java b/src/main/java/team7/inplace/global/exception/code/VideoErrorCode.java index 483b97d0..a1c6ea37 100644 --- a/src/main/java/team7/inplace/global/exception/code/VideoErrorCode.java +++ b/src/main/java/team7/inplace/global/exception/code/VideoErrorCode.java @@ -7,7 +7,7 @@ @AllArgsConstructor @Getter public enum VideoErrorCode implements ErrorCode{ - NO_SUCH_VIDEO(HttpStatus.NOT_FOUND, "V001", "Can't find such video info"); + NOT_FOUND(HttpStatus.NOT_FOUND, "V001", "Can't find such video info"); private final HttpStatus httpStatus; private final String errorCode; From 761bd2cd2d539e87db55177de25c18484926497b Mon Sep 17 00:00:00 2001 From: BaeJunho Date: Fri, 11 Oct 2024 19:16:19 +0900 Subject: [PATCH 35/40] =?UTF-8?q?[refactor]=20=EA=B2=80=EC=83=89=20?= =?UTF-8?q?=EC=A1=B0=EA=B1=B4=EC=9D=B4=20=EB=8D=94=20=EB=B3=B5=EC=9E=A1?= =?UTF-8?q?=ED=95=B4=EC=A0=B8=EC=84=9C=20=ED=95=B4=EB=8B=B9=20=EB=B6=80?= =?UTF-8?q?=EB=B6=84=20=EB=B3=80=ED=99=98=ED=95=B4=EC=A3=BC=EB=8A=94=20?= =?UTF-8?q?=ED=8E=99=ED=86=A0=EB=A6=AC=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 --- .../place/application/command/PlacesCommand.java | 12 ++++++++++++ .../video/presentation/dto/VideoSearchParams.java | 4 ++++ 2 files changed, 16 insertions(+) diff --git a/src/main/java/team7/inplace/place/application/command/PlacesCommand.java b/src/main/java/team7/inplace/place/application/command/PlacesCommand.java index 376f2351..27fc1939 100644 --- a/src/main/java/team7/inplace/place/application/command/PlacesCommand.java +++ b/src/main/java/team7/inplace/place/application/command/PlacesCommand.java @@ -7,6 +7,7 @@ import java.util.Objects; import org.springframework.data.domain.Pageable; import team7.inplace.place.domain.Place; +import team7.inplace.video.presentation.dto.VideoSearchParams; public class PlacesCommand { @@ -19,6 +20,17 @@ public record PlacesCoordinateCommand( String latitude, Pageable pageable ) { + public static PlacesCoordinateCommand from(VideoSearchParams videoSearchParams, Pageable pageable) { + return new PlacesCoordinateCommand( + videoSearchParams.topLeftLongitude(), + videoSearchParams.topLeftLatitude(), + videoSearchParams.bottomRightLatitude(), + videoSearchParams.bottomRightLatitude(), + videoSearchParams.longitude(), + videoSearchParams.latitude(), + pageable + ); + } } public record PlacesFilterParamsCommand( diff --git a/src/main/java/team7/inplace/video/presentation/dto/VideoSearchParams.java b/src/main/java/team7/inplace/video/presentation/dto/VideoSearchParams.java index e56c21cc..6efcb0d7 100644 --- a/src/main/java/team7/inplace/video/presentation/dto/VideoSearchParams.java +++ b/src/main/java/team7/inplace/video/presentation/dto/VideoSearchParams.java @@ -1,6 +1,10 @@ package team7.inplace.video.presentation.dto; public record VideoSearchParams( + String topLeftLongitude, + String topLeftLatitude, + String bottomRightLongitude, + String bottomRightLatitude, String longitude, String latitude ) { From fb85dcf8523461016660f5990187f1aed68bfcb6 Mon Sep 17 00:00:00 2001 From: BaeJunho Date: Fri, 11 Oct 2024 19:17:06 +0900 Subject: [PATCH 36/40] =?UTF-8?q?[refactor]=20Facade=20=ED=8C=A8=ED=84=B4?= =?UTF-8?q?=20=EB=8F=84=EC=9E=85=20=EB=B0=8F=20Place=20Nullable=20?= =?UTF-8?q?=EC=B2=B4=ED=81=AC=20=EB=8F=84=EC=9E=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../video/application/VideoFacade.java | 22 +++++++++++ .../video/application/VideoService.java | 38 +++++++++---------- .../video/presentation/VideoController.java | 4 +- 3 files changed, 42 insertions(+), 22 deletions(-) diff --git a/src/main/java/team7/inplace/video/application/VideoFacade.java b/src/main/java/team7/inplace/video/application/VideoFacade.java index 2e4712f7..a4bd2a14 100644 --- a/src/main/java/team7/inplace/video/application/VideoFacade.java +++ b/src/main/java/team7/inplace/video/application/VideoFacade.java @@ -2,17 +2,26 @@ import java.util.List; import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; import org.springframework.transaction.annotation.Transactional; +import org.springframework.util.ObjectUtils; import team7.inplace.global.annotation.Facade; +import team7.inplace.global.exception.InplaceException; +import team7.inplace.global.exception.code.AuthorizationErrorCode; import team7.inplace.place.application.PlaceService; import team7.inplace.place.application.command.PlacesCommand; +import team7.inplace.security.util.AuthorizationUtil; +import team7.inplace.user.application.UserService; import team7.inplace.video.application.command.VideoCommand; +import team7.inplace.video.application.dto.VideoInfo; @Facade @RequiredArgsConstructor public class VideoFacade { private final VideoService videoService; private final PlaceService placeService; + private final UserService userService; @Transactional public void createVideos(List videoCommands, List placeCommands) { @@ -20,4 +29,17 @@ public void createVideos(List videoCommands, List getVideosByMyInfluencer(Pageable pageable){ + // User 정보를 쿠키에서 추출 + Long userId = AuthorizationUtil.getUserId(); + // 토큰 정보에 대한 검증 + if (ObjectUtils.isEmpty(userId)) { + throw InplaceException.of(AuthorizationErrorCode.TOKEN_IS_EMPTY); + } + // 유저 정보를 이용하여 유저가 좋아요를 누른 인플루언서 id 리스트를 조회 + List influencerIds = userService.getInfluencerIdsByUsername(userId); + // 인플루언서 id를 사용하여 영상을 조회 + return videoService.getVideosByMyInfluencer(influencerIds, pageable); + } } diff --git a/src/main/java/team7/inplace/video/application/VideoService.java b/src/main/java/team7/inplace/video/application/VideoService.java index 9129fb3a..868d7864 100644 --- a/src/main/java/team7/inplace/video/application/VideoService.java +++ b/src/main/java/team7/inplace/video/application/VideoService.java @@ -7,15 +7,13 @@ import org.springframework.data.domain.PageImpl; import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Service; -import org.springframework.util.ObjectUtils; import team7.inplace.global.exception.InplaceException; -import team7.inplace.global.exception.code.AuthorizationErrorCode; +import team7.inplace.global.exception.code.PlaceErrorCode; +import team7.inplace.global.exception.code.VideoErrorCode; import team7.inplace.influencer.persistence.InfluencerRepository; import team7.inplace.place.application.dto.PlaceForVideo; import team7.inplace.place.domain.Place; import team7.inplace.place.persistence.PlaceRepository; -import team7.inplace.security.util.AuthorizationUtil; -import team7.inplace.user.application.UserService; import team7.inplace.video.application.command.VideoCommand.Create; import team7.inplace.video.application.dto.VideoInfo; import team7.inplace.video.domain.Video; @@ -28,22 +26,29 @@ public class VideoService { private final VideoRepository videoRepository; private final PlaceRepository placeRepository; private final InfluencerRepository influencerRepository; - private final UserService userService; public Page getVideosBySurround(VideoSearchParams videoSearchParams, Pageable pageable) { - Page places = placeRepository.getPlacesByDistance( + // Place 엔티티 조회 + Page places = placeRepository.getPlacesByDistanceAndFilters( + videoSearchParams.topLeftLongitude(), + videoSearchParams.topLeftLatitude(), + videoSearchParams.bottomRightLongitude(), + videoSearchParams.bottomRightLatitude(), videoSearchParams.longitude(), videoSearchParams.latitude(), + new ArrayList<>(), + new ArrayList<>(), pageable ); - + // 조회된 엔티티가 비어있는지 아닌지 확인 + if(places.isEmpty()){ + throw InplaceException.of(PlaceErrorCode.NOT_FOUND); + } + // 장소를 기준으로 비디오 엔티티 조회 ( 장소 별로 가장 최근 비디오 하나 씩 ) List