Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
package com.nowait.applicationuser.bookmark.service;

import java.util.HashSet;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
Expand All @@ -19,11 +20,10 @@
import com.nowait.domaincorerdb.user.exception.UserNotFoundException;
import com.nowait.domaincorerdb.user.repository.UserRepository;
import com.nowait.domainuserrdb.bookmark.entity.Bookmark;
import com.nowait.domainuserrdb.bookmark.exception.BookmarkNotFoundException;
import com.nowait.domainuserrdb.bookmark.exception.AlreadyDeletedBookmarkException;
import com.nowait.domainuserrdb.bookmark.repository.BookmarkRepository;
import com.nowait.domainuserrdb.oauth.dto.CustomOAuth2User;

import jakarta.persistence.EntityNotFoundException;
import lombok.RequiredArgsConstructor;

@Service
Expand Down Expand Up @@ -70,15 +70,21 @@ public List<StorePageReadResponse> getBookmarks(CustomOAuth2User customOAuth2Use
User user = userRepository.findById(customOAuth2User.getUserId())
.orElseThrow(UserNotFoundException::new);

Collection<Bookmark> allBookmarks = bookmarkRepository.findAllByUserAndDeletedFalse(user);

List<Long> storeIds = bookmarkRepository.findAllByUserAndDeletedFalse(user)
.stream()
.map(Bookmark::getStore)
.map(Store::getStoreId)
.toList();

Set<Long> bookmarkedSet = new HashSet<>(storeIds);
Map<Long, Long> bookmarkMap = allBookmarks.stream()
.collect(Collectors.toMap(
b -> b.getStore().getStoreId(),
Bookmark::getId
));

return storeService.getAllStoresByPageAndDeparments(storeIds, bookmarkedSet);
return storeService.getAllStoresByPageAndDeparments(storeIds, bookmarkMap);
Comment thread
Jjiggu marked this conversation as resolved.
}

@Transactional
Expand All @@ -89,7 +95,7 @@ public String deleteBookmark(Long storeId, CustomOAuth2User customOAuth2User) {
.orElseThrow(StoreNotFoundException::new);

Bookmark bookmark = bookmarkRepository.findByUserAndStoreAndDeletedFalse(user, store)
.orElseThrow(BookmarkNotFoundException::new);
.orElseThrow(AlreadyDeletedBookmarkException::new);

if (!Objects.equals(bookmark.getUser().getId(), customOAuth2User.getUserId())) {
throw new IllegalArgumentException("you can only delete your own bookmark");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
import com.nowait.domaincorerdb.store.exception.StoreWaitingDisabledException;
import com.nowait.domaincorerdb.token.exception.BusinessException;
import com.nowait.domaincorerdb.user.exception.UserNotFoundException;
import com.nowait.domainuserrdb.bookmark.exception.AlreadyDeletedBookmarkException;
import com.nowait.domainuserrdb.bookmark.exception.BookmarkNotFoundException;
import com.nowait.domainuserrdb.bookmark.exception.BookmarkOwnerMismatchException;
import com.nowait.domainuserrdb.bookmark.exception.DuplicateBookmarkException;
Expand Down Expand Up @@ -153,7 +154,16 @@ public ErrorResponse handleBookmarkNotFoundException(
BookmarkNotFoundException e, WebRequest request) {
alarm(e, request);
log.error("handleBookmarkNotFoundException", e);
return new ErrorResponse(e.getMessage(), BOOKMARK_NOT_FOUND.getCode());
return new ErrorResponse(e.getMessage(), NOT_FOUND_BOOKMARK.getCode());
}

@ResponseStatus(BAD_REQUEST)
@ExceptionHandler(AlreadyDeletedBookmarkException.class)
public ErrorResponse handleAlreadyDeleteBookmark(
AlreadyDeletedBookmarkException e, WebRequest request) {
alarm(e, request);
log.error("AlreadyDeletedBookmarkException", e);
return new ErrorResponse(e.getMessage(), ALREADY_DELETED_BOOKMARK.getCode());
}

@ResponseStatus(NOT_FOUND)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
@Builder
public class StoreDetailReadResponse {
private Long storeId;
private Long bookmarkId;
private Boolean isBookmark;
private Long waitingCount;
private Boolean isWaiting;
Expand All @@ -33,7 +34,7 @@ public class StoreDetailReadResponse {
private LocalDateTime createdAt;

public static StoreDetailReadResponse fromEntity(
Store store, List<StoreImageUploadResponse> allImages, String departmentName, Long waitingCount, Boolean isBookmark, Boolean isWaiting
Store store, Long bookmarkId, List<StoreImageUploadResponse> allImages, String departmentName, Long waitingCount, Boolean isBookmark, Boolean isWaiting
) {

StoreImageUploadResponse profile = allImages.stream()
Expand All @@ -47,6 +48,7 @@ public static StoreDetailReadResponse fromEntity(

return StoreDetailReadResponse.builder()
.storeId(store.getStoreId())
.bookmarkId(bookmarkId)
.isBookmark(isBookmark)
.waitingCount(waitingCount)
.isWaiting(isWaiting)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
@Builder
public class StorePageReadResponse {
private Long storeId;
private Long bookmarkId;
private Boolean isBookmark;
private Long waitingCount;
private Long departmentId;
Expand All @@ -31,7 +32,7 @@ public class StorePageReadResponse {
private Boolean deleted;
private LocalDateTime createdAt;

public static StorePageReadResponse fromEntity(Store store, List<StoreImageUploadResponse> allImages, String departmentName, Long waitingCount, Boolean isBookmark) {
public static StorePageReadResponse fromEntity(Store store, Long bookmarkId, List<StoreImageUploadResponse> allImages, String departmentName, Long waitingCount, Boolean isBookmark) {

StoreImageUploadResponse profile = allImages.stream()
.filter(image -> image.getImageType() == ImageType.PROFILE)
Expand All @@ -44,6 +45,7 @@ public static StorePageReadResponse fromEntity(Store store, List<StoreImageUploa

return StorePageReadResponse.builder()
.storeId(store.getStoreId())
.bookmarkId(bookmarkId)
.isBookmark(isBookmark)
.waitingCount(waitingCount)
.departmentId(store.getDepartmentId())
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.nowait.applicationuser.store.service;

import java.util.List;
import java.util.Map;
import java.util.Set;

import org.springframework.data.domain.Pageable;
Expand All @@ -23,5 +24,5 @@ public interface StoreService {

List<StoreWaitingInfo> getStoresByWaitingCount(boolean desc);

List<StorePageReadResponse> getAllStoresByPageAndDeparments(List<Long> storeIds, Set<Long> bookmarkedSet);
List<StorePageReadResponse> getAllStoresByPageAndDeparments(List<Long> storeIds, Map<Long, Long> bookmarkMap);
Comment thread
Jjiggu marked this conversation as resolved.
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
package com.nowait.applicationuser.store.service;

import java.awt.print.Book;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;
Expand Down Expand Up @@ -42,6 +45,7 @@
import com.nowait.domaincorerdb.user.repository.UserRepository;
import com.nowait.domaincoreredis.common.util.RedisKeyUtils;
import com.nowait.domainuserrdb.bookmark.entity.Bookmark;
import com.nowait.domainuserrdb.bookmark.exception.BookmarkNotFoundException;
import com.nowait.domainuserrdb.bookmark.repository.BookmarkRepository;
import com.nowait.domainuserrdb.oauth.dto.CustomOAuth2User;

Expand All @@ -56,12 +60,12 @@ public class StoreServiceImpl implements StoreService {
private final DepartmentRepository departmentRepository;
private final StringRedisTemplate redisTemplate;
private final BookmarkRepository bookmarkRepository;
private final UserRepository userRepository;
private final WaitingUserRedisRepository waitingRepo;

@Override
@Transactional(readOnly = true)
public StoreDepartmentReadResponse getAllStoresByPageAndDeparments(Pageable pageable, CustomOAuth2User customOAuth2User) {
public StoreDepartmentReadResponse getAllStoresByPageAndDeparments(Pageable pageable,
CustomOAuth2User customOAuth2User) {

User user = customOAuth2User.getUser();

Expand All @@ -78,28 +82,20 @@ public StoreDepartmentReadResponse getAllStoresByPageAndDeparments(Pageable page
.distinct()
.toList();

// 2) 사용자 북마크된 storeId 집합 조회
List<Long> storeBookmarkIds = bookmarkRepository.findAllByUserAndDeletedFalse(user)
.stream()
.map(Bookmark::getStore)
.map(Store::getStoreId)
.toList();
Set<Long> bookmarkedSet = new HashSet<>(storeIds);

// 2-1) Redis에서 각 Store의 웨이팅 사이즈 조회
Map<Long, Long> waitingSizeMap = storeIds.stream()
.collect(Collectors.toMap(
.collect(Collectors.toMap(
Function.identity(),
storeId -> {
String key = "waiting:" + storeId;
try {
return redisTemplate.opsForZSet().zCard(key);
} catch (Exception e) {
return 0L; // Redis 접근 실패 시 0으로 처리
}
storeId -> {
String key = "waiting:" + storeId;
try {
return redisTemplate.opsForZSet().zCard(key);
} catch (Exception e) {
return 0L; // Redis 접근 실패 시 0으로 처리
}

}
));
}
));

// 3) 각 StoreId에 해당하는 이미지 조회
List<StoreImage> allImages = storeImageRepository.findByStore_StoreIdIn(storeIds);
Expand All @@ -109,7 +105,6 @@ public StoreDepartmentReadResponse getAllStoresByPageAndDeparments(Pageable page
StoreImageUploadResponse::getStoreId
));


// 4) 각 DepartmentId에 해당하는 이름 조회
List<Department> allDepts = departmentRepository.findAllById(deptIds);
Map<Long, String> deptNameMap = allDepts.stream()
Expand All @@ -118,21 +113,24 @@ public StoreDepartmentReadResponse getAllStoresByPageAndDeparments(Pageable page
Department::getName
));

List<Bookmark> allBookmarks = bookmarkRepository.findStoreIdByUserAndDeletedFalse(user);
Map<Long, Boolean> bookmarkMap = allBookmarks.stream()
// 5) 북마크 조회
Collection<Bookmark> allBookmarks = bookmarkRepository.findAllByUserAndDeletedFalse(user);
Map<Long, Long> bookmarkIdMap = allBookmarks.stream()
.collect(Collectors.toMap(
bookmark -> bookmark.getStore().getStoreId(),
b -> Boolean.TRUE
b -> b.getStore().getStoreId(),
Bookmark::getId
));

// 5) Dto 매핑
List<StorePageReadResponse> content = stores.stream()
.map(store -> {
Long bookmarkId = bookmarkIdMap.get(store.getStoreId());
boolean isBookmark = bookmarkId != null;
List<StoreImageUploadResponse> imgs = imageMap.getOrDefault(store.getStoreId(), List.of());
String departmentName = deptNameMap.getOrDefault(store.getDepartmentId(), "Unknown Department");
Long waitingCount = waitingSizeMap.getOrDefault(store.getStoreId(), 0L);
Boolean isBookmark = bookmarkMap.getOrDefault(store.getStoreId(), false);
return StorePageReadResponse.fromEntity(store, imgs, departmentName, waitingCount, isBookmark);

return StorePageReadResponse.fromEntity(store, bookmarkId, imgs, departmentName, waitingCount, isBookmark);
})
.toList();

Expand All @@ -144,9 +142,10 @@ public StoreDepartmentReadResponse getAllStoresByPageAndDeparments(Pageable page
@Override
@Transactional(readOnly = true)
public StoreDetailReadResponse getStoreByStoreId(Long storeId, CustomOAuth2User customOAuth2User) {
if (storeId == null) throw new StoreParamEmptyException();
User user = userRepository.findById(customOAuth2User.getUserId())
.orElseThrow(UserNotFoundException::new);

if (storeId == null)
throw new StoreParamEmptyException();
User user = customOAuth2User.getUser();

Store store = storeRepository.findByStoreIdAndDeletedFalse(storeId)
.orElseThrow(StoreNotFoundException::new);
Expand All @@ -155,7 +154,9 @@ public StoreDetailReadResponse getStoreByStoreId(Long storeId, CustomOAuth2User
.map(Department::getName)
.orElse("Unknown Department");

boolean isBookmark = bookmarkRepository.existsByUserAndStoreAndDeletedFalse(user, store);
Optional<Bookmark> bookmark = bookmarkRepository.findByUserAndStoreAndDeletedFalse(user, store);
boolean isBookmark = bookmark.isPresent();
Long bookmarkId = isBookmark ? bookmark.get().getId() : null;

// 2-1) Redis에서 각 Store의 웨이팅 사이즈 조회
String key = "waiting:" + storeId;
Expand All @@ -167,7 +168,8 @@ public StoreDetailReadResponse getStoreByStoreId(Long storeId, CustomOAuth2User
.map(StoreImageUploadResponse::fromEntity)
.toList();

return StoreDetailReadResponse.fromEntity(store, imageDto, departmentName, waitingSize, isBookmark, userWaiting);
return StoreDetailReadResponse.fromEntity(store, bookmarkId, imageDto, departmentName, waitingSize, isBookmark,
userWaiting);
}

@Override
Expand Down Expand Up @@ -255,7 +257,8 @@ public List<StoreWaitingInfo> getStoresByWaitingCount(boolean desc) {

// zset 타입인지 확인
DataType type = redisTemplate.type(key);
if (type == null || !"zset".equals(type.code())) continue;
if (type == null || !"zset".equals(type.code()))
continue;

Long count = redisTemplate.opsForZSet().zCard(key);
String storeId = key.replace(PREFIX, "");
Expand Down Expand Up @@ -284,7 +287,8 @@ public List<StoreWaitingInfo> getStoresByWaitingCount(boolean desc) {

// 정렬 로직: 대기 인원 기준 desc/asc
Comparator<StoreWaitingInfo> comparator = Comparator.comparing(StoreWaitingInfo::getWaitingCount);
if (desc) comparator = comparator.reversed();
if (desc)
comparator = comparator.reversed();
result.sort(comparator);

return result.stream()
Expand All @@ -300,10 +304,10 @@ private RedisConnection getSafeConnection() {
return factory.getConnection();
}


@Override
@Transactional(readOnly = true)
public List<StorePageReadResponse> getAllStoresByPageAndDeparments(List<Long> storeIds, Set<Long> bookmarkedSet) {
public List<StorePageReadResponse> getAllStoresByPageAndDeparments(List<Long> storeIds,
Map<Long, Long> bookmarkMap) {
// 1) 페이징된 Store 스냅샷 조회
List<Store> stores = storeRepository.findAllByStoreIdInOrderByStoreIdAsc(storeIds);

Expand Down Expand Up @@ -336,7 +340,6 @@ public List<StorePageReadResponse> getAllStoresByPageAndDeparments(List<Long> st
StoreImageUploadResponse::getStoreId
));


// 4) 각 DepartmentId에 해당하는 이름 조회
List<Department> allDepts = departmentRepository.findAllById(deptIds);
Map<Long, String> deptNameMap = allDepts.stream()
Expand All @@ -348,15 +351,18 @@ public List<StorePageReadResponse> getAllStoresByPageAndDeparments(List<Long> st
// 5) Dto 매핑
List<StorePageReadResponse> content = stores.stream()
.map(store -> {
Long bookmarkId = bookmarkMap.get(store.getStoreId());
boolean isBookmark = bookmarkId != null;

List<StoreImageUploadResponse> imgs = imageMap
.getOrDefault(store.getStoreId(), List.of());
String departmentName = deptNameMap
.getOrDefault(store.getDepartmentId(), "Unknown Department");
Long waitingCount =
waitingSizeMap.getOrDefault(store.getStoreId(), 0L);
boolean isBookmark = bookmarkedSet.contains(store.getStoreId());

return StorePageReadResponse.fromEntity(store, imgs, departmentName, waitingCount, isBookmark);
return StorePageReadResponse.fromEntity(store, bookmarkId, imgs, departmentName, waitingCount,
isBookmark);
})
.toList();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,9 @@ public enum ErrorMessage {
// bookmark
DUPLICATE_BOOKMARK("이미 북마크한 주점입니다.", "bookmark001"),
NOT_OWN_BOOKMARK("해당 주점은 다른 사용자가 북마크한 주점입니다.", "bookmark002"),
BOOKMARK_NOT_FOUND("이미 북마크 삭제된 주점입니다.", "bookmark002"),
NOT_FOUND_BOOKMARK("북마크를 찾을 수 없습니다", "bookmark003"),
ALREADY_DELETED_BOOKMARK("이미 삭제된 북마크입니다.", "bookmark004"),


// menu
MENU_PARAMETER_EMPTY("메뉴 생성 시 파라미터 정보가 없습니다.", "menu001"),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@
@Repository
public interface StoreRepository extends JpaRepository<Store, Long>, StoreCustomRepository {

List<Store> findAllByDeletedFalse();

Optional<Store> findByStoreIdAndDeletedFalse(Long storeId);

Slice<Store> findAllByDeletedFalseOrderByStoreIdAsc(Pageable pageable);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.nowait.domainuserrdb.bookmark.exception;

import com.nowait.common.exception.ErrorMessage;

public class AlreadyDeletedBookmarkException extends RuntimeException {
public AlreadyDeletedBookmarkException() { super(ErrorMessage.ALREADY_DELETED_BOOKMARK.getMessage()); }
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@

public class BookmarkNotFoundException extends RuntimeException {
public BookmarkNotFoundException() {
super(ErrorMessage.BOOKMARK_NOT_FOUND.getMessage());
super(ErrorMessage.NOT_FOUND_BOOKMARK.getMessage());
}
}
Loading