2025-07-12 Line 訂單系統-C 階段 建立兩個實際可執行的核心檔案 Webhookhook後端 Vue前端訂單記錄頁面
我們現在就完整進入 📘 階段 C — LINE 訂單整合(前端+後端連動) 的實作階段。
接下來我會幫你建立兩個實際可執行的核心檔案:
1️⃣ backend/routes/lineWebhook.js — Node.js Webhook 後端
2️⃣ frontend/src/views/LineOrders.vue — Vue3 前端訂單紀錄頁面
🧩 一、Node.js 後端 — backend/routes/lineWebhook.js
這個檔案的作用是:
讓 LINE Bot 把使用者訊息(例如輸入「商品123」)傳到你的後端,
後端查 MySQL 回傳商品資料,再用 LINE API 回覆給使用者。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74
| import express from "express"; import axios from "axios"; import crypto from "crypto"; import mysql from "mysql2/promise";
const router = express.Router();
const pool = mysql.createPool({ host: process.env.DB_HOST, user: process.env.DB_USER, password: process.env.DB_PASSWORD, database: process.env.DB_NAME, });
function validateSignature(body, signature) { const hash = crypto .createHmac("SHA256", process.env.LINE_CHANNEL_SECRET) .update(JSON.stringify(body)) .digest("base64"); return hash === signature; }
router.post("/webhook", async (req, res) => { const signature = req.headers["x-line-signature"]; if (!validateSignature(req.body, signature)) { return res.status(401).send("Invalid signature"); }
const events = req.body.events; for (const event of events) { if (event.type === "message" && event.message.type === "text") { const userText = event.message.text.trim();
if (userText.startsWith("商品")) { const itemCode = userText.replace("商品", "").trim(); const [rows] = await pool.query( "SELECT name, price, description FROM products WHERE id = ?", [itemCode] );
let replyMessage = ""; if (rows.length > 0) { const product = rows[0]; replyMessage = `📦 商品名稱:${product.name}\n💲 價格:${product.price}\n📝 說明:${product.description}`; } else { replyMessage = "查無此商品,請確認代號是否正確。"; }
await axios.post( "https://api.line.me/v2/bot/message/reply", { replyToken: event.replyToken, messages: [{ type: "text", text: replyMessage }], }, { headers: { "Content-Type": "application/json", Authorization: `Bearer ${process.env.LINE_CHANNEL_ACCESS_TOKEN}`, }, } ); } } }
res.status(200).end(); });
export default router;
|
📁 檔案整合說明
請確認 backend/server.js 中有加入這段:
1 2 3
| import lineWebhook from "./routes/lineWebhook.js"; app.use(express.json()); app.use("/api", lineWebhook);
|
然後 .env 需有以下參數:
1 2
| LINE_CHANNEL_SECRET=你的LINE_CHANNEL_SECRET LINE_CHANNEL_ACCESS_TOKEN=你的LINE_CHANNEL_ACCESS_TOKEN
|
🧩 二、Vue3 前端 — frontend/src/views/LineOrders.vue
這個頁面主要讓管理者在後台看到所有來自 LINE 的訂單紀錄。
假設你的後端有一個 /api/orders API,可以回傳 LINE 送進資料庫的訂單資料。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
| <template> <div class="line-orders"> <h1>📱 LINE 訂單紀錄</h1>
<div v-if="loading">讀取中...</div> <div v-else> <table> <thead> <tr> <th>訂單編號</th> <th>用戶名稱</th> <th>商品名稱</th> <th>數量</th> <th>狀態</th> <th>建立時間</th> </tr> </thead> <tbody> <tr v-for="order in orders" :key="order.id"> <td>{{ order.id }}</td> <td>{{ order.user_name }}</td> <td>{{ order.product_name }}</td> <td>{{ order.quantity }}</td> <td>{{ order.status }}</td> <td>{{ new Date(order.created_at).toLocaleString() }}</td> </tr> </tbody> </table> </div> </div> </template>
<script setup> import { ref, onMounted } from "vue"; import axios from "axios";
const orders = ref([]); const loading = ref(true);
onMounted(async () => { try { const res = await axios.get("http://localhost:3000/api/orders"); orders.value = res.data; } catch (err) { console.error("無法取得訂單資料:", err); } finally { loading.value = false; } }); </script>
<style scoped> .line-orders { padding: 1.5rem; } table { width: 100%; border-collapse: collapse; } th, td { border: 1px solid #ddd; padding: 8px; } th { background: #f5f5f5; } </style>
|
⚙️ 前後端連動測試流程
| 步驟 |
動作 |
說明 |
| ① |
啟動 MySQL、Node.js (npm run dev) |
確保 /api/webhook 可以接收請求 |
| ② |
使用 ngrok 將你的 port 3000 對外公開 |
ngrok http 3000 |
| ③ |
在 LINE Developers → Messaging API → Webhook URL 設定 https://<ngrok-url>/api/webhook |
測試訊息傳遞 |
| ④ |
在 LINE 輸入「商品 1」 |
後端查 MySQL,回傳商品資訊 |
| ⑤ |
在 Vue3 後台 LineOrders.vue 檢視訂單紀錄 |
驗證資料流是否完整 |
是否要我幫你繼續產生:
👉 對應的 /api/orders 後端 API(讓 LineOrders.vue 可以正常顯示訂單)?
這會是 C4 子階段 的最後一塊拼圖。