1.完整的点餐系统页面
2. 主要功能和改进:
-
菜单管理:
- 上架和下架菜品的功能正常工作。
- 新增菜品和修改菜品信息的功能正常工作。
-
购物车模块:
- 在总价后面增加了“会员价”一栏,展示每个菜品在会员折扣下的总价。
- 结算时根据是否是会员来计算相应的总金额,并从会员卡余额中扣除或要求用户输入支付金额并计算找零。
-
会员功能:
- 可以切换会员状态,并在结算时应用会员折扣。
- 支持会员充值功能,可以增加会员卡余额。
-
打印小票功能:
- 点击“打印小票”按钮后,会弹出一个小票模态框,展示点餐号、点餐时间、菜品详情、总价及会员价(如果适用)。
3.详细代码
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>点餐系统</title>
<style>
body {
font-family: Arial, sans-serif;
background-color: #f4f4f9;
margin: 0;
padding: 20px;
}
.container {
width: 80%;
margin: auto;
background-color: white;
padding: 20px;
border-radius: 10px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
}
h1 {
text-align: center;
}
.menu-section, .cart-section, .admin-section, .membership-section {
display: flex;
justify-content: space-between;
margin-bottom: 20px;
}
.menu-item, .cart-item, .admin-item, .membership-item {
width: 45%;
background-color: white;
padding: 20px;
border-radius: 10px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
}
.menu-item button, .cart-item button, .admin-item button, .membership-item button {
padding: 5px 10px;
background-color: #007bff;
color: white;
border: none;
border-radius: 5px;
cursor: pointer;
}
.menu-item button:hover, .cart-item button:hover, .admin-item button:hover, .membership-item button:hover {
background-color: #0056b3;
}
table {
width: 100%;
border-collapse: collapse;
}
th, td {
padding: 12px;
text-align: left;
border-bottom: 1px solid #ddd;
}
th {
background-color: #f2f2f2;
}
tr:hover {
background-color: #f1f1f1;
}
.total {
margin-top: 20px;
font-size: 18px;
font-weight: bold;
}
.checkout-section {
margin-top: 20px;
}
.checkout-section input[type="number"] {
width: 100px;
padding: 5px;
border: 1px solid #ccc;
border-radius: 5px;
margin-right: 10px;
}
.checkout-section button {
padding: 5px 10px;
background-color: #28a745;
color: white;
border: none;
border-radius: 5px;
cursor: pointer;
}
.checkout-section button:hover {
background-color: #218838;
}
.admin-form input[type="text"], .admin-form input[type="number"] {
width: 100%;
padding: 10px;
margin-bottom: 10px;
border: 1px solid #ccc;
border-radius: 5px;
}
.membership-form input[type="number"] {
width: 100%;
padding: 10px;
margin-bottom: 10px;
border: 1px solid #ccc;
border-radius: 5px;
}
.membership-status {
margin-top: 10px;
font-size: 16px;
font-weight: bold;
}
.receipt-modal {
display: none;
position: fixed;
z-index: 1;
left: 0;
top: 0;
width: 100%;
height: 100%;
overflow: auto;
background-color: rgba(0,0,0,0.4);
}
.receipt-modal-content {
background-color: #fefefe;
margin: 15% auto;
padding: 20px;
border: 1px solid #888;
width: 50%;
}
.close-button {
color: #aaa;
float: right;
font-size: 28px;
font-weight: bold;
}
.close-button:hover,
.close-button:focus {
color: black;
text-decoration: none;
cursor: pointer;
}
</style>
</head>
<body>
<div class="container">
<h1>点餐系统</h1>
<div class="membership-status" id="membership-status">当前状态: 非会员</div>
<div class="menu-section">
<div class="menu-item">
<h2>菜单</h2>
<table id="menu-table">
<thead>
<tr>
<th>菜品名称</th>
<th>价格</th>
<th>状态</th>
<th>操作</th>
</tr>
</thead>
<tbody id="menu-items">
<!-- 菜品项将动态生成 -->
</tbody>
</table>
</div>
<div class="cart-item">
<h2>购物车</h2>
<table>
<thead>
<tr>
<th>菜品名称</th>
<th>数量</th>
<th>单价</th>
<th>总价</th>
<th>会员价</th>
<th>操作</th>
</tr>
</thead>
<tbody id="cart-items"></tbody>
</table>
<div class="total" id="total-price">总价: ¥0.00</div>
<div class="total" id="member-price">会员价: ¥0.00</div>
<div class="checkout-section">
<button onclick="checkout()">结算</button>
<button onclick="printReceipt()">打印小票</button>
</div>
</div>
</div>
<div class="admin-section">
<div class="admin-item">
<h2>管理员操作</h2>
<form class="admin-form">
<input type="text" id="new-dish-name" placeholder="菜品名称" required>
<input type="number" id="new-dish-price" placeholder="价格" min="0" step="any" required>
<button type="button" onclick="addDish()">上架菜品</button>
</form>
<button onclick="toggleAdminForm()">修改菜品信息</button>
<div id="modify-dish-form" style="display: none;">
<select id="dish-to-modify" onchange="loadDishInfo()">
<option value="">选择菜品</option>
<!-- 菜品选项将动态生成 -->
</select>
<input type="text" id="modified-dish-name" placeholder="新的菜品名称" required>
<input type="number" id="modified-dish-price" placeholder="新的价格" min="0" step="any" required>
<button type="button" onclick="updateDish()">保存修改</button>
</div>
</div>
</div>
<div class="membership-section">
<div class="membership-item">
<h2>会员充值</h2>
<form class="membership-form">
<input type="number" id="recharge-amount" placeholder="充值金额" min="0" step="any" required>
<button type="button" onclick="recharge()">充值</button>
</form>
<div class="total" id="balance">余额: ¥0.00</div>
<button onclick="toggleMembership()">成为会员</button>
</div>
</div>
</div>
<!-- 小票模态框 -->
<div id="receiptModal" class="receipt-modal">
<div class="receipt-modal-content">
<span class="close-button" onclick="closeReceiptModal()">×</span>
<h2>小票</h2>
<p id="receipt-content"></p>
</div>
</div>
<script>
let dishes = [
{ name: '宫保鸡丁', price: 28, status: true },
{ name: '麻婆豆腐', price: 22, status: true },
{ name: '鱼香肉丝', price: 25, status: true },
{ name: '清蒸鲈鱼', price: 35, status: true }
];
let cart = [];
let balance = 0;
let isMember = false;
let orderNumber = 1;
function updateMenuDisplay() {
const menuItemsDiv = document.getElementById('menu-items');
menuItemsDiv.innerHTML = '';
dishes.forEach((dish, index) => {
const itemDiv = document.createElement('tr');
itemDiv.innerHTML = `
<td>${dish.name}</td>
<td>¥${dish.price.toFixed(2)}</td>
<td>${dish.status ? '上架' : '下架'}</td>
<td>
${dish.status ? `<button οnclick="addToCart('${dish.name}', ${dish.price})">加入购物车</button>` : ''}
<button οnclick="toggleStatus(${index})">${dish.status ? '下架' : '上架'}</button>
</td>
`;
menuItemsDiv.appendChild(itemDiv);
});
// 更新修改菜品信息的下拉框
const modifyDishSelect = document.getElementById('dish-to-modify');
modifyDishSelect.innerHTML = '<option value="">选择菜品</option>';
dishes.forEach(dish => {
const option = document.createElement('option');
option.value = dish.name;
option.textContent = dish.name;
modifyDishSelect.appendChild(option);
});
}
function addToCart(name, price) {
const existingItem = cart.find(item => item.name === name);
if (existingItem) {
existingItem.quantity++;
} else {
cart.push({ name, price, quantity: 1 });
}
updateCartDisplay();
}
function updateCartDisplay() {
const cartItemsDiv = document.getElementById('cart-items');
cartItemsDiv.innerHTML = '';
let totalPrice = 0;
let memberTotalPrice = 0;
cart.forEach((item, index) => {
const itemTotalPrice = item.price * item.quantity;
const itemMemberPrice = itemTotalPrice * 0.8; // 会员价八折
const itemDiv = document.createElement('tr');
itemDiv.innerHTML = `
<td>${item.name}</td>
<td>${item.quantity}</td>
<td>¥${item.price.toFixed(2)}</td>
<td>¥${itemTotalPrice.toFixed(2)}</td>
<td>¥${itemMemberPrice.toFixed(2)}</td>
<td>
<button οnclick="increaseQuantity(${index})">+</button>
<button οnclick="decreaseQuantity(${index})">-</button>
<button οnclick="removeFromCart(${index})">移除</button>
</td>
`;
cartItemsDiv.appendChild(itemDiv);
totalPrice += itemTotalPrice;
memberTotalPrice += itemMemberPrice;
});
document.getElementById('total-price').textContent = `总价: ¥${totalPrice.toFixed(2)}`;
document.getElementById('member-price').textContent = `会员价: ¥${memberTotalPrice.toFixed(2)}`;
}
function increaseQuantity(index) {
cart[index].quantity++;
updateCartDisplay();
}
function decreaseQuantity(index) {
if (cart[index].quantity > 1) {
cart[index].quantity--;
} else {
removeFromCart(index);
}
updateCartDisplay();
}
function removeFromCart(index) {
cart.splice(index, 1);
updateCartDisplay();
}
function checkout() {
if (cart.length === 0) {
alert('购物车为空,请先添加菜品!');
return;
}
let totalPrice = cart.reduce((sum, item) => sum + item.price * item.quantity, 0);
let memberTotalPrice = totalPrice * 0.8; // 会员价八折
if (isMember && balance >= memberTotalPrice) {
balance -= memberTotalPrice;
document.getElementById('balance').textContent = `余额: ¥${balance.toFixed(2)}`;
alert(`结算成功!会员价: ¥${memberTotalPrice.toFixed(2)}\n当前余额: ¥${balance.toFixed(2)}`);
} else if (!isMember) {
const payment = parseFloat(prompt(`请输入支付金额(总价: ¥${totalPrice.toFixed(2)})`));
if (isNaN(payment) || payment < totalPrice) {
alert('支付金额不足,请重新输入!');
return;
}
const change = payment - totalPrice;
alert(`结算成功!总价: ¥${totalPrice.toFixed(2)}\n支付金额: ¥${payment.toFixed(2)}\n找零: ¥${change.toFixed(2)}`);
} else {
alert('余额不足,请充值后再试!');
return;
}
printReceipt();
cart = [];
updateCartDisplay();
}
function addDish() {
const name = document.getElementById('new-dish-name').value.trim();
const price = parseFloat(document.getElementById('new-dish-price').value);
if (!name || isNaN(price)) {
alert('请输入完整且有效的信息!');
return;
}
dishes.push({ name, price, status: true });
updateMenuDisplay();
clearAdminForm();
}
function toggleStatus(index) {
dishes[index].status = !dishes[index].status;
updateMenuDisplay();
}
function toggleAdminForm() {
const form = document.getElementById('modify-dish-form');
form.style.display = form.style.display === 'none' ? 'block' : 'none';
}
function loadDishInfo() {
const selectedName = document.getElementById('dish-to-modify').value;
const dish = dishes.find(d => d.name === selectedName);
if (dish) {
document.getElementById('modified-dish-name').value = dish.name;
document.getElementById('modified-dish-price').value = dish.price;
}
}
function updateDish() {
const selectedName = document.getElementById('dish-to-modify').value;
const newName = document.getElementById('modified-dish-name').value.trim();
const newPrice = parseFloat(document.getElementById('modified-dish-price').value);
if (!selectedName || !newName || isNaN(newPrice)) {
alert('请输入完整且有效的信息!');
return;
}
const dishIndex = dishes.findIndex(d => d.name === selectedName);
if (dishIndex !== -1) {
dishes[dishIndex].name = newName;
dishes[dishIndex].price = newPrice;
updateMenuDisplay();
clearModifyForm();
}
}
function clearAdminForm() {
document.getElementById('new-dish-name').value = '';
document.getElementById('new-dish-price').value = '';
}
function clearModifyForm() {
document.getElementById('dish-to-modify').value = '';
document.getElementById('modified-dish-name').value = '';
document.getElementById('modified-dish-price').value = '';
}
function recharge() {
const amount = parseFloat(document.getElementById('recharge-amount').value);
if (isNaN(amount) || amount <= 0) {
alert('请输入有效的充值金额!');
return;
}
balance += amount;
document.getElementById('balance').textContent = `余额: ¥${balance.toFixed(2)}`;
alert(`充值成功!充值金额: ¥${amount.toFixed(2)}\n当前余额: ¥${balance.toFixed(2)}`);
document.getElementById('recharge-amount').value = '';
}
function toggleMembership() {
if (isMember) {
alert('您已经是会员了!');
} else {
isMember = true;
document.getElementById('membership-status').textContent = '当前状态: 会员';
alert('恭喜您成为会员!现在您可以享受八折优惠。');
}
}
function printReceipt() {
if (cart.length === 0) {
alert('购物车为空,无法打印小票!');
return;
}
const receiptContent = document.getElementById('receipt-content');
receiptContent.innerHTML = '';
const currentTime = new Date().toLocaleString();
let receiptText = `点餐号: ${orderNumber}<br>`;
receiptText += `点餐时间: ${currentTime}<br><br>`;
receiptText += `<table style="width: 100%; border-collapse: collapse;">`;
receiptText += `<thead><tr><th>菜品名称</th><th>数量</th><th>单价</th><th>总价</th></tr></thead><tbody>`;
cart.forEach(item => {
const itemTotalPrice = item.price * item.quantity;
receiptText += `<tr><td>${item.name}</td><td>${item.quantity}</td><td>¥${item.price.toFixed(2)}</td><td>¥${itemTotalPrice.toFixed(2)}</td></tr>`;
});
receiptText += '</tbody></table><br>';
const totalPrice = cart.reduce((sum, item) => sum + item.price * item.quantity, 0);
const memberTotalPrice = totalPrice * 0.8; // 会员价八折
receiptText += `总价: ¥${totalPrice.toFixed(2)}<br>`;
if (isMember) {
receiptText += `会员价: ¥${memberTotalPrice.toFixed(2)}<br>`;
}
receiptContent.innerHTML = receiptText;
openReceiptModal();
orderNumber++; // 增加订单号
}
function openReceiptModal() {
document.getElementById('receiptModal').style.display = 'block';
}
function closeReceiptModal() {
document.getElementById('receiptModal').style.display = 'none';
}
// 初始化显示
updateMenuDisplay();
</script>
</body>
</html>