Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: 주변상점 메뉴 키워드 검색 API 작성 #999

Merged
merged 23 commits into from
Nov 12, 2024
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
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
2 changes: 2 additions & 0 deletions src/main/java/in/koreatech/koin/KoinApplication.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.ConfigurationPropertiesScan;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.scheduling.annotation.EnableScheduling;

@EnableScheduling
@SpringBootApplication
@ConfigurationPropertiesScan
@EnableCaching
public class KoinApplication {

public static void main(String[] args) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import org.springframework.data.repository.Repository;

import in.koreatech.koin.domain.benefit.model.BenefitCategoryMap;
import org.springframework.data.repository.query.Param;

public interface AdminBenefitCategoryMapRepository extends Repository<BenefitCategoryMap, Integer> {

Expand All @@ -19,21 +20,23 @@ public interface AdminBenefitCategoryMapRepository extends Repository<BenefitCat
WHERE bcm.benefitCategory.id = :benefitId
ORDER BY bcm.shop.name ASC
""")
List<BenefitCategoryMap> findAllByBenefitCategoryIdOrderByShopName(Integer benefitId);
List<BenefitCategoryMap> findAllByBenefitCategoryIdOrderByShopName(@Param("benefitId") Integer benefitId);

@Modifying
@Query("""
DELETE FROM BenefitCategoryMap bcm
WHERE bcm.benefitCategory.id = :benefitId
AND bcm.shop.id IN :shopIds
""")
void deleteByBenefitCategoryIdAndShopIds(Integer benefitId, List<Integer> shopIds);
void deleteByBenefitCategoryIdAndShopIds(
@Param("benefitId") Integer benefitId,
@Param("shopIds") List<Integer> shopIds);

@Modifying
@Query("""
DELETE FROM BenefitCategoryMap bcm
WHERE bcm.benefitCategory.id = :benefitId
""")
void deleteByBenefitCategoryId(Integer benefitId);
void deleteByBenefitCategoryId(@Param("benefitId") Integer benefitId);

}
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,22 @@

import in.koreatech.koin.domain.member.exception.MemberNotFoundException;
import in.koreatech.koin.domain.member.model.Member;
import org.springframework.data.repository.query.Param;

public interface AdminMemberRepository extends Repository<Member, Integer> {

@EntityGraph(attributePaths = {"track"})
@Query("select m from Member m where m.track.name = :trackName and m.isDeleted = :isDeleted")
Page<Member> findAllByTrackAndIsDeleted(String trackName, Boolean isDeleted, Pageable pageable);
Page<Member> findAllByTrackAndIsDeleted(
@Param("trackName") String trackName,
@Param("isDeleted") Boolean isDeleted,
Pageable pageable);

@EntityGraph(attributePaths = {"track"})
@Query("select count(m) from Member m where m.track.name = :trackName and m.isDeleted = :isDeleted")
Integer countAllByTrackAndIsDeleted(String trackName, Boolean isDeleted);
Integer countAllByTrackAndIsDeleted(
@Param("trackName") String trackName,
@Param("isDeleted") Boolean isDeleted);

Member save(Member member);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@
import org.springframework.data.repository.Repository;

import in.koreatech.koin.domain.community.article.model.KoinArticle;
import org.springframework.data.repository.query.Param;

public interface AdminKoinArticleRepository extends Repository<KoinArticle, Integer> {

@Query(value = "SELECT * FROM new_koin_articles WHERE article_id = :noticeId", nativeQuery = true)
Optional<KoinArticle> findByArticleId(Integer noticeId);
Optional<KoinArticle> findByArticleId(@Param("noticeId") Integer noticeId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@
import org.springframework.data.repository.Repository;

import in.koreatech.koin.domain.community.article.model.KoreatechArticle;
import org.springframework.data.repository.query.Param;

public interface AdminKoreatechArticleRepository extends Repository<KoreatechArticle, Integer> {

@Query(value = "SELECT * FROM new_koreatech_articles WHERE article_id = :noticeId", nativeQuery = true)
Optional<KoreatechArticle> findByArticleId(Integer noticeId);
Optional<KoreatechArticle> findByArticleId(@Param("noticeId") Integer noticeId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,9 @@
import static io.swagger.v3.oas.annotations.media.Schema.RequiredMode.NOT_REQUIRED;
import static io.swagger.v3.oas.annotations.media.Schema.RequiredMode.REQUIRED;

import java.util.List;

import com.fasterxml.jackson.databind.annotation.JsonNaming;

import in.koreatech.koin.domain.shop.model.menu.Menu;
import in.koreatech.koin.domain.shop.model.shop.Shop;
import in.koreatech.koin.global.validation.NotBlankElement;
import in.koreatech.koin.global.validation.SingleMenuPrice;
import in.koreatech.koin.global.validation.UniqueId;
Expand All @@ -18,6 +16,7 @@
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.PositiveOrZero;
import jakarta.validation.constraints.Size;
import java.util.List;

@JsonNaming(value = SnakeCaseStrategy.class)
@SingleMenuPrice
Expand Down Expand Up @@ -58,10 +57,10 @@ public record AdminCreateMenuRequest(
Integer singlePrice
) {

public Menu toEntity(Integer shopId) {
public Menu toEntity(Shop shop) {
return Menu.builder()
.name(name)
.shopId(shopId)
.shop(shop)
.description(description)
.build();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ public static AdminMenuDetailResponse createForSingleOption(Menu menu, List<Menu

return new AdminMenuDetailResponse(
menu.getId(),
menu.getShopId(),
menu.getShop().getId(),
menu.getName(),
menu.isHidden(),
true,
Expand All @@ -85,7 +85,7 @@ public static AdminMenuDetailResponse createForMultipleOption(Menu menu, List<Me

return new AdminMenuDetailResponse(
menu.getId(),
menu.getShopId(),
menu.getShop().getId(),
menu.getName(),
menu.isHidden(),
false,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,5 +48,5 @@ default Shop getById(Integer shopId) {
int deleteById(@Param("shopId") Integer shopId);

@Query("SELECT s FROM Shop s WHERE s.name LIKE :searchKeyword%")
List<Shop> searchByName(String searchKeyword);
List<Shop> searchByName(@Param("searchKeyword") String searchKeyword);
}
Original file line number Diff line number Diff line change
Expand Up @@ -165,8 +165,8 @@ public void createShopCategory(AdminCreateShopCategoryRequest adminCreateShopCat

@Transactional
public void createMenu(Integer shopId, AdminCreateMenuRequest adminCreateMenuRequest) {
adminShopRepository.getById(shopId);
Menu menu = adminCreateMenuRequest.toEntity(shopId);
Shop shop = adminShopRepository.getById(shopId);
Menu menu = adminCreateMenuRequest.toEntity(shop);
Menu savedMenu = adminMenuRepository.save(menu);
for (Integer categoryId : adminCreateMenuRequest.categoryIds()) {
MenuCategory menuCategory = adminMenuCategoryRepository.getById(categoryId);
Expand Down Expand Up @@ -311,7 +311,7 @@ public void deleteMenuCategory(Integer shopId, Integer categoryId) {
@Transactional
public void deleteMenu(Integer shopId, Integer menuId) {
Menu menu = adminMenuRepository.getById(menuId);
if (!Objects.equals(menu.getShopId(), shopId)) {
if (!Objects.equals(menu.getShop().getId(), shopId)) {
throw new KoinIllegalArgumentException("해당 상점의 카테고리가 아닙니다.");
}
adminMenuRepository.deleteById(menuId);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
import in.koreatech.koin.domain.owner.exception.OwnerNotFoundException;
import in.koreatech.koin.domain.owner.model.Owner;
import in.koreatech.koin.domain.user.model.UserType;
import io.lettuce.core.dynamic.annotation.Param;
import org.springframework.data.repository.query.Param;

public interface AdminOwnerRepository extends Repository<Owner, Integer> {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,13 @@
import in.koreatech.koin.domain.user.exception.UserNotFoundException;
import in.koreatech.koin.domain.user.model.User;
import in.koreatech.koin.domain.user.model.UserType;
import org.springframework.data.repository.query.Param;

public interface AdminUserRepository extends Repository<User, Integer> {

User save(User user);

Optional<User> findByEmail(String Email);
Optional<User> findByEmail(String email);

Optional<User> findById(Integer id);

Expand All @@ -22,7 +23,9 @@ SELECT COUNT(u) FROM User u
WHERE u.userType = :userType
AND u.isAuthed = :isAuthed
""")
Integer findUsersCountByUserTypeAndIsAuthed(UserType userType, Boolean isAuthed);
Integer findUsersCountByUserTypeAndIsAuthed(
@Param("userType") UserType userType,
@Param("isAuthed") Boolean isAuthed);

default User getByEmail(String email) {
return findByEmail(email)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ private Shop getOwnerShopById(Integer shopId, Integer ownerId) {

public MenuDetailResponse getMenuByMenuId(Integer ownerId, Integer menuId) {
Menu menu = menuRepository.getById(menuId);
getOwnerShopById(menu.getShopId(), ownerId);
getOwnerShopById(menu.getShop().getId(), ownerId);
List<MenuCategory> menuCategories = menu.getMenuCategoryMaps()
.stream()
.map(MenuCategoryMap::getMenuCategory)
Expand All @@ -166,7 +166,7 @@ public MenuCategoriesResponse getCategories(Integer shopId, Integer ownerId) {
@Transactional
public void deleteMenuByMenuId(Integer ownerId, Integer menuId) {
Menu menu = menuRepository.getById(menuId);
getOwnerShopById(menu.getShopId(), ownerId);
getOwnerShopById(menu.getShop().getId(), ownerId);
menuRepository.deleteById(menuId);
}

Expand All @@ -179,8 +179,8 @@ public void deleteCategory(Integer ownerId, Integer categoryId) {

@Transactional
public void createMenu(Integer shopId, Integer ownerId, CreateMenuRequest createMenuRequest) {
getOwnerShopById(shopId, ownerId);
Menu menu = createMenuRequest.toEntity(shopId);
Shop shop = getOwnerShopById(shopId, ownerId);
Menu menu = createMenuRequest.toEntity(shop);
Menu savedMenu = menuRepository.save(menu);
for (Integer categoryId : createMenuRequest.categoryIds()) {
MenuCategory menuCategory = menuCategoryRepository.getById(categoryId);
Expand Down Expand Up @@ -229,7 +229,7 @@ public void createMenuCategory(Integer shopId, Integer ownerId, CreateCategoryRe
@Transactional
public void modifyMenu(Integer ownerId, Integer menuId, ModifyMenuRequest modifyMenuRequest) {
Menu menu = menuRepository.getById(menuId);
getOwnerShopById(menu.getShopId(), ownerId);
getOwnerShopById(menu.getShop().getId(), ownerId);
menu.modifyMenu(
modifyMenuRequest.name(),
modifyMenuRequest.description()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package in.koreatech.koin.domain.shop.cache;

import com.fasterxml.jackson.databind.ObjectMapper;
import in.koreatech.koin.domain.shop.cache.dto.ShopsCache;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Repository;

@Getter
@RequiredArgsConstructor
@Repository
public class ShopRedisRepository {
20HyeonsuLee marked this conversation as resolved.
Show resolved Hide resolved
private static final String KEY = "Shops";

private final RedisTemplate<String, Object> redisTemplate;
private final ObjectMapper objectMapper;

public void save(ShopsCache shopsCache) {
redisTemplate.opsForValue().set(KEY, shopsCache);
}

public ShopsCache getShopsResponseByRedis() {
Object data = redisTemplate.opsForValue().get(KEY);
return objectMapper.convertValue(data, ShopsCache.class);
}

public Boolean isCacheAvailable() {
return redisTemplate.hasKey(KEY);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package in.koreatech.koin.domain.shop.cache;

import in.koreatech.koin.domain.shop.cache.dto.ShopsCache;
import in.koreatech.koin.domain.shop.repository.shop.ShopRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@RequiredArgsConstructor
@Transactional(readOnly = true)
@Service
public class ShopsCacheService {
20HyeonsuLee marked this conversation as resolved.
Show resolved Hide resolved

private final ShopRepository shopRepository;
private final ShopRedisRepository shopRedisRepository;

public ShopsCache findAllShopCache() {
if (shopRedisRepository.isCacheAvailable()) {
return shopRedisRepository.getShopsResponseByRedis();
}
return refreshShopsCache();
}

public ShopsCache refreshShopsCache() {
ShopsCache shopsCache = ShopsCache.from(shopRepository.findAll());
shopRedisRepository.save(shopsCache);
return shopsCache;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package in.koreatech.koin.domain.shop.cache.dto;

import in.koreatech.koin.domain.shop.model.article.EventArticle;
import in.koreatech.koin.domain.shop.model.article.EventArticleImage;
import java.util.List;

public record EventArticleCache(
String title,
List<String> thumbnailImages
) {
20HyeonsuLee marked this conversation as resolved.
Show resolved Hide resolved

public static EventArticleCache from(EventArticle eventArticle) {
return new EventArticleCache(
eventArticle.getTitle(),
eventArticle.getThumbnailImages().stream()
.map(EventArticleImage::getThumbnailImage)
.toList()
);
}
}
Loading
Loading