今天我們將實作新增訂單和訂單管理功能。這兩個功能對於餐廳後台管理系統來說非常重要,它們使得餐廳能夠輕鬆處理顧客的訂單,並保持訂單歷史記錄。接下來,我們將深入了解這些功能的實作。
我們要實作的新增訂單和訂單管理功能包括以下幾點:
首先,我們來看Controller層的實作。這個層次負責處理Web頁面(Thymeleaf)的請求和處理API請求。以下是相關的程式碼:
@Controller
@RequestMapping("/orders")
@RequiredArgsConstructor
@Slf4j
public class DishOrderController {
private final DishService dishService;
private final OrderService orderService;
// 顯示新增訂單頁面
@GetMapping("/create")
public String createOrder(Model model) {
List<DishEntity> dishes = dishService.getAllDishes();
model.addAttribute("dishes", dishes);
return "create-order";
}
// 處理新增訂單的API請求
@PostMapping("/place")
public ResponseEntity<OrderResponse> placeOrder(@RequestBody List<OrderDetailsRequest> orderItems) {
return ResponseEntity.ok(orderService.placeOrder(orderItems));
}
// 刪除訂單
@GetMapping("/delete/{orderId}")
public String deleteOrder(@PathVariable Long orderId) {
orderService.deleteOrder(orderId);
return "redirect:/orders";
}
// 顯示所有訂單
@GetMapping()
public String getAllOrders(Model model) {
List<OrderEntity> orders = orderService.getAllOrders();
model.addAttribute("orders", orders);
return "orders";
}
// 顯示訂單詳細內容
@GetMapping("/{orderId}")
public String getOrderDetails(@PathVariable("orderId") Long orderId, Model model) {
OrderEntity order = orderService.getOrderById(orderId);
List<OrderDetailEntity> orderDetails = order.getOrderDetails();
model.addAttribute("order", order);
model.addAttribute("orderDetails", orderDetails);
return "orders";
}
}
接下來,我們將看一下Service層的實作,特別是OrderService
。這個層次負責處理業務邏輯。以下是相關的程式碼:
@Service
@RequiredArgsConstructor
public class OrderService {
private final DishRepository dishRepository;
private final OrderRepository orderRepository;
// 新增訂單並返回訂單號碼
public OrderResponse placeOrder(List<OrderDetailsRequest> orderItems) {
// 創建訂單實體
OrderEntity order = new OrderEntity();
order.setDateTime(LocalDateTime.now());
OrderEntity orderDB = orderRepository.save(order);
int totalPrice = 0;
int index = 0;
for (OrderDetailsRequest item : orderItems) {
var dish = dishRepository.findById(item.getDishId()).orElse(null);
var subTotal = item.getPrice() * item.getCount();
if (dish == null) continue;
OrderDetailEntity orderDetail = new OrderDetailEntity();
orderDetail.getId().setOrderId(orderDB.getId());
orderDetail.getId().setDno(index);
index += 1;
orderDetail.setDish(dish);
orderDetail.setCount(item.getCount());
orderDetail.setTotal(subTotal);
// 設定訂單項目關聯至訂單
orderDB.addOrderDetail(orderDetail);
totalPrice += subTotal;
}
orderDB.setTotalPrice(totalPrice);
// 儲存訂單至資料庫
orderRepository.save(orderDB);
return OrderResponse.builder()
.orderId(orderDB.getId())
.build();
}
// 獲取所有訂單
public List<OrderEntity> getAllOrders() {
return orderRepository.findAll();
}
// 根據訂單ID獲取訂單
public OrderEntity getOrderById(Long orderId) {
return orderRepository.findById(orderId).orElse(null);
}
// 刪除訂單
public void deleteOrder(Long orderId) {
orderRepository.deleteById(orderId);
}
}
資料表(實體類)在第26天文章有詳細介紹和創建。
在Repository層,我們只需要簡單地繼承JpaRepository
接口即可,這樣我們就可以擁有基本的資料庫操作。以下是相關的程式碼:
public interface OrderDetailRepository extends JpaRepository<OrderDetailEntity, Long> {
// 只需繼承JpaRepository即可擁有基本操作
}
@Repository
public interface OrderRepository extends JpaRepository<OrderEntity, Long> {
// 只需繼承JpaRepository即可擁有基本操作
}
最後,我們來看一下View層,這裡包括了新增訂單頁面和訂單管理頁面的HTML Thymeleaf模板。
這是新增訂單的HTML模板,它包含了一個表單,員工可以在這個表單中選擇餐點並輸入訂購數量:
訂單建立成功之提示
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Order</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.10.5/font/bootstrap-icons.css">
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
<script src="/order.js"></script>
</head>
<body>
<div class="container">
<div th:insert="~{navbar}"></div>
<div th:insert="~{create-order-dialog}"></div>
<!-- <div class="modal"></div>-->
<div class="row">
<div class="col-md-6">
<h2>Menu</h2>
<ul class="list-group">
<li class="list-group-item" th:each="dish : ${dishes}">
<div th:data-dish-id="${dish.id}">
<span th:text="${dish.name}"></span> - $<span th:text="${dish.price}"></span>
</div>
</li>
</ul>
</div>
<div class="col-md-6">
<div class="row">
<div class="col"><h2>Order Summary</h2></div>
<div class="col">
<button id="placeOrderBtn"
class="btn btn-primary" disabled="true">
送出訂單
</button>
</div>
</div>
<ul class="list-group" id="orderSummary">
</ul>
<div class="row mt-3">
<div class="col-md-6">
<h4>Total:</h4>
</div>
<div class="col-md-6">
<h4 id="totalAmount">$0.00</h4>
</div>
</div>
</div>
</div>
</div>
</body>
</html>
這是訂單管理的HTML模板,用於顯示所有訂單的列表,以及訂單的詳細內容:
<!DOCTYPE html>
<html lang="zh-tw" xmlns:th="http://www.thymeleaf.org">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<title>Orders</title>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.10.5/font/bootstrap-icons.css">
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
</head>
<body>
<div class="container">
<div th:insert="~{navbar}"></div>
<h1>Orders</h1>
<table class="table">
<thead>
<tr>
<th>ID</th>
<th>Order Date</th>
<th>Total Amount</th>
<th>Details</th>
</tr>
</thead>
<tbody>
<!-- Iterate over the list of orders -->
<th:block th:each="order : ${orders}" class="card">
<tr class="card-header">
<td th:text="${order.id}"></td>
<td th:text="${#temporals.format(order.dateTime, 'yyyy-MM-dd HH:mm:ss')}"></td>
<td>$<span th:text="${order.totalPrice}"></span></td>
<td>
<button class="btn btn-primary" data-toggle="collapse"
th:data-target="'#order-details-' + ${order.id}">Details</button>
<a class="btn btn-danger" th:href="@{/orders/delete/{orderId}(orderId=${order.id})}"><i class="bi bi-trash3"></i></a>
</td>
</tr>
<!-- Add a hidden row for order details -->
<tr class="collapse card-body" th:id="'order-details-' + ${order.id}">
<td colspan="4">
<!-- Render order details here -->
<ul>
<!-- Iterate over the order details -->
<li th:each="detail : ${order.orderDetails}"
th:text="${detail.id.dno+1} + ' '+ ${detail.dish.name} + ' $' + ${detail.total/detail.count} + 'x' + ${detail.count} + ' ...... $' + ${detail.total}"></li>
</ul>
</td>
</tr>
</th:block>
</tbody>
</table>
</div>
</body>
</html>
在這篇文章中,我們成功實作了新增訂單和訂單管理功能。這些功能使得餐廳能夠有效地管理顧客的訂單並保持訂單歷史記錄。在明天的文章中,我們將繼續擴展我們的餐廳後台點餐應用,實作營業分析功能。敬請期待!