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
1 change: 1 addition & 0 deletions infra/sql/ddl.sql
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ create table owned_menu_search (
menu_id bigint not null,
modified_at datetime(6),
user_id bigint not null,
map_id bigint not null,
menu_title varchar(255) not null,
store_address varchar(255) not null,
store_title varchar(255) not null,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,13 @@

import com.ourmenu.backend.domain.cache.application.CacheService;
import com.ourmenu.backend.domain.cache.dto.GetCacheInfoResponse;
import com.ourmenu.backend.domain.cache.dto.GetMenuFolderIconResponse;
import com.ourmenu.backend.domain.cache.dto.GetMenuPinResponse;
import com.ourmenu.backend.domain.cache.dto.GetTagResponse;
import com.ourmenu.backend.global.response.ApiResponse;
import com.ourmenu.backend.global.response.util.ApiUtil;
import io.swagger.v3.oas.annotations.tags.Tag;
import java.util.List;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
Expand All @@ -22,4 +26,25 @@ public ApiResponse<GetCacheInfoResponse> getCacheInfo() {

return ApiUtil.success(response);
}

@GetMapping("api/cache-data/menu-folder-icons")
public ApiResponse<List<GetMenuFolderIconResponse>> getMenuFolderIconsResponse() {
List<GetMenuFolderIconResponse> response = cacheService.getMenuFolderIcons();

return ApiUtil.success(response);
}

@GetMapping("api/cache-data/menu-pins")
public ApiResponse<List<GetMenuPinResponse>> getMenuPinResponse() {
List<GetMenuPinResponse> response = cacheService.getMenuPins();

return ApiUtil.success(response);
}

@GetMapping("api/cache-data/tags")
public ApiResponse<List<GetTagResponse>> getTagResponse() {
List<GetTagResponse> response = cacheService.getTags();

return ApiUtil.success(response);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
import com.ourmenu.backend.domain.cache.domain.MenuFolderIcon;
import com.ourmenu.backend.domain.cache.domain.MenuPin;
import com.ourmenu.backend.domain.cache.dto.GetCacheInfoResponse;
import com.ourmenu.backend.domain.cache.dto.GetMenuFolderIconResponse;
import com.ourmenu.backend.domain.cache.dto.GetMenuPinResponse;
import com.ourmenu.backend.domain.cache.dto.GetTagResponse;
import com.ourmenu.backend.domain.cache.dto.SimpleHomeImgResponse;
import com.ourmenu.backend.domain.cache.dto.SimpleMenuFolderIconResponse;
import com.ourmenu.backend.domain.cache.dto.SimpleMenuPinResponse;
Expand All @@ -29,6 +32,31 @@ public GetCacheInfoResponse getCacheInfo() {
return GetCacheInfoResponse.of(menuFolderIconInfo, menuPinInfo, homeImgInfo, tagInfo);
}


public List<GetMenuFolderIconResponse> getMenuFolderIcons() {
List<SimpleMenuFolderIconResponse> menuFolderIconsInfo = getMenuFolderIconInfo();

return menuFolderIconsInfo.stream()
.map(GetMenuFolderIconResponse::from)
.toList();
}

public List<GetMenuPinResponse> getMenuPins() {
List<SimpleMenuPinResponse> menuPinsInfo = getMenuPinInfo();

return menuPinsInfo.stream()
.map(GetMenuPinResponse::from)
.toList();
}

public List<GetTagResponse> getTags() {
List<SimpleTagImgResponse> tagsImgInfo = getTagImgInfo();

return tagsImgInfo.stream()
.map(GetTagResponse::from)
.toList();
}

private List<SimpleMenuFolderIconResponse> getMenuFolderIconInfo() {
return Arrays.stream(MenuFolderIcon.values())
.map(menuFolderIcon -> {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.ourmenu.backend.domain.cache.dto;

import com.ourmenu.backend.domain.cache.domain.MenuFolderIcon;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;

@AllArgsConstructor(access = AccessLevel.PRIVATE)
@Builder(access = AccessLevel.PRIVATE)
@Getter
public class GetMenuFolderIconResponse {

private MenuFolderIcon menuFolderIcon;
private String menuFolderIconUrl;

public static GetMenuFolderIconResponse from(SimpleMenuFolderIconResponse simpleMenuFolderIconResponse) {
return GetMenuFolderIconResponse.builder()
.menuFolderIcon(simpleMenuFolderIconResponse.getMenuFolderIcon())
.menuFolderIconUrl(simpleMenuFolderIconResponse.getMenuFolderIconUrl())
.build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package com.ourmenu.backend.domain.cache.dto;

import com.ourmenu.backend.domain.cache.domain.MenuPin;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;

@AllArgsConstructor(access = AccessLevel.PRIVATE)
@Builder(access = AccessLevel.PRIVATE)
@Getter
public class GetMenuPinResponse {

private MenuPin menuPin;
private String menuPinAddImgUrl;
private String menuPinAddDisableImgUrl;

public static GetMenuPinResponse from(SimpleMenuPinResponse simpleMenuPinResponse) {
return GetMenuPinResponse.builder()
.menuPin(simpleMenuPinResponse.getMenuPin())
.menuPinAddImgUrl(simpleMenuPinResponse.getMenuPinAddImgUrl())
.menuPinAddDisableImgUrl(simpleMenuPinResponse.getMenuPinAddDisableImgUrl())
.build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package com.ourmenu.backend.domain.cache.dto;

import com.ourmenu.backend.domain.tag.domain.Tag;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;

@AllArgsConstructor(access = AccessLevel.PRIVATE)
@Builder(access = AccessLevel.PRIVATE)
@Getter
public class GetTagResponse {

private Tag tag;
private String orangeTagImgUrl;
private String whiteTagImgUrl;

public static GetTagResponse from(SimpleTagImgResponse simpleTagImgResponse) {
return GetTagResponse.builder()
.tag(simpleTagImgResponse.getTag())
.orangeTagImgUrl(simpleTagImgResponse.getOrangeTagImgUrl())
.whiteTagImgUrl(simpleTagImgResponse.getWhiteTagImgUrl())
.build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

import com.ourmenu.backend.domain.menu.application.MapService;
import com.ourmenu.backend.domain.menu.dto.MapSearchDto;
import com.ourmenu.backend.domain.menu.dto.MapSearchHistoryDto;
import com.ourmenu.backend.domain.menu.dto.MenuInfoOnMapDto;
import com.ourmenu.backend.domain.menu.dto.MenuOnMapDto;
import com.ourmenu.backend.domain.user.domain.CustomUserDetails;
Expand Down Expand Up @@ -62,9 +61,9 @@ public ApiResponse<MenuInfoOnMapDto> findMenuInfoByMenuId(@PathVariable Long men

@Operation(summary = "지도 검색 기록 조회", description = "지도에서 식당 검색 기록을 조회한다.")
@GetMapping("/maps/search-history")
public ApiResponse<List<MapSearchHistoryDto>> findSearchHistoryOnMap(
public ApiResponse<List<MapSearchDto>> findSearchHistoryOnMap(
@AuthenticationPrincipal CustomUserDetails userDetails) {
List<MapSearchHistoryDto> response = mapService.findSearchHistoryOnMap(userDetails.getId());
List<MapSearchDto> response = mapService.findSearchHistoryOnMap(userDetails.getId());
return ApiUtil.success(response);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ public ApiResponse<SaveMenuResponse> saveMenu(@ModelAttribute SaveMenuRequest re
@AuthenticationPrincipal CustomUserDetails userDetails) {
request.initList();
SimpleSearchDto simpleSearchDto = searchService.getSearchDto(request.getIsCrawled(), request.getStoreId());
MenuDto menuDto = MenuDto.of(request, request.getMenuFolderImgs(), userDetails, simpleSearchDto);
MenuDto menuDto = MenuDto.of(request, request.getMenuImgs(), userDetails, simpleSearchDto);
SaveMenuResponse response = menuService.saveMenu(menuDto);
return ApiUtil.success(response);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
import com.ourmenu.backend.domain.menu.domain.MenuFolder;
import com.ourmenu.backend.domain.menu.domain.MenuImg;
import com.ourmenu.backend.domain.menu.dto.MapSearchDto;
import com.ourmenu.backend.domain.menu.dto.MapSearchHistoryDto;
import com.ourmenu.backend.domain.menu.dto.MenuFolderInfoOnMapDto;
import com.ourmenu.backend.domain.menu.dto.MenuInfoOnMapDto;
import com.ourmenu.backend.domain.menu.dto.MenuOnMapDto;
Expand All @@ -20,19 +19,16 @@
import com.ourmenu.backend.domain.store.domain.Map;
import com.ourmenu.backend.domain.tag.dao.MenuTagRepository;
import com.ourmenu.backend.domain.tag.domain.MenuTag;
import com.ourmenu.backend.domain.user.dao.UserRepository;
import com.ourmenu.backend.domain.user.domain.User;
import com.ourmenu.backend.domain.user.exception.NotFoundUserException;
import java.util.Comparator;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.locationtech.jts.geom.Coordinate;
import org.locationtech.jts.geom.GeometryFactory;
import org.locationtech.jts.geom.Point;
import org.locationtech.jts.geom.PrecisionModel;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
Expand All @@ -45,7 +41,6 @@
public class MapService {

private final MenuRepository menuRepository;
private final UserRepository userRepository;
private final MapRepository mapRepository;
private final MenuTagRepository menuTagRepository;
private final MenuImgRepository menuImgRepository;
Expand All @@ -60,8 +55,6 @@ public class MapService {
* @return
*/
public List<MenuOnMapDto> findMenusOnMap(Long userId) {
User user = userRepository.findById(userId)
.orElseThrow(NotFoundUserException::new);
List<Menu> menus = menuRepository.findMenusByUserId(userId);

java.util.Map<Map, List<Menu>> menuMaps = menus.stream()
Expand Down Expand Up @@ -99,15 +92,12 @@ public List<MenuInfoOnMapDto> findMenuOnMap(Long mapId, Long userId) {
* @return
*/
public List<MapSearchDto> findSearchResultOnMap(String title, double mapX, double mapY, Long userId) {
User user = userRepository.findById(userId)
.orElseThrow(NotFoundUserException::new);

GeometryFactory geometryFactory = new GeometryFactory(new PrecisionModel(), 4326);
Point userLocation = geometryFactory.createPoint(new Coordinate(mapX, mapY));

PageRequest pageRequest = PageRequest.of(0, 10);

Page<Menu> menusByUserIdOrderByDistance =
List<Menu> menusByUserIdOrderByDistance =
menuRepository.findByUserIdTitleContainingOrderByDistance(userId, title, userLocation, pageRequest);

return menusByUserIdOrderByDistance.stream()
Expand All @@ -121,21 +111,16 @@ public List<MapSearchDto> findSearchResultOnMap(String title, double mapX, doubl
* @param userId
* @return
*/
public List<MapSearchHistoryDto> findSearchHistoryOnMap(Long userId) {
User user = userRepository.findById(userId)
.orElseThrow(NotFoundUserException::new);

public List<MapSearchDto> findSearchHistoryOnMap(Long userId) {
Pageable pageable = PageRequest.of(
0,
10,
Sort.by(Sort.Direction.DESC, "modifiedAt")
0, 10, Sort.by(Sort.Direction.DESC, "modifiedAt")
);

Page<OwnedMenuSearch> searchHistoryPage = ownedMenuSearchRepository
List<OwnedMenuSearch> searchHistoryPage = ownedMenuSearchRepository
.findByUserId(userId, pageable);

return searchHistoryPage.stream()
.map(MapSearchHistoryDto::from)
.map(MapSearchDto::from)
.collect(Collectors.toList());
}

Expand All @@ -148,9 +133,6 @@ public List<MapSearchHistoryDto> findSearchHistoryOnMap(Long userId) {
*/
@Transactional
public MenuInfoOnMapDto findMenuByMenuIdOnMap(Long menuId, Long userId) {
User user = userRepository.findById(userId)
.orElseThrow(NotFoundUserException::new);

Menu menu = menuRepository.findByIdAndUserId(menuId, userId)
.orElseThrow(NotFoundMenuException::new);

Expand Down Expand Up @@ -187,7 +169,15 @@ private MenuInfoOnMapDto getMenuInfo(Menu menu) {
* @param menu
*/
private void saveOwnedMenuSearchHistory(Long userId, Menu menu) {
Optional<OwnedMenuSearch> searchHistory = ownedMenuSearchRepository.findByUserIdAndMenuId(userId, menu.getId());

if (searchHistory.isPresent()) {
searchHistory.get().updateModifiedAt();
return;
}

OwnedMenuSearch ownedMenuSearch = OwnedMenuSearch.builder()
.mapId(menu.getStore().getMap().getId())
.menuId(menu.getId())
.menuTitle(menu.getTitle())
.storeTitle(menu.getStore().getTitle())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,13 @@ public interface MenuRepository extends JpaRepository<Menu, Long> {

boolean existsByStore(Store store);

@Query("""
SELECT m
FROM Menu m
JOIN FETCH m.store s
JOIN FETCH s.map map
WHERE m.userId = :userId
""")
List<Menu> findMenusByUserId(Long userId);

List<Menu> findMenusByStoreIdAndUserId(Long storeId, Long userId);
Expand All @@ -27,8 +34,6 @@ public interface MenuRepository extends JpaRepository<Menu, Long> {

Optional<Menu> findByIdAndUserId(Long menuId, Long userId);

List<Menu> findByUserIdAndStoreId(Long userId, Long storeId);

int countByUserId(Long userId);

@Query(value = """
Expand Down Expand Up @@ -264,23 +269,20 @@ List<MenuSimpleDto> findByUserIdAndTag(@Param("userId") Long userId,
@Param("tag") String tag,
Pageable pageable);

@Query(
value = "SELECT m.* FROM menu m " +
"JOIN store s ON m.store_id = s.id " +
"JOIN map ON s.map_id = map.id " +
"WHERE m.user_id = :userId " +
"AND LOWER(m.title) LIKE CONCAT('%', LOWER(:title), '%') " +
"ORDER BY ST_Distance_Sphere(map.location, :userLocation) ASC",
countQuery = "SELECT COUNT(*) FROM menu m " +
"JOIN store s ON m.store_id = s.id " +
"JOIN map ON s.map_id = map.id " +
"WHERE m.user_id = :userId " +
"AND LOWER(m.title) LIKE CONCAT('%', LOWER(:title), '%')",
nativeQuery = true
)
Page<Menu> findByUserIdTitleContainingOrderByDistance(@Param("userId") Long userId,
@Param("title") String title,
@Param("userLocation") Point userLocation,
Pageable pageable);
@Query(value = """
SELECT m.*
FROM menu m
JOIN store s ON m.store_id = s.id
JOIN map ON s.map_id = map.id
WHERE m.user_id = :userId
AND LOWER(m.title) LIKE CONCAT('%', LOWER(:title), '%')
ORDER BY ST_Distance_Sphere(map.location, :userLocation) ASC
""", nativeQuery = true)
List<Menu> findByUserIdTitleContainingOrderByDistance(
@Param("userId") Long userId,
@Param("title") String title,
@Param("userLocation") Point userLocation,
Pageable pageable
);
}

Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,16 @@
@AllArgsConstructor(access = AccessLevel.PRIVATE)
public class MapSearchDto {

private Long mapId;
private Long menuId;
private String menuTitle;
private String storeTitle;
private String storeAddress;

public static MapSearchDto from(Menu menu){
return MapSearchDto.builder()
.mapId(menu.getStore().getMap().getId())
.menuId(menu.getId())
.menuTitle(menu.getTitle())
.storeTitle(menu.getStore().getTitle())
.storeAddress(menu.getStore().getAddress())
Expand All @@ -26,6 +30,8 @@ public static MapSearchDto from(Menu menu){

public static MapSearchDto from(OwnedMenuSearch ownedMenuSearch){
return MapSearchDto.builder()
.mapId(ownedMenuSearch.getMapId())
.menuId(ownedMenuSearch.getMenuId())
.menuTitle(ownedMenuSearch.getMenuTitle())
.storeTitle(ownedMenuSearch.getStoreTitle())
.storeAddress(ownedMenuSearch.getStoreAddress())
Expand Down
Loading