在這一篇文章中,我們將實作餐點管理功能。這是一個重要的功能,它讓我們能夠輕鬆管理餐廳菜單,包括餐點的新增、修改、查詢和刪除。讓我們一起開始吧!
我們要實作的餐點管理功能包括以下幾點:
我們將實作以下API端點:
/dishes
/dishes/create
/dishes/delete/{dishId}
/dishes/edit/{dishId}
首先,我們將建立Controller層,用於處理Thymeleaf網頁和處理API請求。以下是相關的程式碼:
@Controller
@RequestMapping("/dishes")
@RequiredArgsConstructor
@Slf4j
public class DishController {
    private final DishService dishService;
    // 獲取所有餐點
    @GetMapping
    public String getAllDishes(Model model) {
        List<DishEntity> dishes = dishService.getAllDishes();
        model.addAttribute("dishes", dishes);
        return "dishes";
    }
    // 新增餐點表單
    @GetMapping("/create")
    public String createDishForm(Model model) {
        model.addAttribute("dish", new DishEntity());
        model.addAttribute("dishTypes", dishService.getAllDishTypes());
        return "create-dish";
    }
    // 執行新增餐點
    @PostMapping("/create")
    public String createDish(@ModelAttribute("dish") DishEntity dish) {
        DishTypeEntity dishType = dishService.getDishTypeByName(dish.getDishType().getName());
        if (dishType != null) {
            dish.setDishType(dishType);
        } else {
            dishType = new DishTypeEntity();
            dishType.setName(dish.getDishType().getName());
            dishType = dishService.createDishType(dishType);
            dish.setDishType(dishType);
        }
        dishService.createDish(dish);
        return "redirect:/dishes";
    }
    // 編輯餐點表單
    @GetMapping("/edit/{dishId}")
    public String editDishForm(@PathVariable Long dishId, Model model) {
        model.addAttribute("dish", dishService.getDishById(dishId));
        model.addAttribute("dishTypes", dishService.getAllDishTypes());
        return "edit-dish";
    }
    // 執行編輯餐點
    @PostMapping("/edit/{dishId}")
    public String editDish(@PathVariable Long dishId, @ModelAttribute("dish") DishEntity updatedDish) {
        dishService.updateDish(dishId, updatedDish);
        return "redirect:/dishes";
    }
    @PostMapping("/delete/{dishId}")
    public String deleteDish(@PathVariable Long dishId) {
        dishService.deleteDish(dishId);
        return "redirect:/dishes";
    }
}
在Repository層,我們將建立用於餐點和餐點種類的Repository接口。我們使用Spring Data JPA來簡化資料庫操作,因此這些接口只需繼承JpaRepository即可,無需編寫額外的程式碼。
@Repository
public interface DishRepository extends JpaRepository<DishEntity, Long> {
    // 這裡不用寫程式碼,只要將DishRepository繼承JpaRepository就可有基本的資料庫新增讀寫功能
}
@Repository
public interface DishTypeRepository extends JpaRepository<DishTypeEntity, Long> {
    Optional<DishTypeEntity> findByName(String name);
}
最後,我們將建立Thymeleaf模板來呈現餐點管理頁面。這包括新增餐點頁面、編輯餐點頁面和餐點管理總覽頁面。

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
  <meta charset="utf-8">
  <title>Create Dish</title>
  <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
</head>
<body>
<div class="container">
  <h1>新增餐點</h1>
  <form action="/dishes/create" method="post" th:object="${dish}">
    <div class="form-group">
      <label>Type:</label>
      <input type="text" class="form-control" list="dishTypeList" th:field="*{dishType.name}" required>
      <datalist id="dishTypeList">
        <option th:each="dishType : ${dishTypes}" th:value="${dishType.name}"></option>
      </datalist>
    </div>
    <div class="form-group">
      <label for="name">Name:</label>
      <input type="text" class="form-control" id="name" name="name" th:field="*{name}" required />
    </div>
    <div class="form-group">
      <label for="price">Price:</label>
      <input type="number" class="form-control" id="price" name="price" th:field="*{price}" required />
    </div>
    <div class="form-group">
      <label for="description">Description:</label>
      <textarea class="form-control" id="description" name="description" th:field="*{description}"></textarea>
    </div>
    <button type="submit" class="btn btn-primary">Create</button>
  </form>
</div>
</body>
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
  <meta charset="utf-8">
  <title>Edit Dish</title>
  <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
</head>
<body class="container">
<h1>編輯餐點</h1>
<form th:action="'/dishes/edit/' + ${dishId}" method="post" th:object="${dish}">
  <div class="form-group">
    <label for="typeId">Type:</label>
    <input type="text" class="form-control" list="dishTypeList" id="typeId" th:field="*{dishType.name}" required>
    <datalist id="dishTypeList">
      <option th:each="dishType : ${dishTypes}" th:value="${dishType.name}"></option>
    </datalist>
  </div>
  <div class="form-group">
    <label for="name">Name:</label>
    <input class="form-control" type="text" id="name" name="name" th:field="*{name}" required />
  </div>
  <div class="form-group">
    <label for="description">Description:</label>
    <textarea class="form-control" id="description" name="description" th:field="*{description}"></textarea>
  </div>
  <div class="form-group">
    <label for="price">Price:</label>
    <input class="form-control" type="number" id="price" name="price" th:field="*{price}" required />
  </div>
  <div class="form-group">
    <button class="btn btn-primary" type="submit">Save</button>
  </div>
</form>
</body>
</html>

<!DOCTYPE html>
<html lang="zh-tw" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="utf-8">
    <title>Dishes</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">
</head>
<body>
<div class="container">
    <div th:insert="~{navbar}"></div>
    <table class="table">
        <thead>
        <tr>
            <th>Index</th>
            <th>Name</th>
            <th>Description</th>
            <th>Price</th>
            <th>Type</th>
            <th>Action</th>
        </tr>
        </thead>
        <tbody>
        <tr th:each="dish,iterStat : ${dishes}">
            <td th:text="${iterStat.index+1}"></td>
            <td th:text="${dish.name}"></td>
            <td th:text="${dish.description}"></td>
            <td th:text="'$'+${dish.price}"></td>
            <td th:text="${dish.dishType.name}"></td>
            <td>
                <a class="btn btn-info" th:href="@{/dishes/edit/{dishId}(dishId=${dish.id})}"><i class="bi bi-pencil-square"></i></a>
                <a class="btn btn-danger" th:href="@{/dishes/delete/{dishId}(dishId=${dish.id})}"><i class="bi bi-trash3"></i></a>
            </td>
        </tr>
        </tbody>
    </table>
    <a class="btn btn-success" href="/dishes/create">新增餐點</a>
</div>
</body>
</html>
在這篇文章中,我們實作了餐點管理功能,讓你能夠輕鬆管理餐廳菜單。我們建立了Controller層來處理頁面和API請求,Repository層來處理資料庫操作,以及Thymeleaf模板來呈現頁面。接下來,在明天的文章中,我們將實作新增訂單和訂單管理功能。敬請期待!