专注小程序 / APP 开发,用代码改变生活

获取方案
全国分站 主站首页 北京分站 石家庄分站 唐山分站 保定分站 廊坊分站 沧州分站 郑州分站

扫码点餐小程序开发实战:从零到上线

小程序开发 2026-10-12 2 阅读 0 点赞 原创

去年帮朋友的连锁快餐店做了一套扫码点餐小程序,从需求梳理到上线只用两周,日均订单稳定在 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 连接,后厨端要记得在页面卸载时 close watcher
  • 支付回调幂等:微信支付回调可能重复,订单状态更新前先查一次

八、上线后的优化方向

上线只是开始。后续我陆续加了几个提升复购的功能:会员积分、菜品销量排行、桌台翻台率统计。数据看板用云开发的数据分析 + 简单的图表组件就能做,不用额外搭 BI 系统。

如果你也打算做扫码点餐小程序,建议先跑通"扫码 → 点餐 → 下单 → 出单"这条最小闭环,再逐步加功能。别一上来就做会员、营销、报表,很容易拖到项目黄掉。

奶茶店小程序开发实战:从点单到会员社区团购小程序开发实战指南

评论 (0)

还没有评论,快来抢沙发吧~

好想法,值得被认真交付

从小程序、APP 到全栈网站,一站式把想法变成可落地的产品

微信咨询

微信扫码,直接沟通需求