去年帮本地一家连锁餐饮品牌升级点餐系统时,我选择了SpringBoot+微信小程序的组合方案。这种架构既能利用微信生态的流量红利,又能通过后端服务保证高并发场景下的稳定性。系统上线后,门店平均点餐耗时从原来的7分钟缩短到1分半钟,服务员人力成本降低了40%。
这个开源版本保留了核心功能模块,包括扫码桌台绑定、菜品分类展示、购物车管理、订单状态追踪和支付回调处理。特别适合中小型餐厅快速搭建自己的数字化点餐平台,也适合开发者学习现代餐饮系统的典型架构设计。
系统采用经典的前后端分离架构:
选择微信小程序而非原生App主要基于三点考虑:
数据库主要包含6个核心表:
dish(菜品表):包含菜品状态字段(上架/下架)、辣度标识等餐饮特色属性order(订单表):采用JSON字段存储快照化的菜品详情,避免历史订单受后续菜品修改影响table(桌台表):包含二维码编号、座位数等字段user(用户表):微信OpenID作为唯一标识cart(购物车表):采用Redis缓存+MySQL持久化双写策略payment(支付记录表):与微信支付流水号关联java复制// 订单实体示例
public class Order {
private Long id;
private String orderNo; // 业务流水号
private Long tableId;
private String openId;
private String dishItemsJson; // 菜品快照
private BigDecimal totalAmount;
private Integer status; // 0-待支付 1-已支付 2-已接单 3-已完成
private LocalDateTime createTime;
}
每个桌台生成唯一二维码,包含:
code复制restaurant://table/bind?storeId=1001&tableId=5
小程序端扫码后:
/api/table/check接口验证桌台有效性javascript复制// 小程序扫码处理
wx.scanCode({
success: (res) => {
const params = parseUrl(res.result);
wx.request({
url: '/api/table/check',
data: { storeId: params.storeId, tableId: params.tableId },
success: (res) => {
wx.setStorageSync('currentTable', res.data)
}
})
}
})
针对餐饮场景的特殊优化:
关键点:购物车数据在提交订单后自动清除,但保留3分钟防误操作恢复机制
订单状态流转采用状态模式实现:
mermaid复制stateDiagram
[*] --> 待支付
待支付 --> 已支付: 微信支付回调
已支付 --> 已接单: 商家确认
已接单 --> 已完成: 后厨出餐
已支付 --> 已取消: 超时未支付
已接单 --> 已退款: 用户申请
对应Spring状态机配置:
java复制@Configuration
public class OrderStateMachineConfig {
@Bean
public StateMachine<OrderStatus, OrderEvent> stateMachine() {
StateMachineBuilder.Builder<OrderStatus, OrderEvent> builder = StateMachineBuilder.builder();
builder.configureStates()
.withStates()
.initial(OrderStatus.WAIT_PAY)
.states(EnumSet.allOf(OrderStatus.class));
builder.configureTransitions()
.withExternal()
.source(OrderStatus.WAIT_PAY).target(OrderStatus.PAID)
.event(OrderEvent.PAY_SUCCESS)
.and()
.withExternal()
.source(OrderStatus.PAID).target(OrderStatus.ACCEPTED)
.event(OrderEvent.MERCHANT_CONFIRM);
return builder.build();
}
}
/api/payment/create创建预支付订单java复制// 支付回调处理示例
@PostMapping("/payment/notify")
public String paymentNotify(@RequestBody String notifyData) {
// 1. 验证签名
WXPayUtil.checkSign(notifyData);
// 2. 处理业务逻辑
Payment payment = parsePayment(notifyData);
if(payment.getReturnCode().equals("SUCCESS")) {
orderService.updateOrderPaid(payment.getOrderNo());
}
// 3. 返回微信要求的XML格式
return "<xml><return_code><![CDATA[SUCCESS]]></return_code></xml>";
}
out_trade_no(业务订单号)bash复制HSET cart:{tableId} dishId1 "{count:2, remark:'少辣'}"
最低生产环境配置:
推荐使用Docker Compose部署:
yaml复制version: '3'
services:
app:
image: openjdk:11-jre
ports:
- "8080:8080"
volumes:
- ./app.jar:/app.jar
command: java -jar /app.jar
mysql:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: 123456
volumes:
- ./mysql-data:/var/lib/mysql
项目结构说明:
code复制src/
├── main/
│ ├── java/
│ │ └── com/
│ │ └── restaurant/
│ │ ├── config/ # 配置类
│ │ ├── controller/ # 控制器
│ │ ├── entity/ # 实体类
│ │ ├── enums/ # 枚举类
│ │ ├── mapper/ # MyBatis接口
│ │ ├── service/ # 业务逻辑
│ │ └── utils/ # 工具类
│ └── resources/
│ ├── mapper/ # XML映射文件
│ ├── application.yml
│ └── banner.txt
└── test/ # 单元测试
重点阅读类:
WechatPayService:微信支付核心逻辑OrderStateMachine:订单状态机实现CartServiceImpl:购物车业务逻辑TableQrCodeGenerator:桌台二维码生成器调试建议:
application-dev.yml测试环境营销功能:
智能推荐:
硬件对接:
数据分析:
这个项目经过三个月的迭代开发,期间踩过不少坑。最深刻的体会是:餐饮系统的核心不在于技术复杂度,而在于对业务场景的深度理解。比如退单处理要考虑菜品制作进度,桌台管理要支持临时拼桌等特殊场景。建议开发者先到餐厅实地观察运营流程,再动手编码会事半功倍。