From e939cef26aaa2e671f739d7318e362c893052709 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=95=88=EC=A0=95=ED=9B=84?= Date: Tue, 23 Jul 2024 20:19:29 +0900 Subject: [PATCH 1/7] =?UTF-8?q?feat:=20existYn=20=EC=97=AC=EB=B6=80=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 --- .github/workflows/cd.yml | 2 +- .../user/application/LoginUseCase.java | 21 ++++++++++++++----- .../coremodule/user/dto/LoginAddResponse.java | 1 + 3 files changed, 18 insertions(+), 6 deletions(-) diff --git a/.github/workflows/cd.yml b/.github/workflows/cd.yml index 71d484a..f974b36 100644 --- a/.github/workflows/cd.yml +++ b/.github/workflows/cd.yml @@ -2,7 +2,7 @@ name: Backend CD # actions 이름 on: push: - branches: [ feat/error-fix ] + branches: [ feat/home ] jobs: deploy: diff --git a/api-module/src/main/java/com/likelion/apimodule/user/application/LoginUseCase.java b/api-module/src/main/java/com/likelion/apimodule/user/application/LoginUseCase.java index 82cfd20..b04a648 100644 --- a/api-module/src/main/java/com/likelion/apimodule/user/application/LoginUseCase.java +++ b/api-module/src/main/java/com/likelion/apimodule/user/application/LoginUseCase.java @@ -13,6 +13,8 @@ import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; +import java.util.Optional; + @Service @RequiredArgsConstructor public class LoginUseCase { @@ -23,17 +25,26 @@ public class LoginUseCase { @Transactional(propagation = Propagation.REQUIRES_NEW) public LoginAddResponse kakaoLogin(final KakaoLoginRequest kakaoLoginRequest) { + // ID 토큰으로 찾아온 유저 정보 final OidcDecodePayload oidcDecodePayload = kakaoIdTokenDecodeService.getPayloadFromIdToken(kakaoLoginRequest.idToken()); - final User user = userRepository.findBySubId(oidcDecodePayload.sub()) - .orElseGet(() -> createNewKakaoUser(oidcDecodePayload)); + // User 존재 여부 확인 및 조회 + final Optional optionalUser = userRepository.findBySubId(oidcDecodePayload.sub()); + final boolean existYn = optionalUser.isPresent(); + + // 유저가 존재하지 않으면 새로운 유저 생성 + final User user = optionalUser.orElseGet(() -> createNewKakaoUser(oidcDecodePayload)); - return new LoginAddResponse(user.getName(), user.getPicture(), - jwtUtil.createJwtAccessToken(oidcDecodePayload.email(), oidcDecodePayload.sub()), - jwtUtil.createJwtRefreshToken(oidcDecodePayload.email(), oidcDecodePayload.sub())); + // JWT 토큰 생성 + final String accessToken = jwtUtil.createJwtAccessToken(oidcDecodePayload.email(), oidcDecodePayload.sub()); + final String refreshToken = jwtUtil.createJwtRefreshToken(oidcDecodePayload.email(), oidcDecodePayload.sub()); + + // 응답 객체 생성 및 반환 + return new LoginAddResponse(user.getName(), user.getPicture(), existYn, accessToken, refreshToken); } + private User createNewKakaoUser(final OidcDecodePayload oidcDecodePayload) { final User newUser = User.createSocialUser(oidcDecodePayload.sub(), oidcDecodePayload.nickname(), oidcDecodePayload.picture(), oidcDecodePayload.email()); diff --git a/core-module/src/main/java/com/likelion/coremodule/user/dto/LoginAddResponse.java b/core-module/src/main/java/com/likelion/coremodule/user/dto/LoginAddResponse.java index e67e389..95518e9 100644 --- a/core-module/src/main/java/com/likelion/coremodule/user/dto/LoginAddResponse.java +++ b/core-module/src/main/java/com/likelion/coremodule/user/dto/LoginAddResponse.java @@ -5,6 +5,7 @@ public record LoginAddResponse( String nickname, String picture, + Boolean existYn, @Schema(description = "액세스 토큰", example = "eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ0ZXN0QGdtYWlsLmNvbSIs", defaultValue = "eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ0ZXN0QGdtYWlsLmNvbSIs") String accessToken, @Schema(description = "리프레시 토큰", example = "eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ0ZXN0QGdtYWlsLmNvbSIs", defaultValue = "eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ0ZXN0QGdtYWlsLmNvbSIs") From 76efcc671a1ee71359051b72f5b5ee582cc874c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=95=88=EC=A0=95=ED=9B=84?= Date: Wed, 24 Jul 2024 11:11:04 +0900 Subject: [PATCH 2/7] =?UTF-8?q?fix:=20=EC=A4=91=EB=B3=B5=20=EC=BB=AC?= =?UTF-8?q?=EB=9F=BC=20=EC=9D=B4=EC=8A=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../market/application/MarketInfoUseCase.java | 4 +-- .../market/presentation/MarketController.java | 6 ++-- .../store/application/StoreInfoUseCase.java | 32 +++++++------------ 3 files changed, 16 insertions(+), 26 deletions(-) diff --git a/api-module/src/main/java/com/likelion/apimodule/market/application/MarketInfoUseCase.java b/api-module/src/main/java/com/likelion/apimodule/market/application/MarketInfoUseCase.java index a8dc60f..85c0260 100644 --- a/api-module/src/main/java/com/likelion/apimodule/market/application/MarketInfoUseCase.java +++ b/api-module/src/main/java/com/likelion/apimodule/market/application/MarketInfoUseCase.java @@ -24,9 +24,9 @@ public class MarketInfoUseCase { private final StoreQueryService storeQueryService; private final JwtUtil jwtUtil; - public MarketInfo findMarketInfo() { + public MarketInfo findMarketInfo(Long marketId) { - Market market = marketQueryService.findMarket(1L); + Market market = marketQueryService.findMarket(marketId); return new MarketInfo( market.getId(), diff --git a/api-module/src/main/java/com/likelion/apimodule/market/presentation/MarketController.java b/api-module/src/main/java/com/likelion/apimodule/market/presentation/MarketController.java index cd8d133..52681e7 100644 --- a/api-module/src/main/java/com/likelion/apimodule/market/presentation/MarketController.java +++ b/api-module/src/main/java/com/likelion/apimodule/market/presentation/MarketController.java @@ -28,7 +28,7 @@ public class MarketController { private final StoreInfoUseCase storeInfoUseCase; // 시장 정보 - @GetMapping("/info") + @GetMapping("/{marketId}/info") @ApiResponses( value = { @ApiResponse( @@ -39,9 +39,9 @@ public class MarketController { } ) @Operation(summary = "시장 정보 확인 API", description = "시장 정보 확인 API 입니다.") - public ApplicationResponse getMarketInfo() { + public ApplicationResponse getMarketInfo(@PathVariable Long marketId) { - MarketInfo infos = marketInfoUseCase.findMarketInfo(); + MarketInfo infos = marketInfoUseCase.findMarketInfo(marketId); return ApplicationResponse.ok(infos); } diff --git a/api-module/src/main/java/com/likelion/apimodule/store/application/StoreInfoUseCase.java b/api-module/src/main/java/com/likelion/apimodule/store/application/StoreInfoUseCase.java index e02c9cb..959882c 100644 --- a/api-module/src/main/java/com/likelion/apimodule/store/application/StoreInfoUseCase.java +++ b/api-module/src/main/java/com/likelion/apimodule/store/application/StoreInfoUseCase.java @@ -35,12 +35,10 @@ public class StoreInfoUseCase { private final JwtUtil jwtUtil; public List findStoreInfo() { - List storeList = storeQueryService.findAllStore(); List storeInfoList = new ArrayList<>(); for (Store store : storeList) { - List menus = menuQueryService.findMenusByStoreId(store.getId()); List menuDetails = menus.stream() .map(menu -> new MenuDetailDTO( @@ -51,32 +49,24 @@ public List findStoreInfo() { menu.getImageUrl())) .toList(); - for (Menu menu : menus) { - - // 리뷰 관련 cnt, avg - List reviews = reviewQueryService.findReviewsByStoreId(menu.getId()); - final StoreInfo storeInfo = getStoreInfo(store, reviews, menuDetails); - storeInfoList.add(storeInfo); - } + // 리뷰 관련 cnt, avg + List reviews = reviewQueryService.findReviewsByStoreId(store.getId()); + final StoreInfo storeInfo = getStoreInfo(store, reviews, menuDetails); + storeInfoList.add(storeInfo); } return storeInfoList; } - private static StoreInfo getStoreInfo(Store store, List reviews, List menuDetails) { - int totalReviews = reviews.size(); - double totalRating = 0.0; - for (Review review : reviews) { - totalRating += review.getRating(); - } - - double averageRating = totalReviews > 0 ? totalRating / totalReviews : 0.0; + private StoreInfo getStoreInfo(Store store, List reviews, List menuDetails) { + int reviewCount = reviews.size(); + double ratingAvg = reviews.stream().mapToDouble(Review::getRating).average().orElse(0.0); - StoreInfo storeInfo = new StoreInfo( + return new StoreInfo( store.getId(), store.getName(), - totalReviews, - averageRating, + reviewCount, + ratingAvg, store.getLocation(), store.getOpenHours(), store.getCloseHours(), @@ -85,9 +75,9 @@ private static StoreInfo getStoreInfo(Store store, List reviews, List findStoreByFilter(String search, String category) { List response = new ArrayList<>(); From f4712a3d6912567cb5ba70a4b121cb67e0ceec04 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=95=88=EC=A0=95=ED=9B=84?= Date: Wed, 24 Jul 2024 13:57:48 +0900 Subject: [PATCH 3/7] fix: cart error-fix api-module --- .../cart/application/CartFindUseCase.java | 1 + .../cart/application/CartSaveUseCase.java | 29 +++++++++++++-- .../likelion/apimodule/cart/dto/CartInfo.java | 1 + .../apimodule/cart/dto/CartUpdateReq.java | 7 ++++ .../cart/presentation/CartController.java | 20 +++++++++++ .../home/application/HomeFindUseCase.java | 4 +++ .../home/presentation/HomeController.java | 36 +++++++++++++++++++ 7 files changed, 96 insertions(+), 2 deletions(-) create mode 100644 api-module/src/main/java/com/likelion/apimodule/cart/dto/CartUpdateReq.java create mode 100644 api-module/src/main/java/com/likelion/apimodule/home/application/HomeFindUseCase.java create mode 100644 api-module/src/main/java/com/likelion/apimodule/home/presentation/HomeController.java diff --git a/api-module/src/main/java/com/likelion/apimodule/cart/application/CartFindUseCase.java b/api-module/src/main/java/com/likelion/apimodule/cart/application/CartFindUseCase.java index 2245c34..f362b94 100644 --- a/api-module/src/main/java/com/likelion/apimodule/cart/application/CartFindUseCase.java +++ b/api-module/src/main/java/com/likelion/apimodule/cart/application/CartFindUseCase.java @@ -40,6 +40,7 @@ public List findAllCarts(String accessToken) { Store store = storeQueryService.findStoreById(menu.getStore().getId()); CartInfo cartInfo = new CartInfo( + cart.getId(), store.getName(), menu.getName(), menu.getPrice(), diff --git a/api-module/src/main/java/com/likelion/apimodule/cart/application/CartSaveUseCase.java b/api-module/src/main/java/com/likelion/apimodule/cart/application/CartSaveUseCase.java index 1222000..0dfd467 100644 --- a/api-module/src/main/java/com/likelion/apimodule/cart/application/CartSaveUseCase.java +++ b/api-module/src/main/java/com/likelion/apimodule/cart/application/CartSaveUseCase.java @@ -1,8 +1,11 @@ package com.likelion.apimodule.cart.application; import com.likelion.apimodule.cart.dto.CartSaveReq; +import com.likelion.apimodule.cart.dto.CartUpdateReq; import com.likelion.apimodule.security.util.JwtUtil; import com.likelion.coremodule.cart.domain.Cart; +import com.likelion.coremodule.cart.exception.CartErrorCode; +import com.likelion.coremodule.cart.exception.CartException; import com.likelion.coremodule.cart.service.CartQueryService; import com.likelion.coremodule.menu.domain.Menu; import com.likelion.coremodule.menu.service.MenuQueryService; @@ -12,6 +15,8 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import java.util.List; + @Service @RequiredArgsConstructor @Transactional @@ -22,6 +27,10 @@ public class CartSaveUseCase { private final UserQueryService userQueryService; private final MenuQueryService menuQueryService; + public Integer findMyCartCount(Long userId, Long menuId) { + return cartQueryService.findCartByUserIdAndMenuId(userId, menuId); + } + public void saveMyCart(String accessToken, CartSaveReq saveReq) { String email = jwtUtil.getEmail(accessToken); @@ -29,8 +38,24 @@ public void saveMyCart(String accessToken, CartSaveReq saveReq) { Menu menu = menuQueryService.findMenuById(saveReq.menuId()); - final Cart cart = Cart.builder().user(user).menu(menu).quantity(saveReq.quantity()).build(); - cartQueryService.saveCart(cart); + if (findMyCartCount(user.getUserId(), menu.getId()) >= 1) { + throw new CartException(CartErrorCode.NO_CART_INFO); + } else { + final Cart cart = Cart.builder().user(user).menu(menu).quantity(saveReq.quantity()).build(); + cartQueryService.saveCart(cart); + } + } + + public void updateMyCart(String accessToken, List updateReqs) { + + String email = jwtUtil.getEmail(accessToken); + User user = userQueryService.findByEmail(email); + + for (CartUpdateReq req : updateReqs) { + + Cart cart = cartQueryService.findCartByUserIdAndCartId(user.getUserId(), req.cartId()); + cart.setCartQuantity(req.quantity()); + } } public void deleteMyCart(String accessToken, Long cartId) { diff --git a/api-module/src/main/java/com/likelion/apimodule/cart/dto/CartInfo.java b/api-module/src/main/java/com/likelion/apimodule/cart/dto/CartInfo.java index a3d4c02..d50ff6b 100644 --- a/api-module/src/main/java/com/likelion/apimodule/cart/dto/CartInfo.java +++ b/api-module/src/main/java/com/likelion/apimodule/cart/dto/CartInfo.java @@ -1,6 +1,7 @@ package com.likelion.apimodule.cart.dto; public record CartInfo( + Long cartid, // cart String storeName, // store String menuName, // menu Integer price, // menu diff --git a/api-module/src/main/java/com/likelion/apimodule/cart/dto/CartUpdateReq.java b/api-module/src/main/java/com/likelion/apimodule/cart/dto/CartUpdateReq.java new file mode 100644 index 0000000..9cf32bd --- /dev/null +++ b/api-module/src/main/java/com/likelion/apimodule/cart/dto/CartUpdateReq.java @@ -0,0 +1,7 @@ +package com.likelion.apimodule.cart.dto; + +public record CartUpdateReq( + Long cartId, + Integer quantity +) { +} diff --git a/api-module/src/main/java/com/likelion/apimodule/cart/presentation/CartController.java b/api-module/src/main/java/com/likelion/apimodule/cart/presentation/CartController.java index 4e24955..c0cf181 100644 --- a/api-module/src/main/java/com/likelion/apimodule/cart/presentation/CartController.java +++ b/api-module/src/main/java/com/likelion/apimodule/cart/presentation/CartController.java @@ -4,6 +4,7 @@ import com.likelion.apimodule.cart.application.CartSaveUseCase; import com.likelion.apimodule.cart.dto.CartInfo; import com.likelion.apimodule.cart.dto.CartSaveReq; +import com.likelion.apimodule.cart.dto.CartUpdateReq; import com.likelion.commonmodule.exception.common.ApplicationResponse; import com.likelion.commonmodule.security.util.AuthConsts; import io.swagger.v3.oas.annotations.Operation; @@ -64,6 +65,25 @@ public ApplicationResponse saveMyCart(@RequestHeader(AuthConsts.ACCESS_T return ApplicationResponse.ok("장바구니 저장 완료"); } + // 장바구니 추가 + @PutMapping + @ApiResponses( + value = { + @ApiResponse( + responseCode = "200", + description = "나의 장바구니 추가 성공", + useReturnTypeSchema = true + ) + } + ) + @Operation(summary = "나의 장바구니 추가 API", description = "나의 장바구니 추가 API 입니다.") + public ApplicationResponse updateMyCart(@RequestHeader(AuthConsts.ACCESS_TOKEN_HEADER) String accessToken, + @RequestBody List updateReqs) { + + cartSaveUseCase.updateMyCart(accessToken, updateReqs); + return ApplicationResponse.ok("장바구니 수량 수정 완료"); + } + // 장바구니 삭제 @DeleteMapping("{cartId}/delete") @ApiResponses( diff --git a/api-module/src/main/java/com/likelion/apimodule/home/application/HomeFindUseCase.java b/api-module/src/main/java/com/likelion/apimodule/home/application/HomeFindUseCase.java new file mode 100644 index 0000000..c87486e --- /dev/null +++ b/api-module/src/main/java/com/likelion/apimodule/home/application/HomeFindUseCase.java @@ -0,0 +1,4 @@ +package com.likelion.apimodule.home.application; + +public class HomeFindUseCase { +} diff --git a/api-module/src/main/java/com/likelion/apimodule/home/presentation/HomeController.java b/api-module/src/main/java/com/likelion/apimodule/home/presentation/HomeController.java new file mode 100644 index 0000000..aae53a2 --- /dev/null +++ b/api-module/src/main/java/com/likelion/apimodule/home/presentation/HomeController.java @@ -0,0 +1,36 @@ +package com.likelion.apimodule.home.presentation; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.RequiredArgsConstructor; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RequiredArgsConstructor +@RestController +@RequestMapping("/v1/home") +@Validated +@Tag(name = "Home", description = "Home 관련 API") +public class HomeController { + + // qr 시 시장 조회수 증가 +// @GetMapping("/{marketId}/info") +// @ApiResponses( +// value = { +// @ApiResponse( +// responseCode = "200", +// description = "시장 정보 확인 성공", +// useReturnTypeSchema = true +// ) +// } +// ) +// @Operation(summary = "시장 정보 확인 API", description = "시장 정보 확인 API 입니다.") + + // 시장 리스트 검색 + + // 시장 리스트 나열 +} From 19c9e5b1410564fb06fa51b87a456747de2d5cb8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=95=88=EC=A0=95=ED=9B=84?= Date: Wed, 24 Jul 2024 13:58:04 +0900 Subject: [PATCH 4/7] feat: cart error-fix core-module --- .../likelion/coremodule/cart/domain/Cart.java | 6 ++++- .../cart/exception/CartErrorCode.java | 24 +++++++++++++++++++ .../cart/exception/CartException.java | 22 +++++++++++++++++ .../cart/repository/CartRepository.java | 4 ++++ .../cart/service/CartQueryService.java | 8 +++++++ 5 files changed, 63 insertions(+), 1 deletion(-) create mode 100644 core-module/src/main/java/com/likelion/coremodule/cart/exception/CartErrorCode.java create mode 100644 core-module/src/main/java/com/likelion/coremodule/cart/exception/CartException.java diff --git a/core-module/src/main/java/com/likelion/coremodule/cart/domain/Cart.java b/core-module/src/main/java/com/likelion/coremodule/cart/domain/Cart.java index fb35c5c..8171b93 100644 --- a/core-module/src/main/java/com/likelion/coremodule/cart/domain/Cart.java +++ b/core-module/src/main/java/com/likelion/coremodule/cart/domain/Cart.java @@ -13,7 +13,7 @@ public class Cart { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) - @Column(name = "item_id") + @Column(name = "cart_id") private Long id; @ManyToOne(fetch = FetchType.LAZY) @@ -25,4 +25,8 @@ public class Cart { private Menu menu; private Integer quantity; + + public void setCartQuantity(Integer quantity) { + this.quantity = quantity; + } } diff --git a/core-module/src/main/java/com/likelion/coremodule/cart/exception/CartErrorCode.java b/core-module/src/main/java/com/likelion/coremodule/cart/exception/CartErrorCode.java new file mode 100644 index 0000000..760ad4c --- /dev/null +++ b/core-module/src/main/java/com/likelion/coremodule/cart/exception/CartErrorCode.java @@ -0,0 +1,24 @@ +package com.likelion.coremodule.cart.exception; + +import com.likelion.commonmodule.exception.common.ApiResponse; +import com.likelion.commonmodule.exception.common.BaseErrorCode; +import lombok.AllArgsConstructor; +import lombok.Getter; +import org.springframework.http.HttpStatus; + +@Getter +@AllArgsConstructor +public enum CartErrorCode implements BaseErrorCode { + + NO_CART_INFO(HttpStatus.BAD_REQUEST, "2000", "장바구니 안에 상품이 존재하지 않습니다."); + + private final HttpStatus httpStatus; + private final String code; + private final String message; + + + @Override + public ApiResponse getErrorResponse() { + return null; + } +} diff --git a/core-module/src/main/java/com/likelion/coremodule/cart/exception/CartException.java b/core-module/src/main/java/com/likelion/coremodule/cart/exception/CartException.java new file mode 100644 index 0000000..1709162 --- /dev/null +++ b/core-module/src/main/java/com/likelion/coremodule/cart/exception/CartException.java @@ -0,0 +1,22 @@ +package com.likelion.coremodule.cart.exception; + +import com.likelion.commonmodule.exception.common.BaseErrorCode; +import lombok.Getter; + +@Getter +public class CartException extends RuntimeException { + + private final BaseErrorCode errorCode; + + private final Throwable cause; + + public CartException(BaseErrorCode errorCode) { + this.errorCode = errorCode; + this.cause = null; + } + + public CartException(BaseErrorCode errorCode, Throwable cause) { + this.errorCode = errorCode; + this.cause = cause; + } +} \ No newline at end of file diff --git a/core-module/src/main/java/com/likelion/coremodule/cart/repository/CartRepository.java b/core-module/src/main/java/com/likelion/coremodule/cart/repository/CartRepository.java index 5c614cd..a9da55e 100644 --- a/core-module/src/main/java/com/likelion/coremodule/cart/repository/CartRepository.java +++ b/core-module/src/main/java/com/likelion/coremodule/cart/repository/CartRepository.java @@ -9,5 +9,9 @@ public interface CartRepository extends JpaRepository { List findCartsByUserUserId(Long userId); + int countCartsByUserUserIdAndMenuId(Long userId, Long menuId); + + Cart findCartByUserUserIdAndId(Long userId, Long cartId); + void deleteCartByIdAndUserUserId(Long cartId, Long userId); } diff --git a/core-module/src/main/java/com/likelion/coremodule/cart/service/CartQueryService.java b/core-module/src/main/java/com/likelion/coremodule/cart/service/CartQueryService.java index ea680c0..ed404e0 100644 --- a/core-module/src/main/java/com/likelion/coremodule/cart/service/CartQueryService.java +++ b/core-module/src/main/java/com/likelion/coremodule/cart/service/CartQueryService.java @@ -21,6 +21,14 @@ public List findCartsByUserId(Long userId) { return cartRepository.findCartsByUserUserId(userId); } + public int findCartByUserIdAndMenuId(Long userId, Long menuId) { + return cartRepository.countCartsByUserUserIdAndMenuId(userId, menuId); + } + + public Cart findCartByUserIdAndCartId(Long userId, Long cartId) { + return cartRepository.findCartByUserUserIdAndId(userId, cartId); + } + public void deleteCartByUserIdAndCartId(Long userId, Long cartId) { cartRepository.deleteCartByIdAndUserUserId(cartId, userId); From 25152dea71c660da086295b3c87dc6ad65555630 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=95=88=EC=A0=95=ED=9B=84?= Date: Thu, 25 Jul 2024 18:27:34 +0900 Subject: [PATCH 5/7] =?UTF-8?q?fix:=20storeid=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../apimodule/market/application/MarketInfoUseCase.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api-module/src/main/java/com/likelion/apimodule/market/application/MarketInfoUseCase.java b/api-module/src/main/java/com/likelion/apimodule/market/application/MarketInfoUseCase.java index 85c0260..62215d8 100644 --- a/api-module/src/main/java/com/likelion/apimodule/market/application/MarketInfoUseCase.java +++ b/api-module/src/main/java/com/likelion/apimodule/market/application/MarketInfoUseCase.java @@ -52,7 +52,7 @@ public List findVisitList() { for (VisitList i : visitLists) { Long id = i.getId(); - Store store = storeQueryService.findStoreById(id); + Store store = storeQueryService.findStoreById(i.getStore().getId()); VisitListInfo visitListInfo = new VisitListInfo(id, store.getId(), store.getName(), i.getVisit_status()); visitListInfos.add(visitListInfo); From ccc86ec25fa8d93f8879d2090360299707e9102f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=95=88=EC=A0=95=ED=9B=84?= Date: Sun, 28 Jul 2024 17:53:16 +0900 Subject: [PATCH 6/7] feat: home feature api-module --- .../home/application/HomeFindUseCase.java | 90 +++++++++++++++++++ .../home/application/HomeSaveUseCase.java | 39 ++++++++ .../likelion/apimodule/home/dto/HomeInfo.java | 9 ++ .../apimodule/home/dto/HotListHome.java | 8 ++ .../apimodule/home/dto/TotalSumCompare.java | 7 ++ .../apimodule/home/dto/VisitListHome.java | 12 +++ .../home/presentation/HomeController.java | 64 +++++++++++-- .../store/application/StoreInfoUseCase.java | 8 +- 8 files changed, 227 insertions(+), 10 deletions(-) create mode 100644 api-module/src/main/java/com/likelion/apimodule/home/application/HomeSaveUseCase.java create mode 100644 api-module/src/main/java/com/likelion/apimodule/home/dto/HomeInfo.java create mode 100644 api-module/src/main/java/com/likelion/apimodule/home/dto/HotListHome.java create mode 100644 api-module/src/main/java/com/likelion/apimodule/home/dto/TotalSumCompare.java create mode 100644 api-module/src/main/java/com/likelion/apimodule/home/dto/VisitListHome.java diff --git a/api-module/src/main/java/com/likelion/apimodule/home/application/HomeFindUseCase.java b/api-module/src/main/java/com/likelion/apimodule/home/application/HomeFindUseCase.java index c87486e..7d85c8a 100644 --- a/api-module/src/main/java/com/likelion/apimodule/home/application/HomeFindUseCase.java +++ b/api-module/src/main/java/com/likelion/apimodule/home/application/HomeFindUseCase.java @@ -1,4 +1,94 @@ package com.likelion.apimodule.home.application; +import com.likelion.apimodule.home.dto.HomeInfo; +import com.likelion.apimodule.home.dto.HotListHome; +import com.likelion.apimodule.home.dto.VisitListHome; +import com.likelion.apimodule.security.util.JwtUtil; +import com.likelion.coremodule.market.domain.Market; +import com.likelion.coremodule.market.domain.MarketQrVisit; +import com.likelion.coremodule.market.service.HomeQueryService; +import com.likelion.coremodule.market.service.MarketQueryService; +import com.likelion.coremodule.store.domain.Store; +import com.likelion.coremodule.store.domain.StoreVisit; +import com.likelion.coremodule.store.service.StoreQueryService; +import com.likelion.coremodule.user.application.UserQueryService; +import com.likelion.coremodule.user.domain.User; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; + +@Service +@RequiredArgsConstructor public class HomeFindUseCase { + + private final HomeQueryService homeQueryService; + private final MarketQueryService marketQueryService; + private final StoreQueryService storeQueryService; + private final JwtUtil jwtUtil; + private final UserQueryService userQueryService; + + public HomeInfo findMarketLists(String accessToken) { + + String email = jwtUtil.getEmail(accessToken); + User user = userQueryService.findByEmail(email); + + List marketList = marketQueryService.findAllMarkets(); + + List visitListHomeList = new ArrayList<>(); + List hotListHomeList = new ArrayList<>(); + + for (Market market : marketList) { + List storeList = storeQueryService.findStoresByMarketId(market.getId()); + int totalStoreVisits = 0; + + for (Store store : storeList) { + List storeVisitList = storeQueryService.findStoreVisitsByUserIdAndStoreId(user.getUserId(), store.getId()); + totalStoreVisits += storeVisitList.size(); + } + + VisitListHome visitListHome = new VisitListHome( + market.getName(), + market.getLocation(), + storeList.size(), + totalStoreVisits, + market.getCreatedAt().toLocalDate() + ); + visitListHomeList.add(visitListHome); + + MarketQrVisit marketQrVisit = marketQueryService.findMarketVisit(market.getId()); + + HotListHome hotListHome = new HotListHome( + market.getName(), + market.getLocation(), + marketQrVisit.getQrVisit() + ); + hotListHomeList.add(hotListHome); + } + + // VisitListHome 리스트를 날짜 기준으로 정렬 + visitListHomeList.sort(Comparator.comparing(VisitListHome::visitDate)); + // HotListHome 리스트를 qrVisit 순으로 정렬 + hotListHomeList.sort(Comparator.comparingInt(HotListHome::totalQrVisit)); + + return new HomeInfo(visitListHomeList, hotListHomeList); + } + + public String findNearestMarket(Integer xloc, Integer yloc) { + List marketList = marketQueryService.findAllMarkets(); + String nearestMarketName = null; + double shortestDistance = Double.MAX_VALUE; + + for (Market market : marketList) { + double distance = Math.sqrt(Math.pow(market.getXloc() - xloc, 2) + Math.pow(market.getYloc() - yloc, 2)); + if (distance < shortestDistance) { + shortestDistance = distance; + nearestMarketName = market.getName(); + } + } + return nearestMarketName; + } + } diff --git a/api-module/src/main/java/com/likelion/apimodule/home/application/HomeSaveUseCase.java b/api-module/src/main/java/com/likelion/apimodule/home/application/HomeSaveUseCase.java new file mode 100644 index 0000000..78f9d5a --- /dev/null +++ b/api-module/src/main/java/com/likelion/apimodule/home/application/HomeSaveUseCase.java @@ -0,0 +1,39 @@ +package com.likelion.apimodule.home.application; + +import com.likelion.apimodule.security.util.JwtUtil; +import com.likelion.coremodule.market.domain.Market; +import com.likelion.coremodule.market.domain.MarketQrVisit; +import com.likelion.coremodule.market.service.HomeQueryService; +import com.likelion.coremodule.market.service.MarketQueryService; +import com.likelion.coremodule.store.domain.Store; +import com.likelion.coremodule.store.domain.StoreVisit; +import com.likelion.coremodule.store.service.StoreQueryService; +import com.likelion.coremodule.user.application.UserQueryService; +import com.likelion.coremodule.user.domain.User; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +@Service +@RequiredArgsConstructor +public class HomeSaveUseCase { + + private final HomeQueryService homeQueryService; + private final UserQueryService userQueryService; + private final StoreQueryService storeQueryService; + private final MarketQueryService marketQueryService; + private final JwtUtil jwtUtil; + + public void updateQrVisit(String accessToken, Long storeId) { + + String email = jwtUtil.getEmail(accessToken); + User user = userQueryService.findByEmail(email); + + Store store = storeQueryService.findStoreById(storeId); + Market market = marketQueryService.findMarket(store.getMarket().getId()); + + // 방문여부 업데이트 + storeQueryService.saveVisitYn(store, user); + // qr 조회수 증가 + homeQueryService.updateQrVisit(user, market); + } +} diff --git a/api-module/src/main/java/com/likelion/apimodule/home/dto/HomeInfo.java b/api-module/src/main/java/com/likelion/apimodule/home/dto/HomeInfo.java new file mode 100644 index 0000000..f1dadc3 --- /dev/null +++ b/api-module/src/main/java/com/likelion/apimodule/home/dto/HomeInfo.java @@ -0,0 +1,9 @@ +package com.likelion.apimodule.home.dto; + +import java.util.List; + +public record HomeInfo( + List visitListHomeList, + List hotListHomeList +) { +} diff --git a/api-module/src/main/java/com/likelion/apimodule/home/dto/HotListHome.java b/api-module/src/main/java/com/likelion/apimodule/home/dto/HotListHome.java new file mode 100644 index 0000000..7db4b66 --- /dev/null +++ b/api-module/src/main/java/com/likelion/apimodule/home/dto/HotListHome.java @@ -0,0 +1,8 @@ +package com.likelion.apimodule.home.dto; + +public record HotListHome( + String marketName, + String location, + Integer totalQrVisit +) { +} diff --git a/api-module/src/main/java/com/likelion/apimodule/home/dto/TotalSumCompare.java b/api-module/src/main/java/com/likelion/apimodule/home/dto/TotalSumCompare.java new file mode 100644 index 0000000..20d56e7 --- /dev/null +++ b/api-module/src/main/java/com/likelion/apimodule/home/dto/TotalSumCompare.java @@ -0,0 +1,7 @@ +package com.likelion.apimodule.home.dto; + +public record TotalSumCompare( + String name, + Integer sum +) { +} diff --git a/api-module/src/main/java/com/likelion/apimodule/home/dto/VisitListHome.java b/api-module/src/main/java/com/likelion/apimodule/home/dto/VisitListHome.java new file mode 100644 index 0000000..0aa8ae4 --- /dev/null +++ b/api-module/src/main/java/com/likelion/apimodule/home/dto/VisitListHome.java @@ -0,0 +1,12 @@ +package com.likelion.apimodule.home.dto; + +import java.time.LocalDate; + +public record VisitListHome( + String marketName, + String location, + Integer visitedStore, + Integer totalStore, + LocalDate visitDate +) { +} diff --git a/api-module/src/main/java/com/likelion/apimodule/home/presentation/HomeController.java b/api-module/src/main/java/com/likelion/apimodule/home/presentation/HomeController.java index aae53a2..1044c73 100644 --- a/api-module/src/main/java/com/likelion/apimodule/home/presentation/HomeController.java +++ b/api-module/src/main/java/com/likelion/apimodule/home/presentation/HomeController.java @@ -1,14 +1,17 @@ package com.likelion.apimodule.home.presentation; +import com.likelion.apimodule.home.application.HomeFindUseCase; +import com.likelion.apimodule.home.application.HomeSaveUseCase; +import com.likelion.apimodule.home.dto.HomeInfo; +import com.likelion.commonmodule.exception.common.ApplicationResponse; +import com.likelion.commonmodule.security.util.AuthConsts; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.responses.ApiResponses; import io.swagger.v3.oas.annotations.tags.Tag; import lombok.RequiredArgsConstructor; import org.springframework.validation.annotation.Validated; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; @RequiredArgsConstructor @RestController @@ -17,20 +20,65 @@ @Tag(name = "Home", description = "Home 관련 API") public class HomeController { + private final HomeFindUseCase homeFindUseCase; + private final HomeSaveUseCase homeSaveUseCase; + // qr 시 시장 조회수 증가 -// @GetMapping("/{marketId}/info") + @PostMapping("/{storeId}/qrvisit") + public ApplicationResponse updateQrVisit(@RequestHeader(AuthConsts.ACCESS_TOKEN_HEADER) String accessToken, + @PathVariable Long storeId) { + + homeSaveUseCase.updateQrVisit(accessToken, storeId); + return ApplicationResponse.ok("qr 조회수 증가 + 방문 상태 변경"); + } + + // 시장 리스트 나열 + @GetMapping + @ApiResponses( + value = { + @ApiResponse( + responseCode = "200", + description = "시장 정보 확인 성공", + useReturnTypeSchema = true + ) + } + ) + @Operation(summary = "시장 정보 확인 API", description = "시장 정보 확인 API 입니다.") + public ApplicationResponse findHomeInfo(@RequestHeader(AuthConsts.ACCESS_TOKEN_HEADER) String accessToken) { + + final HomeInfo marketLists = homeFindUseCase.findMarketLists(accessToken); + return ApplicationResponse.ok(marketLists); + } + + // 시장 리스트 검색 +// @GetMapping // @ApiResponses( // value = { // @ApiResponse( // responseCode = "200", -// description = "시장 정보 확인 성공", +// description = "시장 리스트 검색 성공", // useReturnTypeSchema = true // ) // } // ) -// @Operation(summary = "시장 정보 확인 API", description = "시장 정보 확인 API 입니다.") +// @Operation(summary = "시장 리스트 검색 API", description = "시장 리스트 검색 API 입니다.") +// public ApplicationResponse - // 시장 리스트 검색 + // 가까운 시장 확인 + @GetMapping("/nearmarket") + @ApiResponses( + value = { + @ApiResponse( + responseCode = "200", + description = "시장 정보 확인 성공", + useReturnTypeSchema = true + ) + } + ) + @Operation(summary = "시장 정보 확인 API", description = "시장 정보 확인 API 입니다.") + public ApplicationResponse findNearestMarket(@RequestParam Integer xloc, @RequestParam Integer yloc) { - // 시장 리스트 나열 + String nearestMarket = homeFindUseCase.findNearestMarket(xloc, yloc); + return ApplicationResponse.ok(nearestMarket); + } } diff --git a/api-module/src/main/java/com/likelion/apimodule/store/application/StoreInfoUseCase.java b/api-module/src/main/java/com/likelion/apimodule/store/application/StoreInfoUseCase.java index 959882c..7b0c264 100644 --- a/api-module/src/main/java/com/likelion/apimodule/store/application/StoreInfoUseCase.java +++ b/api-module/src/main/java/com/likelion/apimodule/store/application/StoreInfoUseCase.java @@ -77,13 +77,17 @@ private StoreInfo getStoreInfo(Store store, List reviews, List findStoreByFilter(String search, String category) { List response = new ArrayList<>(); List storeList = storeQueryService.findAllStore(); if ((search == null || search.isEmpty()) && (category == null || category.isEmpty())) { + + for (Store store : storeList) { + StoreResponse ex = new StoreResponse(store.getId(), store.getName(), store.getCategory(), store.getDescription(), store.getLocation(), store.getOpenHours(), store.getImageUrl()); + response.add(ex); + } return response; } @@ -104,7 +108,7 @@ public List findStoreByFilter(String search, String category) { .toList(); for (Store store : list) { - StoreResponse ex = new StoreResponse(store.getId(), store.getName(), finalStoreCategory, store.getDescription(), store.getLocation(), store.getOpenHours(), store.getImageUrl()); + StoreResponse ex = new StoreResponse(store.getId(), store.getName(), store.getCategory(), store.getDescription(), store.getLocation(), store.getOpenHours(), store.getImageUrl()); response.add(ex); } From 75ec15bd151624ae9180dae8c5a4a0e936fc68d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=95=88=EC=A0=95=ED=9B=84?= Date: Sun, 28 Jul 2024 17:53:29 +0900 Subject: [PATCH 7/7] feat: home feature core-module --- .../coremodule/market/domain/Market.java | 8 +++- .../market/domain/MarketQrVisit.java | 32 ++++++++++++++++ .../repository/MarketQrVisitRepository.java | 9 +++++ .../market/service/HomeQueryService.java | 38 +++++++++++++++++++ .../market/service/MarketQueryService.java | 13 +++++++ .../coremodule/store/domain/Store.java | 5 ++- .../coremodule/store/domain/StoreVisit.java | 33 ++++++++++++++++ .../store/exception/StoreErrorCode.java | 3 +- .../store/repository/StoreRepository.java | 4 ++ .../repository/StoreVisitRepository.java | 15 ++++++++ .../store/service/StoreQueryService.java | 28 +++++++++++++- 11 files changed, 182 insertions(+), 6 deletions(-) create mode 100644 core-module/src/main/java/com/likelion/coremodule/market/domain/MarketQrVisit.java create mode 100644 core-module/src/main/java/com/likelion/coremodule/market/repository/MarketQrVisitRepository.java create mode 100644 core-module/src/main/java/com/likelion/coremodule/market/service/HomeQueryService.java create mode 100644 core-module/src/main/java/com/likelion/coremodule/store/domain/StoreVisit.java create mode 100644 core-module/src/main/java/com/likelion/coremodule/store/repository/StoreVisitRepository.java diff --git a/core-module/src/main/java/com/likelion/coremodule/market/domain/Market.java b/core-module/src/main/java/com/likelion/coremodule/market/domain/Market.java index c3f5929..1efaa5d 100644 --- a/core-module/src/main/java/com/likelion/coremodule/market/domain/Market.java +++ b/core-module/src/main/java/com/likelion/coremodule/market/domain/Market.java @@ -1,15 +1,16 @@ package com.likelion.coremodule.market.domain; +import com.likelion.commonmodule.exception.common.BaseEntity; import jakarta.persistence.*; import lombok.*; @Builder @Getter -@Setter @NoArgsConstructor(access = AccessLevel.PROTECTED) @AllArgsConstructor @Entity -public class Market { +public class Market extends BaseEntity { + @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "market_id") @@ -22,4 +23,7 @@ public class Market { private String location; private String contact; private String imageUrl; + private Integer xloc; + private Integer yloc; + } diff --git a/core-module/src/main/java/com/likelion/coremodule/market/domain/MarketQrVisit.java b/core-module/src/main/java/com/likelion/coremodule/market/domain/MarketQrVisit.java new file mode 100644 index 0000000..3e8e2e8 --- /dev/null +++ b/core-module/src/main/java/com/likelion/coremodule/market/domain/MarketQrVisit.java @@ -0,0 +1,32 @@ +package com.likelion.coremodule.market.domain; + +import com.likelion.coremodule.user.domain.User; +import jakarta.persistence.*; +import lombok.*; + +@Builder +@Getter +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@AllArgsConstructor +@Entity +public class MarketQrVisit { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "marketqrvisit_id") + private Long id; + + private Integer qrVisit; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "user_id") + private User user; + + @OneToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "market_id") + private Market market; + + public void updateQrVisit() { + this.qrVisit += 1; + } +} diff --git a/core-module/src/main/java/com/likelion/coremodule/market/repository/MarketQrVisitRepository.java b/core-module/src/main/java/com/likelion/coremodule/market/repository/MarketQrVisitRepository.java new file mode 100644 index 0000000..5763aaa --- /dev/null +++ b/core-module/src/main/java/com/likelion/coremodule/market/repository/MarketQrVisitRepository.java @@ -0,0 +1,9 @@ +package com.likelion.coremodule.market.repository; + +import com.likelion.coremodule.market.domain.MarketQrVisit; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface MarketQrVisitRepository extends JpaRepository { + + MarketQrVisit findByMarketId(Long marketId); +} diff --git a/core-module/src/main/java/com/likelion/coremodule/market/service/HomeQueryService.java b/core-module/src/main/java/com/likelion/coremodule/market/service/HomeQueryService.java new file mode 100644 index 0000000..fcfda7c --- /dev/null +++ b/core-module/src/main/java/com/likelion/coremodule/market/service/HomeQueryService.java @@ -0,0 +1,38 @@ +package com.likelion.coremodule.market.service; + +import com.likelion.coremodule.market.domain.Market; +import com.likelion.coremodule.market.domain.MarketQrVisit; +import com.likelion.coremodule.market.repository.MarketQrVisitRepository; +import com.likelion.coremodule.market.repository.MarketRepository; +import com.likelion.coremodule.store.repository.StoreRepository; +import com.likelion.coremodule.user.domain.User; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@RequiredArgsConstructor +@Transactional +public class HomeQueryService { + + private final MarketRepository marketRepository; + private final MarketQrVisitRepository marketQrVisitRepository; + private final StoreRepository storeRepository; + + public void updateQrVisit(User user, Market market) { + + MarketQrVisit marketQrVisit = marketQrVisitRepository.findByMarketId(market.getId()); + + if (marketQrVisit != null) { + marketQrVisit.updateQrVisit(); + } else { + marketQrVisit = MarketQrVisit.builder() + .qrVisit(1) + .market(market) + .user(user) + .build(); + marketQrVisitRepository.save(marketQrVisit); + } + } + +} diff --git a/core-module/src/main/java/com/likelion/coremodule/market/service/MarketQueryService.java b/core-module/src/main/java/com/likelion/coremodule/market/service/MarketQueryService.java index 67e3298..9791e5c 100644 --- a/core-module/src/main/java/com/likelion/coremodule/market/service/MarketQueryService.java +++ b/core-module/src/main/java/com/likelion/coremodule/market/service/MarketQueryService.java @@ -6,8 +6,10 @@ import com.likelion.coremodule.VisitList.exception.VisitException; import com.likelion.coremodule.VisitList.repository.VisitListRepository; import com.likelion.coremodule.market.domain.Market; +import com.likelion.coremodule.market.domain.MarketQrVisit; import com.likelion.coremodule.market.exception.MarketErrorCode; import com.likelion.coremodule.market.exception.MarketException; +import com.likelion.coremodule.market.repository.MarketQrVisitRepository; import com.likelion.coremodule.market.repository.MarketRepository; import com.likelion.coremodule.store.domain.Store; import com.likelion.coremodule.store.service.StoreQueryService; @@ -16,19 +18,30 @@ import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; +import java.util.List; + @Service @RequiredArgsConstructor public class MarketQueryService { private final MarketRepository marketRepository; + private final MarketQrVisitRepository marketQrVisitRepository; private final UserQueryService userQueryService; private final StoreQueryService storeQueryService; private final VisitListRepository visitListRepository; + public List findAllMarkets() { + return marketRepository.findAll(); + } + public Market findMarket(Long id) { return marketRepository.findById(id).orElseThrow(() -> new MarketException(MarketErrorCode.NO_MARKET_INFO)); } + public MarketQrVisit findMarketVisit(Long marketId) { + return marketQrVisitRepository.findByMarketId(marketId); + } + public void saveVisitList(Long storeId, String email) { User user = userQueryService.findByEmail(email); diff --git a/core-module/src/main/java/com/likelion/coremodule/store/domain/Store.java b/core-module/src/main/java/com/likelion/coremodule/store/domain/Store.java index 2339e29..0411a1f 100644 --- a/core-module/src/main/java/com/likelion/coremodule/store/domain/Store.java +++ b/core-module/src/main/java/com/likelion/coremodule/store/domain/Store.java @@ -1,6 +1,7 @@ package com.likelion.coremodule.store.domain; import com.fasterxml.jackson.annotation.JsonValue; +import com.likelion.commonmodule.exception.common.BaseEntity; import com.likelion.coremodule.market.domain.Market; import jakarta.persistence.*; import lombok.*; @@ -10,7 +11,7 @@ @NoArgsConstructor(access = AccessLevel.PROTECTED) @AllArgsConstructor @Entity -public class Store { +public class Store extends BaseEntity { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @@ -29,6 +30,8 @@ public class Store { private String closeHours; private String contact; private String imageUrl; + private Integer xloc; + private Integer yloc; @JsonValue public String getCategoryValue() { diff --git a/core-module/src/main/java/com/likelion/coremodule/store/domain/StoreVisit.java b/core-module/src/main/java/com/likelion/coremodule/store/domain/StoreVisit.java new file mode 100644 index 0000000..67f4e12 --- /dev/null +++ b/core-module/src/main/java/com/likelion/coremodule/store/domain/StoreVisit.java @@ -0,0 +1,33 @@ +package com.likelion.coremodule.store.domain; + +import com.likelion.commonmodule.exception.common.BaseEntity; +import com.likelion.coremodule.user.domain.User; +import jakarta.persistence.*; +import lombok.*; + +@Builder +@Getter +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@AllArgsConstructor +@Entity +public class StoreVisit extends BaseEntity { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "storevisit_id") + private Long id; + + private Boolean visitYn; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "user_id") + private User user; + + @OneToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "store_id") + private Store store; + + public void updateVisitYn() { + this.visitYn = true; + } +} diff --git a/core-module/src/main/java/com/likelion/coremodule/store/exception/StoreErrorCode.java b/core-module/src/main/java/com/likelion/coremodule/store/exception/StoreErrorCode.java index db7e33a..5eb7f63 100644 --- a/core-module/src/main/java/com/likelion/coremodule/store/exception/StoreErrorCode.java +++ b/core-module/src/main/java/com/likelion/coremodule/store/exception/StoreErrorCode.java @@ -11,7 +11,8 @@ public enum StoreErrorCode implements BaseErrorCode { NO_STORE_INFO(HttpStatus.BAD_REQUEST, "2000", "시장 정보가 존재하지 않습니다."), - NO_STORE_CATEGORY(HttpStatus.BAD_REQUEST, "2000", "카테고리 정보를 잘못 입력하였습니다."); + NO_STORE_CATEGORY(HttpStatus.BAD_REQUEST, "2000", "카테고리 정보를 잘못 입력하였습니다."), + NO_STORE_VISIT(HttpStatus.BAD_REQUEST, "2000", "방문 기록이 존재하지 않습니다."); private final HttpStatus httpStatus; private final String code; diff --git a/core-module/src/main/java/com/likelion/coremodule/store/repository/StoreRepository.java b/core-module/src/main/java/com/likelion/coremodule/store/repository/StoreRepository.java index ad68ca3..96f1799 100644 --- a/core-module/src/main/java/com/likelion/coremodule/store/repository/StoreRepository.java +++ b/core-module/src/main/java/com/likelion/coremodule/store/repository/StoreRepository.java @@ -3,5 +3,9 @@ import com.likelion.coremodule.store.domain.Store; import org.springframework.data.jpa.repository.JpaRepository; +import java.util.List; + public interface StoreRepository extends JpaRepository { + + List findStoresByMarketId(Long marketId); } diff --git a/core-module/src/main/java/com/likelion/coremodule/store/repository/StoreVisitRepository.java b/core-module/src/main/java/com/likelion/coremodule/store/repository/StoreVisitRepository.java new file mode 100644 index 0000000..003474c --- /dev/null +++ b/core-module/src/main/java/com/likelion/coremodule/store/repository/StoreVisitRepository.java @@ -0,0 +1,15 @@ +package com.likelion.coremodule.store.repository; + +import com.likelion.coremodule.store.domain.StoreVisit; +import org.springframework.data.jpa.repository.JpaRepository; + +import java.util.List; + +public interface StoreVisitRepository extends JpaRepository { + + StoreVisit findByStoreId(Long storeId); + + List findStoreVisitsByUserUserIdAndStoreId(Long userId, Long storeId); + + List findStoreVisitsByStoreId(Long storeId); +} diff --git a/core-module/src/main/java/com/likelion/coremodule/store/service/StoreQueryService.java b/core-module/src/main/java/com/likelion/coremodule/store/service/StoreQueryService.java index cfd5dbe..673f2f2 100644 --- a/core-module/src/main/java/com/likelion/coremodule/store/service/StoreQueryService.java +++ b/core-module/src/main/java/com/likelion/coremodule/store/service/StoreQueryService.java @@ -1,28 +1,52 @@ package com.likelion.coremodule.store.service; import com.likelion.coremodule.store.domain.Store; +import com.likelion.coremodule.store.domain.StoreVisit; import com.likelion.coremodule.store.exception.StoreErrorCode; import com.likelion.coremodule.store.exception.StoreException; import com.likelion.coremodule.store.repository.StoreRepository; +import com.likelion.coremodule.store.repository.StoreVisitRepository; +import com.likelion.coremodule.user.domain.User; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import java.util.List; -import java.util.Optional; @Service @RequiredArgsConstructor public class StoreQueryService { private final StoreRepository storeRepository; + private final StoreVisitRepository storeVisitRepository; public Store findStoreById(Long storeId) { return storeRepository.findById(storeId).orElseThrow(() -> new StoreException(StoreErrorCode.NO_STORE_INFO)); } - public List findAllStore() { + public List findStoreVisitsByUserIdAndStoreId(Long userId, Long storeId) { + return storeVisitRepository.findStoreVisitsByUserUserIdAndStoreId(userId, storeId); + } + + public StoreVisit findStoreVisitByStoreId(Long storeId) { + return storeVisitRepository.findByStoreId(storeId); + } + public List findAllStore() { return storeRepository.findAll(); } + + public List findStoresByMarketId(Long marketId) { + return storeRepository.findStoresByMarketId(marketId); + } + + public List findStoreVisitsByStoreId(Long storeId) { + return storeVisitRepository.findStoreVisitsByStoreId(storeId); + } + + public void saveVisitYn(Store store, User user) { + final StoreVisit storeVisit = StoreVisit.builder() + .store(store).user(user).visitYn(true).build(); + storeVisitRepository.save(storeVisit); + } }