diff --git a/nowait-app-admin-api/src/main/java/com/nowait/applicationadmin/store/dto/StoreCreateRequest.java b/nowait-app-admin-api/src/main/java/com/nowait/applicationadmin/store/dto/StoreCreateRequest.java index 7650a985..5eff72bb 100644 --- a/nowait-app-admin-api/src/main/java/com/nowait/applicationadmin/store/dto/StoreCreateRequest.java +++ b/nowait-app-admin-api/src/main/java/com/nowait/applicationadmin/store/dto/StoreCreateRequest.java @@ -1,5 +1,6 @@ package com.nowait.applicationadmin.store.dto; +import com.nowait.common.token.TokenGenerator; import com.nowait.domaincorerdb.store.entity.Store; import jakarta.validation.constraints.NotBlank; @@ -25,6 +26,7 @@ public class StoreCreateRequest { public Store toEntity() { return Store.builder() + .publicCode(TokenGenerator.base62(12)) .departmentId(departmentId) .name(name) .location(location) diff --git a/nowait-app-admin-api/src/main/java/com/nowait/applicationadmin/store/dto/StoreCreateResponse.java b/nowait-app-admin-api/src/main/java/com/nowait/applicationadmin/store/dto/StoreCreateResponse.java index 725c3159..6dcaf79d 100644 --- a/nowait-app-admin-api/src/main/java/com/nowait/applicationadmin/store/dto/StoreCreateResponse.java +++ b/nowait-app-admin-api/src/main/java/com/nowait/applicationadmin/store/dto/StoreCreateResponse.java @@ -14,6 +14,7 @@ public class StoreCreateResponse { private Long storeId; + private String publicCode; private Long departmentId; private String name; private String location; @@ -29,6 +30,7 @@ public static StoreCreateResponse fromEntity(Store store) { return StoreCreateResponse.builder() .createdAt(store.getCreatedAt()) .storeId(store.getStoreId()) + .publicCode(store.getPublicCode()) .departmentId(store.getDepartmentId()) .name(store.getName()) .location(store.getLocation()) diff --git a/nowait-app-user-api/src/main/java/com/nowait/applicationuser/menu/controller/MenuController.java b/nowait-app-user-api/src/main/java/com/nowait/applicationuser/menu/controller/MenuController.java index b9abf632..9c8b997a 100644 --- a/nowait-app-user-api/src/main/java/com/nowait/applicationuser/menu/controller/MenuController.java +++ b/nowait-app-user-api/src/main/java/com/nowait/applicationuser/menu/controller/MenuController.java @@ -25,32 +25,32 @@ public class MenuController { private final MenuService menuService; - @GetMapping("/all-menus/stores/{storeId}") + @GetMapping("/all-menus/stores/{publicCode}") @Operation(summary = "가게의 모든 메뉴 조회", description = "특정 가게의 모든 메뉴를 조회합니다.") @ApiResponse(responseCode = "200", description = "모든 메뉴를 조회 성공") - public ResponseEntity getMenusByStoreId(@PathVariable Long storeId) { + public ResponseEntity getMenusByStoreId(@PathVariable String publicCode) { return ResponseEntity .status(HttpStatus.OK) .body( ApiUtils.success( - menuService.getAllMenusByStoreId(storeId) + menuService.getAllMenusByStoreId(publicCode) ) ); } - @GetMapping("/{storeId}/{menuId}") + @GetMapping("/{publicCode}/{menuId}") @Operation( summary = "메뉴 ID로 메뉴 조회", description = "특정 가게의 특정 메뉴를 ID로 조회합니다.") @ApiResponse(responseCode = "200", description = "메뉴 조회 성공") public ResponseEntity getMenuById( - @PathVariable Long storeId, + @PathVariable String publicCode, @PathVariable Long menuId ) { return ResponseEntity .status(HttpStatus.OK) .body( ApiUtils.success( - menuService.getMenuById(storeId, menuId) + menuService.getMenuById(publicCode, menuId) ) ); } diff --git a/nowait-app-user-api/src/main/java/com/nowait/applicationuser/menu/service/MenuService.java b/nowait-app-user-api/src/main/java/com/nowait/applicationuser/menu/service/MenuService.java index 8becf9a6..45aa92e5 100644 --- a/nowait-app-user-api/src/main/java/com/nowait/applicationuser/menu/service/MenuService.java +++ b/nowait-app-user-api/src/main/java/com/nowait/applicationuser/menu/service/MenuService.java @@ -30,15 +30,16 @@ public class MenuService { @Transactional(readOnly = true) - public MenuReadResponse getAllMenusByStoreId(Long storeId) { - if (storeId == null) { + public MenuReadResponse getAllMenusByStoreId(String publicCode) { + if (publicCode == null) { throw new MenuParamEmptyException(); } - Store store = storeRepository.findById(storeId) + Store store = storeRepository.findByPublicCodeAndDeletedFalse(publicCode) .orElseThrow(StoreNotFoundException::new); String storeName = store.getName(); + Long storeId = store.getStoreId(); List menus = menuRepository.findAllByStoreIdAndDeletedFalseOrderBySortOrder(storeId); List menuReadResponse = menus.stream() @@ -55,15 +56,15 @@ public MenuReadResponse getAllMenusByStoreId(Long storeId) { } @Transactional(readOnly = true) - public MenuReadDto getMenuById(Long storeId, Long menuId) { - if (storeId == null || menuId == null) { + public MenuReadDto getMenuById(String publicCode, Long menuId) { + if (publicCode == null || menuId == null) { throw new MenuParamEmptyException(); } - storeRepository.findById(storeId) + Store store = storeRepository.findByPublicCodeAndDeletedFalse(publicCode) .orElseThrow(StoreNotFoundException::new); - Menu menu = menuRepository.findByStoreIdAndIdAndDeletedFalse(storeId, menuId) + Menu menu = menuRepository.findByStoreIdAndIdAndDeletedFalse(store.getStoreId(), menuId) .orElseThrow(MenuNotFoundException::new); List images = menuImageRepository.findByMenu(menu); diff --git a/nowait-app-user-api/src/main/java/com/nowait/applicationuser/order/controller/OrderController.java b/nowait-app-user-api/src/main/java/com/nowait/applicationuser/order/controller/OrderController.java index c814a800..76501d55 100644 --- a/nowait-app-user-api/src/main/java/com/nowait/applicationuser/order/controller/OrderController.java +++ b/nowait-app-user-api/src/main/java/com/nowait/applicationuser/order/controller/OrderController.java @@ -32,17 +32,36 @@ public class OrderController { private final OrderService orderService; - @PostMapping("/create/{storeId}/{tableId}") + // @PostMapping("/create/{storeId}/{tableId}") + // @Operation(summary = "주문 생성", description = "특정 주점 - 특정 테이블에 대한 주문 생성") + // @ApiResponse(responseCode = "201", description = "주문 생성") + // public ResponseEntity createOrder( + // @PathVariable Long storeId, + // @PathVariable Long tableId, + // @RequestBody @Valid OrderCreateRequestDto orderCreateRequestDto, + // HttpSession session + // ) { + // String sessionId = session.getId(); + // OrderCreateResponseDto response = orderService.createOrder(storeId, tableId, orderCreateRequestDto, sessionId); + // return ResponseEntity + // .status(HttpStatus.CREATED) + // .body( + // ApiUtils.success(response) + // ); + // } + + @PostMapping("/create/{publicCode}/{tableId}") @Operation(summary = "주문 생성", description = "특정 주점 - 특정 테이블에 대한 주문 생성") @ApiResponse(responseCode = "201", description = "주문 생성") public ResponseEntity createOrder( - @PathVariable Long storeId, + @PathVariable String publicCode, @PathVariable Long tableId, @RequestBody @Valid OrderCreateRequestDto orderCreateRequestDto, HttpSession session - ) { + ) { String sessionId = session.getId(); - OrderCreateResponseDto response = orderService.createOrder(storeId,tableId,orderCreateRequestDto,sessionId); + OrderCreateResponseDto response = orderService.createOrder(publicCode, tableId, orderCreateRequestDto, + sessionId); return ResponseEntity .status(HttpStatus.CREATED) .body( @@ -50,11 +69,11 @@ public ResponseEntity createOrder( ); } - @GetMapping("/items/{storeId}/{tableId}") + @GetMapping("/items/{publicCode}/{tableId}") @Operation(summary = "테이블별 주문 아이템 조회", description = "비로그인(세션) 기준으로 테이블의 내 주문 목록만 조회") @ApiResponse(responseCode = "200", description = "주문 조회") public ResponseEntity getOrderItems( - @PathVariable Long storeId, + @PathVariable String publicCode, @PathVariable Long tableId, HttpServletRequest request ) { @@ -64,7 +83,7 @@ public ResponseEntity getOrderItems( return ResponseEntity.status(HttpStatus.OK).body(ApiUtils.success(List.of())); } String sessionId = session.getId(); - List orderItems = orderService.getOrderItemsGroupByOrderId(storeId, tableId, sessionId); + List orderItems = orderService.getOrderItemsGroupByOrderId(publicCode, tableId, sessionId); return ResponseEntity. status(HttpStatus.OK) .body( diff --git a/nowait-app-user-api/src/main/java/com/nowait/applicationuser/order/service/OrderService.java b/nowait-app-user-api/src/main/java/com/nowait/applicationuser/order/service/OrderService.java index 656f6846..5b317dcc 100644 --- a/nowait-app-user-api/src/main/java/com/nowait/applicationuser/order/service/OrderService.java +++ b/nowait-app-user-api/src/main/java/com/nowait/applicationuser/order/service/OrderService.java @@ -39,16 +39,16 @@ public class OrderService { private final MenuRepository menuRepository; private final OrderItemRepository orderItemRepository; @Transactional - public OrderCreateResponseDto createOrder(Long storeId, Long tableId, + public OrderCreateResponseDto createOrder(String publicCode, Long tableId, OrderCreateRequestDto orderCreateRequestDto, String sessionId) { - parameterValidation(storeId, tableId, orderCreateRequestDto); + parameterValidation(publicCode, tableId, orderCreateRequestDto); // 💡 [중복 주문 방지] signature 생성 및 체크 - String signature = generateOrderSignature(storeId, tableId, orderCreateRequestDto.getItems()); + String signature = generateOrderSignature(publicCode, tableId, orderCreateRequestDto.getItems()); checkDuplicateOrderSignature(signature); // 1. Store 조회 - Store store = storeRepository.findById(storeId) + Store store = storeRepository.findByPublicCodeAndDeletedFalse(publicCode) .orElseThrow(() -> new IllegalArgumentException("store not found")); // 2. UserOrder 생성 및 signature 저장 @@ -95,9 +95,9 @@ public OrderCreateResponseDto createOrder(Long storeId, Long tableId, @Transactional(readOnly = true) public List getOrderItemsGroupByOrderId( - Long storeId, Long tableId, String sessionId) { + String publicCode, Long tableId, String sessionId) { - List userOrders = orderRepository.findByStore_StoreIdAndTableIdAndSessionId(storeId, tableId, sessionId); + List userOrders = orderRepository.findByStore_PublicCodeAndTableIdAndSessionId(publicCode, tableId, sessionId); // orderId 기준으로 바로 변환 return userOrders.stream() @@ -116,8 +116,8 @@ public List getOrderItemsGroupByOrderId( } - private static void parameterValidation(Long storeId, Long tableId, OrderCreateRequestDto orderCreateRequestDto) { - if (storeId == null || tableId == null || orderCreateRequestDto == null) { + private static void parameterValidation(String publicCode, Long tableId, OrderCreateRequestDto orderCreateRequestDto) { + if (publicCode == null || tableId == null || orderCreateRequestDto == null) { throw new OrderParameterEmptyException(); } if (orderCreateRequestDto.getItems() == null || orderCreateRequestDto.getItems().isEmpty()) { @@ -130,7 +130,7 @@ private static void parameterValidation(Long storeId, Long tableId, OrderCreateR throw new IllegalArgumentException("Depositor name is too long"); } } - private String generateOrderSignature(Long storeId, Long tableId, List items) { + private String generateOrderSignature(String storeId, Long tableId, List items) { String cartString = items.stream() .sorted((a, b) -> a.getMenuId().compareTo(b.getMenuId())) // 메뉴 ID 기준 정렬 .map(item -> item.getMenuId() + ":" + item.getQuantity()) diff --git a/nowait-common/src/main/java/com/nowait/common/token/TokenGenerator.java b/nowait-common/src/main/java/com/nowait/common/token/TokenGenerator.java new file mode 100644 index 00000000..2b84840b --- /dev/null +++ b/nowait-common/src/main/java/com/nowait/common/token/TokenGenerator.java @@ -0,0 +1,17 @@ +package com.nowait.common.token; + +import java.security.SecureRandom; + +public final class TokenGenerator { + private static final SecureRandom RNG = new SecureRandom(); + private static final char[] ALPHABET = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789".toCharArray(); + + // 12~16 권장 + public static String base62(int len) { + char[] out = new char[len]; + for (int i = 0; i < len; i++) out[i] = ALPHABET[RNG.nextInt(ALPHABET.length)]; + return new String(out); + } + private TokenGenerator() {} +} diff --git a/nowait-domain/domain-core-rdb/src/main/java/com/nowait/domaincorerdb/order/repository/OrderRepository.java b/nowait-domain/domain-core-rdb/src/main/java/com/nowait/domaincorerdb/order/repository/OrderRepository.java index b1a38e8e..d5bb6bf4 100644 --- a/nowait-domain/domain-core-rdb/src/main/java/com/nowait/domaincorerdb/order/repository/OrderRepository.java +++ b/nowait-domain/domain-core-rdb/src/main/java/com/nowait/domaincorerdb/order/repository/OrderRepository.java @@ -13,7 +13,7 @@ public interface OrderRepository extends JpaRepository { boolean existsBySignatureAndCreatedAtAfter(String signature, LocalDateTime createdAt); - List findByStore_StoreIdAndTableIdAndSessionId(Long storeId, Long tableId, String sessionId); + List findByStore_PublicCodeAndTableIdAndSessionId(String publicCode, Long tableId, String sessionId); @EntityGraph(attributePaths = {"orderItems", "orderItems.menu"}) List findAllByStore_StoreIdAndCreatedAtBetween(Long storeId, LocalDateTime startDateTime, LocalDateTime endDateTime); diff --git a/nowait-domain/domain-core-rdb/src/main/java/com/nowait/domaincorerdb/store/entity/Store.java b/nowait-domain/domain-core-rdb/src/main/java/com/nowait/domaincorerdb/store/entity/Store.java index 5aa58b95..a635dab2 100644 --- a/nowait-domain/domain-core-rdb/src/main/java/com/nowait/domaincorerdb/store/entity/Store.java +++ b/nowait-domain/domain-core-rdb/src/main/java/com/nowait/domaincorerdb/store/entity/Store.java @@ -28,6 +28,9 @@ public class Store extends BaseTimeEntity { @GeneratedValue(strategy = GenerationType.IDENTITY) private Long storeId; + @Column(nullable = false, unique = true, updatable = false, length = 12) + private String publicCode; + @Column(name = "department_id", nullable = false) private Long departmentId; @@ -56,7 +59,8 @@ public class Store extends BaseTimeEntity { private Boolean deleted; public Store(LocalDateTime createdAt, Long storeId, Long departmentId, String name, String location, - String description, String noticeTitle, String noticeContent, String openTime, Boolean isActive, Boolean deleted) { + String description, String noticeTitle, String noticeContent, String openTime, Boolean isActive, + Boolean deleted) { super(createdAt); this.storeId = storeId; this.departmentId = departmentId; @@ -70,7 +74,8 @@ public Store(LocalDateTime createdAt, Long storeId, Long departmentId, String na this.deleted = deleted; } - public void updateInfo(String name, String location, String description, String noticeTitle, String notice, String openTime) { + public void updateInfo(String name, String location, String description, String noticeTitle, String notice, + String openTime) { if (name != null) this.name = name; if (location != null) diff --git a/nowait-domain/domain-core-rdb/src/main/java/com/nowait/domaincorerdb/store/repository/StoreRepository.java b/nowait-domain/domain-core-rdb/src/main/java/com/nowait/domaincorerdb/store/repository/StoreRepository.java index 921a0ad2..83d7d324 100644 --- a/nowait-domain/domain-core-rdb/src/main/java/com/nowait/domaincorerdb/store/repository/StoreRepository.java +++ b/nowait-domain/domain-core-rdb/src/main/java/com/nowait/domaincorerdb/store/repository/StoreRepository.java @@ -18,6 +18,8 @@ public interface StoreRepository extends JpaRepository, StoreCustom Optional findByStoreIdAndDeletedFalse(Long storeId); + Optional findByPublicCodeAndDeletedFalse(String publicCode); + Slice findAllByDeletedFalseOrderByStoreIdAsc(Pageable pageable); @Query(value = """