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,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;
Expand All @@ -25,6 +26,7 @@ public class StoreCreateRequest {

public Store toEntity() {
return Store.builder()
.publicCode(TokenGenerator.base62(12))
.departmentId(departmentId)
.name(name)
.location(location)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
public class StoreCreateResponse {

private Long storeId;
private String publicCode;
private Long departmentId;
private String name;
private String location;
Expand All @@ -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())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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)
)
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<Menu> menus = menuRepository.findAllByStoreIdAndDeletedFalseOrderBySortOrder(storeId);

List<MenuReadDto> menuReadResponse = menus.stream()
Expand All @@ -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<MenuImage> images = menuImageRepository.findByMenu(menu);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,29 +32,48 @@
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(
ApiUtils.success(response)
);
}

@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
) {
Expand All @@ -64,7 +83,7 @@ public ResponseEntity<?> getOrderItems(
return ResponseEntity.status(HttpStatus.OK).body(ApiUtils.success(List.of()));
}
String sessionId = session.getId();
List<OrderResponseDto> orderItems = orderService.getOrderItemsGroupByOrderId(storeId, tableId, sessionId);
List<OrderResponseDto> orderItems = orderService.getOrderItemsGroupByOrderId(publicCode, tableId, sessionId);
return ResponseEntity.
status(HttpStatus.OK)
.body(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 저장
Expand Down Expand Up @@ -95,9 +95,9 @@ public OrderCreateResponseDto createOrder(Long storeId, Long tableId,

@Transactional(readOnly = true)
public List<OrderResponseDto> getOrderItemsGroupByOrderId(
Long storeId, Long tableId, String sessionId) {
String publicCode, Long tableId, String sessionId) {

List<UserOrder> userOrders = orderRepository.findByStore_StoreIdAndTableIdAndSessionId(storeId, tableId, sessionId);
List<UserOrder> userOrders = orderRepository.findByStore_PublicCodeAndTableIdAndSessionId(publicCode, tableId, sessionId);

// orderId 기준으로 바로 변환
return userOrders.stream()
Expand All @@ -116,8 +116,8 @@ public List<OrderResponseDto> 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()) {
Expand All @@ -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<CartItemDto> items) {
private String generateOrderSignature(String storeId, Long tableId, List<CartItemDto> items) {
String cartString = items.stream()
.sorted((a, b) -> a.getMenuId().compareTo(b.getMenuId())) // 메뉴 ID 기준 정렬
.map(item -> item.getMenuId() + ":" + item.getQuantity())
Expand Down
Original file line number Diff line number Diff line change
@@ -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() {}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
public interface OrderRepository extends JpaRepository<UserOrder, Long> {
boolean existsBySignatureAndCreatedAtAfter(String signature, LocalDateTime createdAt);

List<UserOrder> findByStore_StoreIdAndTableIdAndSessionId(Long storeId, Long tableId, String sessionId);
List<UserOrder> findByStore_PublicCodeAndTableIdAndSessionId(String publicCode, Long tableId, String sessionId);

@EntityGraph(attributePaths = {"orderItems", "orderItems.menu"})
List<UserOrder> findAllByStore_StoreIdAndCreatedAtBetween(Long storeId, LocalDateTime startDateTime, LocalDateTime endDateTime);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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;
Expand All @@ -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)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ public interface StoreRepository extends JpaRepository<Store, Long>, StoreCustom

Optional<Store> findByStoreIdAndDeletedFalse(Long storeId);

Optional<Store> findByPublicCodeAndDeletedFalse(String publicCode);

Slice<Store> findAllByDeletedFalseOrderByStoreIdAsc(Pageable pageable);

@Query(value = """
Expand Down