refactor(customer-vue, store-service): 즐겨찾기 매장 조회
- 즐겨찾기 매장 조회 - 즐겨찾기 테스트 데이터 - 페이지 라우팅 체크 로직
This commit is contained in:
@@ -1,5 +1,7 @@
|
||||
package com.justpickup.storeservice;
|
||||
|
||||
import com.justpickup.storeservice.domain.favoritestore.entity.FavoriteStore;
|
||||
import com.justpickup.storeservice.domain.favoritestore.repository.FavoriteStoreRepository;
|
||||
import com.justpickup.storeservice.domain.map.entity.Map;
|
||||
import com.justpickup.storeservice.domain.store.entity.Store;
|
||||
import com.justpickup.storeservice.domain.store.repository.StoreRepository;
|
||||
@@ -22,7 +24,7 @@ public class StoreServiceApplication {
|
||||
}
|
||||
|
||||
@Bean
|
||||
CommandLineRunner run(StoreRepository storeRepository) {
|
||||
CommandLineRunner run(StoreRepository storeRepository, FavoriteStoreRepository favoriteStoreRepository) {
|
||||
return args -> {
|
||||
List<Store> stores = new ArrayList<>();
|
||||
|
||||
@@ -63,6 +65,14 @@ public class StoreServiceApplication {
|
||||
);
|
||||
|
||||
storeRepository.saveAll(stores);
|
||||
|
||||
List<Long> userList = List.of(1L,2L,3L,4L,5L,6L,7L);
|
||||
userList.forEach(userId -> {
|
||||
stores.forEach(store -> {
|
||||
favoriteStoreRepository.save(FavoriteStore.of(userId, store));
|
||||
});
|
||||
});
|
||||
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,9 +2,7 @@ package com.justpickup.storeservice.domain.favoritestore.entity;
|
||||
|
||||
import com.justpickup.storeservice.domain.store.entity.Store;
|
||||
import com.justpickup.storeservice.global.entity.BaseEntity;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.*;
|
||||
|
||||
import javax.persistence.*;
|
||||
|
||||
@@ -25,4 +23,11 @@ public class FavoriteStore extends BaseEntity {
|
||||
@ManyToOne(fetch = LAZY)
|
||||
@JoinColumn(name = "store_id")
|
||||
private Store store;
|
||||
|
||||
public static FavoriteStore of(Long userId , Store store){
|
||||
FavoriteStore favoriteStore = new FavoriteStore();
|
||||
favoriteStore.userId = userId;
|
||||
favoriteStore.store = store;
|
||||
return favoriteStore;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
package com.justpickup.storeservice.domain.favoritestore.repository;
|
||||
|
||||
import com.justpickup.storeservice.domain.favoritestore.entity.FavoriteStore;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
|
||||
public interface FavoriteStoreRepository extends JpaRepository<FavoriteStore,Long> {
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.justpickup.storeservice.domain.store.entity;
|
||||
|
||||
import com.justpickup.storeservice.domain.category.entity.Category;
|
||||
import com.justpickup.storeservice.domain.favoritestore.entity.FavoriteStore;
|
||||
import com.justpickup.storeservice.domain.item.entity.Item;
|
||||
import com.justpickup.storeservice.domain.map.entity.Map;
|
||||
import com.justpickup.storeservice.global.entity.Address;
|
||||
@@ -52,6 +53,8 @@ public class Store extends BaseEntity {
|
||||
@OneToMany(mappedBy = "store")
|
||||
private List<Item> items;
|
||||
|
||||
@OneToMany(mappedBy = "store")
|
||||
private List<FavoriteStore> favoriteStores;
|
||||
// == 연관관계 편의 메소드 == //
|
||||
public void addCategory(Category category) {
|
||||
categories.add(category);
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package com.justpickup.storeservice.domain.store.repository;
|
||||
|
||||
import com.justpickup.storeservice.domain.favoritestore.entity.FavoriteStore;
|
||||
import com.justpickup.storeservice.domain.favoritestore.entity.QFavoriteStore;
|
||||
import com.justpickup.storeservice.domain.store.dto.SearchStoreCondition;
|
||||
import com.justpickup.storeservice.domain.store.dto.SearchStoreResult;
|
||||
import com.querydsl.core.types.Expression;
|
||||
@@ -28,25 +30,8 @@ public class StoreRepositoryCustom {
|
||||
private final JPAQueryFactory queryFactory;
|
||||
|
||||
public SliceImpl<SearchStoreResult> findSearchStoreScroll(SearchStoreCondition condition, Pageable pageable) {
|
||||
Expression<Double> latitude = Expressions.constant(condition.getLatitude());
|
||||
Expression<Double> longitude = Expressions.constant(condition.getLongitude());
|
||||
|
||||
NumberExpression<Double> haversineDistance = getHaversineDistance(condition.getLatitude(),condition.getLongitude());
|
||||
NumberPath<Double> distanceAlias = Expressions.numberPath(Double.class, "distance");
|
||||
int earthRadius = 6371;
|
||||
|
||||
NumberExpression<Double> haversineDistance = acos(
|
||||
cos(radians(latitude))
|
||||
.multiply(cos(radians(store.map.latitude)))
|
||||
.multiply(
|
||||
cos(radians(store.map.longitude)
|
||||
.subtract(radians(longitude)))
|
||||
)
|
||||
.add(
|
||||
sin(radians(latitude))
|
||||
.multiply(sin(radians(store.map.latitude)))
|
||||
)
|
||||
)
|
||||
.multiply(Expressions.constant(earthRadius * 1000));
|
||||
|
||||
List<SearchStoreResult> content = queryFactory.select(
|
||||
Projections.constructor(SearchStoreResult.class,
|
||||
@@ -77,4 +62,47 @@ public class StoreRepositoryCustom {
|
||||
return storeName == null ? null : store.name.contains(storeName);
|
||||
}
|
||||
|
||||
public List<SearchStoreResult> findFavoriteStore(SearchStoreCondition condition,Long userId){
|
||||
|
||||
NumberExpression<Double> haversineDistance = getHaversineDistance(condition.getLatitude(),condition.getLongitude());
|
||||
NumberPath<Double> distanceAlias = Expressions.numberPath(Double.class, "distance");
|
||||
List<SearchStoreResult> content = queryFactory.select(
|
||||
Projections.constructor(SearchStoreResult.class,
|
||||
store.id,
|
||||
store.name,
|
||||
haversineDistance.as(distanceAlias))
|
||||
)
|
||||
.from(store)
|
||||
.join(store.map)
|
||||
.join(store.favoriteStores, QFavoriteStore.favoriteStore)
|
||||
.on(QFavoriteStore.favoriteStore.userId.eq(userId))
|
||||
.orderBy(distanceAlias.asc())
|
||||
.fetch();
|
||||
|
||||
|
||||
return content;
|
||||
}
|
||||
|
||||
private NumberExpression<Double> getHaversineDistance (double SearchLatitude, double SearchLongitude){
|
||||
Expression<Double> latitude = Expressions.constant(SearchLatitude);
|
||||
Expression<Double> longitude = Expressions.constant(SearchLongitude);
|
||||
|
||||
int earthRadius = 6371;
|
||||
|
||||
NumberExpression<Double> haversineDistance = acos(
|
||||
cos(radians(latitude))
|
||||
.multiply(cos(radians(store.map.latitude)))
|
||||
.multiply(
|
||||
cos(radians(store.map.longitude)
|
||||
.subtract(radians(longitude)))
|
||||
)
|
||||
.add(
|
||||
sin(radians(latitude))
|
||||
.multiply(sin(radians(store.map.latitude)))
|
||||
)
|
||||
)
|
||||
.multiply(Expressions.constant(earthRadius * 1000));
|
||||
return haversineDistance;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -5,6 +5,9 @@ import com.justpickup.storeservice.domain.store.dto.SearchStoreResult;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.domain.SliceImpl;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface StoreService {
|
||||
SliceImpl<SearchStoreResult> findSearchStoreScroll(SearchStoreCondition condition, Pageable pageable);
|
||||
List<SearchStoreResult> findFavoriteStore(SearchStoreCondition condition, Long userId);
|
||||
}
|
||||
|
||||
@@ -8,6 +8,8 @@ import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.domain.SliceImpl;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class StoreServiceImpl implements StoreService {
|
||||
@@ -18,4 +20,9 @@ public class StoreServiceImpl implements StoreService {
|
||||
public SliceImpl<SearchStoreResult> findSearchStoreScroll(SearchStoreCondition condition, Pageable pageable) {
|
||||
return storeRepositoryCustom.findSearchStoreScroll(condition, pageable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SearchStoreResult> findFavoriteStore(SearchStoreCondition condition, Long userId) {
|
||||
return storeRepositoryCustom.findFavoriteStore(condition,userId);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
package com.justpickup.storeservice.domain.store.web;
|
||||
|
||||
import com.justpickup.storeservice.domain.store.dto.SearchStoreCondition;
|
||||
import com.justpickup.storeservice.domain.store.dto.SearchStoreResult;
|
||||
import com.justpickup.storeservice.domain.store.service.StoreService;
|
||||
import com.justpickup.storeservice.global.dto.Result;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.domain.SliceImpl;
|
||||
import org.springframework.data.web.PageableDefault;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestHeader;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.validation.Valid;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@RestController
|
||||
@Slf4j
|
||||
@RequestMapping("api/customer/store")
|
||||
@RequiredArgsConstructor
|
||||
public class StoreCustomerApiController {
|
||||
|
||||
private final StoreService storeService;
|
||||
|
||||
@GetMapping("/favorite")
|
||||
public ResponseEntity getFavoriteStore(@Valid SearchStoreCondition condition,
|
||||
@RequestHeader(value = "user-id") String userId){
|
||||
|
||||
List<SearchStoreResult> favoriteStore = storeService.findFavoriteStore(condition,Long.parseLong(userId));
|
||||
|
||||
List<StoreCustomerApiController.SearchStoreResponse> searchStoreResponse
|
||||
= favoriteStore.stream().map(SearchStoreResponse::new).collect(Collectors.toList());
|
||||
|
||||
return ResponseEntity.status(HttpStatus.OK).body(Result.createSuccessResult(searchStoreResponse));
|
||||
}
|
||||
|
||||
@Data @NoArgsConstructor
|
||||
static class SearchStoreResponse {
|
||||
private Long id;
|
||||
private String name;
|
||||
private String distance;
|
||||
|
||||
public SearchStoreResponse(SearchStoreResult storeResult) {
|
||||
this.id = storeResult.getStoreId();
|
||||
this.name = storeResult.getStoreName();
|
||||
this.distance = storeResult.convertDistanceToString();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user