去年帮朋友的连锁快餐店做了一套扫码点餐小程序,从需求梳理到上线只用两周,日均订单稳定在 800+。这篇文章把整个开发过程拆开讲,包括技术选型、核心表结构、关键代码和踩过的坑,希望能给准备做类似项目的独立开发者一些参考。
一、需求梳理:别急着写代码
扫码点餐的核心链路其实很短:顾客扫桌码 → 进入点餐页 → 选菜下单 → 后厨接单 → 结账。但真正落地时,细节会决定项目成败。我在动手前先列了这份清单:
- 多桌并发:一张桌子可能多人同时扫码,购物车要能共享或合并
- 桌码绑定:二维码里必须携带桌号,且不能被顾客随意篡改
- 菜品规格:辣度、加料、份量等 SKU 组合
- 后厨出单:需要打印机或后厨端实时提醒
- 支付与对账:微信支付分账、退款、日结报表
先把这些想清楚,后面写代码才不会反复推翻。
二、技术选型
我最终选了微信小程序 + 云开发的组合,理由很实在:
- 云函数免服务器运维,小团队够用
- 云数据库自带实时监听,后厨端可以
watch订单变化 - 云存储直接放菜品图,省掉 CDN 配置
- 开发成本低,两周能上线
如果订单量级到日均几千单以上,建议换成自建后端 + 消息队列,云开发的冷启动和连接数会成为瓶颈。
三、核心数据模型
云数据库是文档型,但设计时仍要按关系型思路理清实体。我用了这几张集合:
// 菜品 categories
{ _id, name, sort, shopId }
// 菜品 dishes
{ _id, categoryId, name, price, image, specs: [
{ name: '辣度', options: ['微辣','中辣','特辣'] }
], status }
// 订单 orders
{ _id, tableNo, openid, items: [
{ dishId, name, price, count, specText }
], totalPrice, status, createTime }
// 桌台 tables
{ _id, tableNo, qrcodeUrl, status }订单里的 items 做了冗余存储,把下单时的菜名和价格快照保存下来,防止后续改价影响历史订单。
四、桌码生成与防篡改
桌码不能简单地把桌号写进二维码,否则顾客改一下参数就能点到别的桌。我的做法是:
// 云函数 generateTableCode
const crypto = require('crypto')
const sign = crypto.createHmac('sha256', SECRET)
.update(`${shopId}_${tableNo}`)
.digest('hex').slice(0, 16)
// 小程序码参数
const scene = `t=${tableNo}&s=${sign}`
// 调用 wxacode.getUnlimited 生成小程序码顾客扫码后,小程序在 onLoad 里拿到 scene,调用云函数校验签名,通过才允许点餐。这样即使有人手动改参数,签名也对不上。
五、购物车与多人同桌
多人同时点餐是个高频场景。我的方案是把购物车存在云数据库而不是本地,key 用 shopId + tableNo:
// 加入购物车
await db.collection('carts').where({ tableNo }).update({
data: {
items: _.push({ dishId, count, specText, openid })
}
})
// 前端实时监听
const watcher = db.collection('carts')
.where({ tableNo })
.watch({
onChange: snapshot => {
this.setData({ cart: snapshot.docs[0].items })
}
})这样 A 加了菜,B 的手机上购物车会实时刷新,体验比各自为战好很多。下单时把购物车整体转成订单,然后清空该桌购物车。
六、后厨出单
后厨端我用了云开发实时数据推送 + 云打印机双保险。订单创建后触发云函数,一方面写入 orders 集合,后厨小程序通过 watch 实时收到新订单并语音播报;另一方面调用打印机云 API 出纸质小票,防止网络波动漏单。
// 云函数 createOrder
exports.main = async (event) => {
const order = await db.collection('orders').add({ data: event.order })
// 触发打印
await cloud.callFunction({
name: 'printTicket',
data: { orderId: order._id }
})
return order
}七、踩过的坑
- 并发下单导致重复扣库存:用云数据库事务
runTransaction保证原子性,别用先查后改 - 小程序码 scene 长度限制 32 字符:桌号 + 签名要精简,签名截断到 8 位够用
- 实时监听连接数上限:云开发单个环境默认 1000 连接,后厨端要记得在页面卸载时
closewatcher - 支付回调幂等:微信支付回调可能重复,订单状态更新前先查一次
八、上线后的优化方向
上线只是开始。后续我陆续加了几个提升复购的功能:会员积分、菜品销量排行、桌台翻台率统计。数据看板用云开发的数据分析 + 简单的图表组件就能做,不用额外搭 BI 系统。
如果你也打算做扫码点餐小程序,建议先跑通"扫码 → 点餐 → 下单 → 出单"这条最小闭环,再逐步加功能。别一上来就做会员、营销、报表,很容易拖到项目黄掉。
评论 (0)
还没有评论,快来抢沙发吧~