上傳檔案到「/」
This commit is contained in:
12
PromptRecord.txt
Normal file
12
PromptRecord.txt
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
[2024-09-08] 新增 employee_votes API 需求
|
||||||
|
- ✅ 產生 Flask API 伺服器
|
||||||
|
- ✅ 使用 DB_connection.txt 連線到 employee_votes 資料表
|
||||||
|
- ✅ 實作 GET /v1/employee_votes (支援過濾)
|
||||||
|
- ✅ 實作 GET /v1/employee_votes/<id> (找不到回 404)
|
||||||
|
- ✅ 實作 POST /v1/employee_votes (JSON 接收, 欄位驗證, 成功回 201)
|
||||||
|
- ✅ 實作 PATCH /v1/employee_votes/<id> (更新 menu_item_id/is_active, 成功回 200)
|
||||||
|
- ✅ 實作 DELETE /v1/employee_votes/<id> (成功回 204)
|
||||||
|
- ✅ 所有寫入使用參數化查詢避免 SQL 注入
|
||||||
|
- ✅ 統一回應格式 { status, code, message, data }
|
||||||
|
- ✅ 統一錯誤格式 {status:"error", code, message}
|
||||||
|
- ✅ 啟用 CORS (允許本機前端)
|
289
index.html
Normal file
289
index.html
Normal file
@@ -0,0 +1,289 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="zh-TW">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>公司內部訂餐系統</title>
|
||||||
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||||
|
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css" rel="stylesheet">
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||||
|
min-height: 100vh;
|
||||||
|
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
||||||
|
}
|
||||||
|
.navbar-brand {
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 1.5rem;
|
||||||
|
}
|
||||||
|
.card {
|
||||||
|
border: none;
|
||||||
|
border-radius: 15px;
|
||||||
|
box-shadow: 0 8px 20px rgba(0,0,0,0.1);
|
||||||
|
transition: transform 0.3s ease;
|
||||||
|
}
|
||||||
|
.card:hover {
|
||||||
|
transform: translateY(-5px);
|
||||||
|
}
|
||||||
|
.card-img-top {
|
||||||
|
height: 200px;
|
||||||
|
object-fit: cover;
|
||||||
|
border-top-left-radius: 15px;
|
||||||
|
border-top-right-radius: 15px;
|
||||||
|
}
|
||||||
|
.category-header {
|
||||||
|
background: rgba(255,255,255,0.95);
|
||||||
|
border-radius: 10px;
|
||||||
|
padding: 15px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
box-shadow: 0 4px 15px rgba(0,0,0,0.1);
|
||||||
|
}
|
||||||
|
.price {
|
||||||
|
color: #28a745;
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 1.2rem;
|
||||||
|
}
|
||||||
|
.btn-order {
|
||||||
|
background: linear-gradient(45deg, #ff6b6b, #ee5a24);
|
||||||
|
border: none;
|
||||||
|
border-radius: 25px;
|
||||||
|
padding: 10px 25px;
|
||||||
|
font-weight: bold;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
}
|
||||||
|
.btn-order:hover {
|
||||||
|
transform: scale(1.05);
|
||||||
|
box-shadow: 0 5px 15px rgba(255,107,107,0.4);
|
||||||
|
}
|
||||||
|
.hero-section {
|
||||||
|
background: rgba(255,255,255,0.95);
|
||||||
|
border-radius: 20px;
|
||||||
|
padding: 40px;
|
||||||
|
margin: 20px 0;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
|
||||||
|
<div class="container">
|
||||||
|
<a class="navbar-brand" href="#">
|
||||||
|
<i class="fas fa-utensils me-2"></i>
|
||||||
|
公司內部訂餐系統
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
<div class="container py-5">
|
||||||
|
<div class="hero-section">
|
||||||
|
<h1 class="display-4 fw-bold text-primary mb-3">
|
||||||
|
<i class="fas fa-concierge-bell me-2"></i>
|
||||||
|
今日菜單
|
||||||
|
</h1>
|
||||||
|
<p class="lead text-muted">選擇您喜愛的餐點,享受美味時光</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{% if menu_items %}
|
||||||
|
{% set categories = menu_items|map(attribute='category')|unique|list %}
|
||||||
|
|
||||||
|
{% for category in categories %}
|
||||||
|
<div class="category-header">
|
||||||
|
<h2 class="h3 mb-0">
|
||||||
|
<i class="fas fa-folder me-2"></i>
|
||||||
|
{{ category }}
|
||||||
|
</h2>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row row-cols-1 row-cols-md-2 row-cols-lg-3 g-4 mb-5">
|
||||||
|
{% for item in menu_items if item.category == category %}
|
||||||
|
<div class="col">
|
||||||
|
<div class="card h-100">
|
||||||
|
<img src="{{ item.image_url }}" class="card-img-top" alt="{{ item.name }}"
|
||||||
|
onerror="this.src='https://via.placeholder.com/300x200/667eea/ffffff?text=餐點圖片'">
|
||||||
|
<div class="card-body">
|
||||||
|
<h5 class="card-title fw-bold">{{ item.name }}</h5>
|
||||||
|
<p class="card-text text-muted">{{ item.description }}</p>
|
||||||
|
<div class="d-flex justify-content-between align-items-center">
|
||||||
|
<span class="price">${{ "%0.2f"|format(item.price) }}</span>
|
||||||
|
<button class="btn btn-order" onclick="addToCart({{ item.id }}, '{{ item.name }}', {{ item.price }})">
|
||||||
|
<i class="fas fa-cart-plus me-2"></i>
|
||||||
|
加入訂單
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
{% else %}
|
||||||
|
<div class="text-center py-5">
|
||||||
|
<i class="fas fa-utensils fa-5x text-light mb-3"></i>
|
||||||
|
<h3 class="text-light">暫無菜單資料</h3>
|
||||||
|
<p class="text-light">請聯繫管理員更新菜單</p>
|
||||||
|
<a href="/init" class="btn btn-light btn-lg">
|
||||||
|
<i class="fas fa-sync me-2"></i>
|
||||||
|
初始化菜單
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Shopping Cart Modal -->
|
||||||
|
<div class="modal fade" id="cartModal" tabindex="-1">
|
||||||
|
<div class="modal-dialog modal-lg">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header bg-primary text-white">
|
||||||
|
<h5 class="modal-title">
|
||||||
|
<i class="fas fa-shopping-cart me-2"></i>
|
||||||
|
我的訂單
|
||||||
|
</h5>
|
||||||
|
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<div id="cartItems">
|
||||||
|
<p class="text-muted text-center">購物車是空的</p>
|
||||||
|
</div>
|
||||||
|
<div class="d-flex justify-content-between align-items-center mt-3">
|
||||||
|
<h5>總金額: <span id="totalAmount">$0.00</span></h5>
|
||||||
|
<button class="btn btn-success" onclick="submitOrder()">
|
||||||
|
<i class="fas fa-paper-plane me-2"></i>
|
||||||
|
提交訂單
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Floating Cart Button -->
|
||||||
|
<div class="position-fixed bottom-0 end-0 m-4">
|
||||||
|
<button class="btn btn-primary btn-lg rounded-pill shadow" data-bs-toggle="modal" data-bs-target="#cartModal">
|
||||||
|
<i class="fas fa-shopping-cart me-2"></i>
|
||||||
|
<span class="badge bg-danger" id="cartCount">0</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"></script>
|
||||||
|
<script>
|
||||||
|
let cart = [];
|
||||||
|
|
||||||
|
function addToCart(id, name, price) {
|
||||||
|
const existingItem = cart.find(item => item.id === id);
|
||||||
|
|
||||||
|
if (existingItem) {
|
||||||
|
existingItem.quantity += 1;
|
||||||
|
} else {
|
||||||
|
cart.push({
|
||||||
|
id: id,
|
||||||
|
name: name,
|
||||||
|
price: price,
|
||||||
|
quantity: 1
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
updateCartDisplay();
|
||||||
|
|
||||||
|
// Show success message
|
||||||
|
showToast('已加入購物車: ' + name);
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateCartDisplay() {
|
||||||
|
const cartCount = document.getElementById('cartCount');
|
||||||
|
const cartItems = document.getElementById('cartItems');
|
||||||
|
const totalAmount = document.getElementById('totalAmount');
|
||||||
|
|
||||||
|
// Update cart count
|
||||||
|
cartCount.textContent = cart.reduce((total, item) => total + item.quantity, 0);
|
||||||
|
|
||||||
|
// Update cart items
|
||||||
|
if (cart.length === 0) {
|
||||||
|
cartItems.innerHTML = '<p class="text-muted text-center">購物車是空的</p>';
|
||||||
|
} else {
|
||||||
|
cartItems.innerHTML = cart.map(item => `
|
||||||
|
<div class="card mb-2">
|
||||||
|
<div class="card-body py-2">
|
||||||
|
<div class="d-flex justify-content-between align-items-center">
|
||||||
|
<div>
|
||||||
|
<h6 class="mb-0">${item.name}</h6>
|
||||||
|
<small class="text-muted">$${item.price.toFixed(2)} x ${item.quantity}</small>
|
||||||
|
</div>
|
||||||
|
<div class="d-flex align-items-center">
|
||||||
|
<span class="fw-bold me-3">$${(item.price * item.quantity).toFixed(2)}</span>
|
||||||
|
<button class="btn btn-sm btn-outline-danger" onclick="removeFromCart(${item.id})">
|
||||||
|
<i class="fas fa-trash"></i>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`).join('');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update total amount
|
||||||
|
const total = cart.reduce((sum, item) => sum + (item.price * item.quantity), 0);
|
||||||
|
totalAmount.textContent = '$' + total.toFixed(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
function removeFromCart(id) {
|
||||||
|
cart = cart.filter(item => item.id !== id);
|
||||||
|
updateCartDisplay();
|
||||||
|
}
|
||||||
|
|
||||||
|
function submitOrder() {
|
||||||
|
if (cart.length === 0) {
|
||||||
|
showToast('請先選擇餐點', 'warning');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Here you would typically send the order to the server
|
||||||
|
const orderData = {
|
||||||
|
items: cart,
|
||||||
|
total: cart.reduce((sum, item) => sum + (item.price * item.quantity), 0),
|
||||||
|
timestamp: new Date().toISOString()
|
||||||
|
};
|
||||||
|
|
||||||
|
console.log('Order submitted:', orderData);
|
||||||
|
|
||||||
|
// Show success message
|
||||||
|
showToast('訂單提交成功!', 'success');
|
||||||
|
|
||||||
|
// Clear cart
|
||||||
|
cart = [];
|
||||||
|
updateCartDisplay();
|
||||||
|
|
||||||
|
// Close modal
|
||||||
|
bootstrap.Modal.getInstance(document.getElementById('cartModal')).hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
function showToast(message, type = 'success') {
|
||||||
|
// Create toast element
|
||||||
|
const toast = document.createElement('div');
|
||||||
|
toast.className = `position-fixed bottom-0 end-0 m-3 toast align-items-center text-white bg-${type} border-0`;
|
||||||
|
toast.setAttribute('role', 'alert');
|
||||||
|
toast.innerHTML = `
|
||||||
|
<div class="d-flex">
|
||||||
|
<div class="toast-body">
|
||||||
|
${message}
|
||||||
|
</div>
|
||||||
|
<button type="button" class="btn-close btn-close-white me-2 m-auto" data-bs-dismiss="toast"></button>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
|
||||||
|
document.body.appendChild(toast);
|
||||||
|
|
||||||
|
// Initialize and show toast
|
||||||
|
const bsToast = new bootstrap.Toast(toast);
|
||||||
|
bsToast.show();
|
||||||
|
|
||||||
|
// Remove toast after it's hidden
|
||||||
|
toast.addEventListener('hidden.bs.toast', () => {
|
||||||
|
document.body.removeChild(toast);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize cart display
|
||||||
|
updateCartDisplay();
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
23
main_Prompt.txt
Normal file
23
main_Prompt.txt
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
你是一個很有設計品味的網頁設計全端大師,且設計過多個餐廳用的系統;同時你也非常瞭解資料庫的運用及管理,現在我請想你幫助我設計一個公司內部用的訂餐系統,我會逐步告訴你需求
|
||||||
|
1.請先將每次我們的對話記錄在資料夾下的PromptRecord.txt,每一次都要記錄,之後我不會在每一步逐一提醒
|
||||||
|
2.請先連結到資料庫,連結方式請見資料夾下的DB_connection.txt
|
||||||
|
3.請抓取網址https://club.panjit.com.tw/back/menu/menu.php?1672970133&indexselectid=1中的菜單資訊,並將內容建立於DB內的menu_items資料表中,建立後將建立的資料呈現在畫面上
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
4.請產生一支可直接執行的 Flask API 伺服器,需求:
|
||||||
|
- 使用資料夾下的DB_connection.txt連線到menu_items資料表
|
||||||
|
|
||||||
|
- 路由:
|
||||||
|
- GET /v1/menu_items資料表:支援 ?main_course、?side_dish、?addon、?Order_Date、?is_active,要多回傳 {meta}
|
||||||
|
- GET /v1/menu_items資料表/<id>:找不到回 404
|
||||||
|
- POST /v1/menu_items資料表:接收 JSON {name,email,age},欄位驗證,成功回 201 並回新資料
|
||||||
|
- PATCH /v1/menu_items資料表/<id>:可更新任一欄位(main_course/side_dish/addon/Order_Date/is_active),成功回 200 回更新後資料
|
||||||
|
- DELETE /v1/menu_items資料表/<id>:成功回 204
|
||||||
|
|
||||||
|
- 所有寫入請用參數化查詢避免 SQL 注入
|
||||||
|
- 統一格式 { status,code,message,data }
|
||||||
|
- 統一錯誤格式 {status:"error", code, message}
|
||||||
|
- 啟用 CORS(允許本機前端)
|
||||||
|
|
||||||
|
5.請製作一網頁功能,可以對menu_items資料表做維護,功能為第4點的API為主,當USER送出後透過呼叫API去執行維護的功能
|
BIN
maintenance.html
Normal file
BIN
maintenance.html
Normal file
Binary file not shown.
3
requirements.txt
Normal file
3
requirements.txt
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
Flask
|
||||||
|
Flask-Cors
|
||||||
|
mysql-connector-python
|
Reference in New Issue
Block a user