一、系统架构设计
自动售货系统的核心在于处理商品库存、用户选择和交易流程三大环节。采用模块化设计可提升代码可维护性,建议划分以下功能模块:
- 商品管理模块:存储商品信息(ID、名称、价格、库存)
- 库存控制模块:处理商品增减和库存预警
- 支付处理模块:模拟货币交易逻辑
- 用户界面模块:提供可视化操作界面
// 基础数据结构示例const vendingMachine = {products: [{ id: 1, name: '矿泉水', price: 2, stock: 10 },{ id: 2, name: '薯片', price: 5, stock: 8 }],coins: [1, 2, 5, 10], // 可接受硬币面额currentBalance: 0};
二、核心功能实现
1. 商品展示与选择
通过数组遍历动态生成商品列表,使用事件监听处理用户选择:
function displayProducts() {const productList = document.getElementById('product-list');productList.innerHTML = vendingMachine.products.map(product => `<div class="product-item" data-id="${product.id}"><h3>${product.name}</h3><p>价格: ¥${product.price}</p><p>库存: ${product.stock}</p><button class="select-btn">选择</button></div>`).join('');// 添加选择事件document.querySelectorAll('.select-btn').forEach(btn => {btn.addEventListener('click', handleProductSelection);});}
2. 库存管理系统
实现原子化的库存操作,防止并发问题:
function updateStock(productId, quantity) {const productIndex = vendingMachine.products.findIndex(p => p.id === productId);if (productIndex === -1) return false;const newStock = vendingMachine.products[productIndex].stock + quantity;if (newStock < 0) return false; // 库存不足vendingMachine.products[productIndex].stock = newStock;return true;}// 使用示例if (updateStock(1, -1)) {console.log('出货成功');} else {console.log('库存不足');}
3. 支付处理逻辑
模拟完整的货币交易流程,包含金额计算和找零功能:
function processPayment(amount) {if (amount < vendingMachine.currentBalance) {return { success: false, message: '金额不足' };}const change = amount - vendingMachine.currentBalance;vendingMachine.currentBalance = 0; // 重置余额return {success: true,change: calculateChange(change),message: '交易成功'};}function calculateChange(amount) {const coins = [...vendingMachine.coins].sort((a,b) => b-a);let remaining = amount;const change = [];for (const coin of coins) {while (remaining >= coin) {change.push(coin);remaining -= coin;}}return change;}
三、用户交互优化
1. 硬币投入模拟
实现可视化的硬币投入效果:
function insertCoin(coinValue) {if (!vendingMachine.coins.includes(coinValue)) {showMessage('无效硬币');return;}vendingMachine.currentBalance += coinValue;updateBalanceDisplay();animateCoinDrop(coinValue);}function updateBalanceDisplay() {document.getElementById('balance').textContent =`当前余额: ¥${vendingMachine.currentBalance}`;}
2. 交易状态反馈
通过UI元素实时显示系统状态:
function showMessage(text, isError = false) {const msgElement = document.getElementById('system-message');msgElement.textContent = text;msgElement.style.color = isError ? 'red' : 'green';// 3秒后自动消失setTimeout(() => {msgElement.textContent = '';}, 3000);}
四、系统扩展建议
- 持久化存储:使用localStorage保存系统状态
```javascript
function saveSystemState() {
localStorage.setItem(‘vendingMachine’,
JSON.stringify(vendingMachine));
}
function loadSystemState() {
const saved = localStorage.getItem(‘vendingMachine’);
if (saved) {
Object.assign(vendingMachine, JSON.parse(saved));
}
}
2. **多设备同步**:通过WebSocket实现多终端数据同步3. **数据分析模块**:记录销售数据并生成报表4. **异常处理**:添加网络请求超时和重试机制# 五、最佳实践总结1. **状态管理**:将系统状态集中管理,避免分散更新2. **输入验证**:对所有用户输入进行类型和范围检查3. **错误隔离**:使用try-catch处理可能出错的代码块4. **性能优化**:对频繁更新的DOM操作使用文档片段(DocumentFragment)5. **可测试性**:将核心逻辑与UI分离,便于单元测试完整实现示例可参考以下结构:
index.html # 主页面
styles.css # 样式文件
vending.js # 核心逻辑
ui-controller.js # 界面交互
storage.js # 数据持久化
```
通过这种模块化设计,系统可轻松扩展新功能,如添加会员系统、优惠券功能或接入第三方支付。开发者可根据实际需求调整各模块的实现细节,保持代码的灵活性和可维护性。