☰
微信点餐管理系统开发实战:从数据库设计到部署上线
2026/9/26 22:20:27 网站建设 项目流程

做了多年的微信小程序开发,带过的毕设项目和实战系统不在少数,但点餐系统绝对是我见过"看着简单、做起来最琐碎"的一类。你随便搜一下"微信点餐管理系统",出来的源码一堆,但真正能跑通完整交易链路、能在审核期不被打回来的其实不多。这篇我把一个相对完整的微信点餐管理系统从需求拆解、数据库设计、小程序端核心代码、商家后台、部署上线到避坑清单全部过一遍,适合正在做毕设、或者想接餐饮商家外包单的开发者在已有基础上快速落地。项目配套的完整源码和论文说明文件,我都会按模块说明结构,方便你对照自己的工程做调整。

先说清楚这个系统做了什么:用户打开微信小程序,浏览菜品分类,加购物车,提交订单,选择到店自取或堂食扫码点餐,然后支付;商家端有一个独立的管理后台(网页端),可以上架下架菜品、设置每日特价、查看订单、操作接单/出餐/完成,以及查看基础的营业统计。用户端和商家端的数据通过云端接口实时同步,后厨或者前台能看到新订单提醒。

下面直接进入正题,我把整个系统的搭建过程按模块拆开讲。

1. 需求边界设计:先搞清楚"点餐系统"到底要管哪些事

点餐系统听起来功能简单,但一旦进入真实业务场景,需求边界很容易失控。我在开始写代码前,会先把整个系统的用户角色和业务流程画清楚。这套系统的核心角色就两个:C端用户和B端商家管理员,但在开发时还要考虑一个隐藏的后台运维角色,用来处理超时订单、退款异常这类边缘情况。

1.1 用户角色与核心业务规则

C端用户侧,最核心的流程是:扫码/搜索进入小程序 -> 浏览菜品 -> 加入购物车 -> 提交订单 -> 在线支付 -> 等待商家出餐 -> 取餐/用餐。这个链路里有一个特别容易忽略的点:订单在"已支付"状态之后,不是直接跳到"已完成",而是中间要经过商家接单、制作、出餐等环节。很多简化版源码在这里直接砍掉了中间态,导致商家根本没法操作订单流转,这是判断一个点餐系统是否可用的关键分水岭。

B端商家側,业务规则更细:

  • 菜品管理:需要区分"在售"和"停售"状态,停售菜品在用户端应该直接隐藏或置灰,而不是等用户下单后再说"这个没了"。
  • 订单处理:新订单要有提醒,接单后进入制作,制作完成标记出餐,用户取餐后订单完结。
  • 营业统计:至少要有当日营业额、订单数、热销菜品排行,这些数据直接从订单表和订单明细表聚合出来。

还有一个被我反复验证过的重要规则:用户提交订单时,必须校验菜品是否还在售、价格是否发生变化,不能直接信任前端传过来的价格。原因往下看,这是我在实测中踩过的坑。

1.2 数据库设计:表结构是这样拆出来的

数据模型是整个系统最需要仔细设计的部分,后续所有接口的复杂度都由它决定。我用MySQL作为主存储,核心表一共9张:

  • 用户表(user):openid(唯一索引)、昵称、头像、手机号、注册时间
  • 菜品分类表(category):分类名称、排序权重、是否置顶
  • 菜品表(dish):所属分类、名称、描述、图片URL、价格(存分为单位)、是否停售、月销量
  • 购物车表(cart):用户ID、菜品ID、数量、加入时间(小程序端也可用本地存储,但服务端保存更稳)
  • 订单表(orders):订单号、用户ID、总金额、订单状态、支付状态、支付时间、订单类型(堂食/自取)、备注
  • 订单明细表(order_detail):订单ID、菜品ID、菜品名称快照、单价快照、数量
  • 管理员表(admin):账号、密码(加密存储)、角色
  • 营业时间表(business_hours):可灵活配置各时段的营业状态
  • 系统配置表(config):存储起送价、配送费、商家公告等

菜品价格我是强烈建议用"分"存储的,不要在数据库里用FLOAT或DECIMAL存"元"。整型运算没有精度误差,前端展示时再做一次除以100的转换。金额这种数据一旦出现0.1+0.2这类精度问题,对账的时候会让你怀疑人生。

订单状态我用整数存储,定义如下约定:0待支付、1已支付待接单、2已接单制作中、3已出餐待取餐、4已完成、5已取消、6退款中、7已退款。这个状态机在商家后台和用户端都要保持一致,所以我把它抽成了常量文件,前后端各维护一份,避免状态码对不上。

2. 小程序端登录与用户体系:最容易被忽视的隐蔽工程

登录模块是点餐系统第一个要做的功能,也是问题最多的功能。很多初学者直接把wx.login拿到的code往后台一传就以为登录完成了,其实这个过程的完整链路是:小程序端调用wx.login获取临时code,把code发给自己的后端,后端拿着code加上小程序的AppID和AppSecret去微信的接口换openid和session_key,然后用openid去查用户表。

2.1 静默登录与token续期的设计

用户打开小程序时我不希望弹出一个强制授权框,那样跳出率太高。所以用户端走的是"静默登录"逻辑:前端先调wx.login拿code,后端拿到code换openid后,如果用户表里没有记录就自动创建一条,并签发一个自定义的登录态token返回给前端。前端把token存到storage里,后续所有请求都在header里携带这个token。

这个token的有效期我设置的是7天,但有个细节:小程序可能7天内多次打开,所以我做了一个"token自动续期"策略。后端返回token时同时返回一个expires_in字段,小程序在每次请求的响应拦截器里判断如果token快过期了(剩余时间少于1天),就静默调一次刷新接口,把旧token换新的。这样用户完全无感知,也不会出现用着用着突然被踢回登录页的情况。

2.2 获取手机号与用户信息授权的边界

新版微信已经基本废弃了wx.getUserInfo直接弹窗拿昵称头像的方式,改成用户主动点击"头像昵称填写能力"或者用"手机号快速验证组件"。点餐系统里手机号很重要,因为到店自取需要联系用户。但这里有个体验和审核的平衡问题:如果一进来就强制要手机号,转化率会掉很多。

我的做法是:手机号获取放在用户第一次提交订单时,作为下单流程的一步,而不是小程序启动时。这样既不会过度打扰浏览用户,又能在真正需要联系用户的时候拿到必要信息。用微信官方提供的<button open-type="getPhoneNumber">组件,后端拿code换手机号,整个过程不经过前端明文传递,安全性有保障。

2.3 用户端接口的异常处理:不要只处理成功路径

接口设计上,除了常规的成功返回,我专门设计了一套错误码体系。比如:菜品已下架返回2001、库存不足返回2002、订单已关闭返回2003、登录态过期返回401。前端请求封装统一处理这些错误码,遇到401就静默重新登录再重放请求,遇到2001就刷新购物车并提示用户"菜品已售罄,已自动移除"。

这套体系看着不起眼,但在真实环境中特别有用。一个小程序上线后,你根本无法预判用户会在什么网络环境、什么操作顺序下触发问题。比如用户把小程序切到后台半小时再回来直接点提交订单,token可能换了,菜品可能下架了,价格可能调了,没有统一错误处理的话,用户只会看到莫名其妙的"请求失败"。

3. 点餐核心链路:菜品展示、购物车与订单落库

这是整个系统最核心的业务代码区。我会把每个环节的关键实现逻辑讲清楚,包括为什么这样设计。

3.1 菜品数据与分类的接口设计

菜品列表接口我设计成了两个:一个获取全部分类(含分类下的菜品),一个获取单个菜品详情。分类接口返回的数据结构是嵌套的,这样小程序端渲染时不需要做二次聚合处理,一次性拿到所有数据直接渲染。

这里特别注意一个性能问题:不能每次用户打开小程序都从数据库实时查全量菜品。菜品的更新频率其实很低,半小时、一小时变一次就算频繁了。我在后端给这个接口加了Redis缓存,缓存key按"菜品分类_店铺ID"区分,商家后台修改菜品后主动删除对应缓存,下次请求自动回源刷新。实测在低配云服务器上,接口响应从平均300ms降到了50ms以内。

菜品的图片存储我用的云存储,返回给前端的是CDN加速过的URL。图片有一个规范:必须等比压缩,因为小程序端列表图和详情图尺寸要求不一样,不能一张原图走天下。我在商家后台上传菜品图片时,后端会自动生成多个尺寸的缩略图,列表用200x200,详情用640x640,这样能显著减少流量消耗和首屏加载时间。

3.2 购物车的本地状态管理:避免服务端频繁读写

购物车这块,初学者最容易犯的错是把每个加购动作都实时同步到服务端。点餐场景下用户操作购物车是非常高频的,而且网络并不总是稳定,每次操作都请求后端会让体验变得非常糟糕。

我的方案是小程序端本地维护购物车,使用全局状态管理(小程序里可以用globalData或者引入轻量的状态库),数据结构设计成:

{ "items": [ { "dishId": 12, "name": "招牌牛肉面", "price": 2800, "qty": 2, "specs": "微辣" }, { "dishId": 18, "name": "冰酸梅汤", "price": 600, "qty": 1, "specs": "" } ], "totalQty": 3, "totalAmount": 6200 }

这个本地购物车会在用户每次加购时更新,同时同步到storage做持久化。真正和服务端交互的节点在"提交订单"那一刻,一次性把购物车数据发送给后端。这样设计还有一个好处:就算用户中途退出小程序,下次进来购物车还在。

购物车本地化有一个必须处理的细节:用户打开小程序时,要从服务端拉取一遍购物车里所有菜品的实时价格和售罄状态,和本地缓存做比对。菜品价格变了以服务端为准并提示用户,菜品停售了直接移除并提示。这个校验我放在"进入购物车页面"的时机执行,保证下单前用户看到的一定是准确信息。下单接口再做一次兜底校验,双重保险。

3.3 下单接口的服务端校验与幂等处理

服务端的下单接口是整个系统最需要谨慎的接口,因为它直接涉及钱。前端提交的请求里只传这些字段:订单类型、备注、购物车明细列表(菜品ID和数量)。后端要做的事情如下:

第一步,根据用户token解析出用户ID,然后查询用户信息是否存在,不存在直接拒绝。 第二步,将购物车明细里的菜品ID批量查库,拿出每个菜品的当前价格、在售状态,和前端传的数量重新计算总金额。这里绝对不信任前端传过来的totalAmount,而是以后端计算的为准。前端显示的总金额只是参考展示。 第三步,用数据库事务把订单主表记录和订单明细表记录写入,同时扣减菜品销量字段,清空用户服务端的购物车记录。这期间如果任何一步失败,整个事务回滚。 第四步,生成业务订单号并返回给前端,前端拿到订单号后调用微信支付接口。

下单接口还有一个隐藏需求:幂等处理。用户可能在网络波动时多次点击提交按钮,如果每次都生成新订单就会出问题。我的方案是给下单请求加一个前端生成的"请求唯一标识",后端以这个标识做去重判断。同一标识的重复请求直接返回第一次的订单结果,不会重复建立订单。实测这个设计在真实场景下几乎必然会被触发,非常重要。

3.4 支付流程:微信支付接入的几个关键细节

微信支付接入是点餐系统最"劝退"初学者的环节。我快速过一遍完整流程和需要注意的配置点:

  • 第一步,申请微信支付商户号。注意主体要和小程序的主体一致,不然很多支付功能没法开。
  • 第二步,在小程序后台开通微信支付,并配置支付目录、回调域名。
  • 第三步,后端引入微信支付v3的SDK(我用的是官方sdk,不要自己造轮子去拼签名),配置商户号、API证书、APIv3密钥。
  • 第四步,后端统一下单接口返回给前端5个核心参数:时间戳、随机字符串、订单详情扩展字符串、签名方式、签名。前端用wx.requestPayment发起支付。

支付回调是这里最容易出问题的环节。微信服务器会异步通知你的回调地址,通知里带签名和订单状态。你要做的是:验签 -> 判断订单状态是SUCCESS -> 更新本地订单状态为已支付 -> 返回"处理成功"给微信服务器。这里有一个坑:微信会重试通知,如果业务处理成功但你没有正确返回,微信会一直重复通知,造成订单状态被重复更新的问题。所以支付成功的回调处理必须做幂等:先查订单当前状态,如果已经是已支付就不要再重复更新了,直接返回成功。

关于支付证书,很多源码包里的证书是明文的,安全性堪忧。你在真实部署时一定不要把商户号和证书机密提交到代码仓库里,要用环境变量或者单独的配置文件管理,并且配置文件要加进.gitignore。

4. 看板式的实时订单提醒:别用轮询,用WebSocket长连接

这是用户堂食场景的刚需,也是我在毕设评估里最看重的功能点之一。用户下单后,商家端需要几乎实时地看到新订单并处理;用户端在等待出餐时,也需要看到订单状态的实时变化,不能老盯着屏幕手动刷新。

4.1 为什么最终选了WebSocket而不是定时轮询

不少简化版源码用的是前端定时器,每5秒拉一次订单状态接口。在小并发场景下这样确实能用,但有两个硬伤:第一,订单状态更新不是瞬时的,最坏情况下用户要等5秒才能看到新状态;第二,用户量稍微上来一点,服务端的查询压力会被无意义的轮询请求放大很多倍。

这个系统里我用了WebSocket长连接,小程序端通过WebSocket连接服务器,服务端在订单状态变化时主动推送消息给对应连接。用户端和商家端都依赖于这个通道。我用的方案是服务端在订单状态变更的代码逻辑处,主动向对应角色的WebSocket连接推送一条消息,消息内容是订单ID和新的状态码。前端收到后,如果当前正停留在订单详情页,就自动刷新页面数据;如果在首页,就弹出一个轻量提示"您的订单已出餐"。

接入过程有几个实际经验分享。

小程序端,原生代码直接这样写:

wx.connectSocket({ url: 'wss://api.yourshop.com/ws', header: { 'Authorization': token } }) wx.onSocketMessage(function (res) { const data = JSON.parse(res.data) // data.type === 'ORDER_STATUS_CHANGED' // data.orderId, data.status handleOrderStatus(data) }) wx.onSocketClose(function () { // 心跳断了,做重连,最多重试5次 retryConnect() })

后端我用的是Netty实现WebSocket服务(如果你用Java系后端的话),每台机器维护一份userId到Channel的映射,用ConcurrentHashMap存储。如果是单体应用这样完全够用;如果你的装机量比较大,需要用Redis的Pub/Sub做跨节点广播,不然A机器收到订单变更,B机器上的用户连接收不到消息。小程序端的WebSocket有些老坑,比如切后台后连接会被系统断掉,需要在前端实现重连机制和心跳保活。我一般用每30秒发一个ping包,服务器端60秒内没收到ping就主动断开连接,前端检测到断线后自动重连。

4.2 商家端"实时订单墙"的实现

商家端我用的是一个独立的Web管理后台界面,其中最重要的页面是"订单看板",它的核心是一个实时更新的订单列表。

每个订单卡片展示:订单号、用户取餐号、菜品清单、备注、金额、倒计时(从接单开始计时,超过15分钟变红提醒)、操作按钮。新订单到达时,WebSocket推送消息触发列表头部插入一张新卡片,并播放提示音。商家点击"接单",状态变成"制作中";点击"出餐",状态变成"已出餐待取餐";用户取餐后,用户端点击"确认取餐",订单状态变成"已完成"。每一步操作都同步推送状态给用户端。

取餐号的设计可以在这里说一下:它是店内自取的标识,我用的是一个3位数字编号,每天从1开始递增。这样商家和用户喊号方便,不会暴露用户真实订单号。生成逻辑是在下单接口里取当天最大取餐号+1,用Redis的INCR命令实现原子递增,一天一重置。

5. 数据统计模块:让商家看到营业情况的真实全貌

很多点餐系统做完了点餐、支付、订单管理就结束了,但商家真正长期使用的是数据统计功能。一个餐饮老板每天最关心的几个数据:今天卖了多少单、营业额多少、哪个菜品卖得最多、哪个时段是高峰期。这部分我用SQL聚合实现,不引入额外的大数据组件,性价比很高。

5.1 营业日报的SQL实现思路

当日总营业额和总订单数:

SELECT COUNT(*) AS order_count, SUM(total_amount) AS total_revenue FROM orders WHERE pay_status = 1 AND pay_time >= CURDATE() AND pay_time < CURDATE() + INTERVAL 1 DAY;

热销菜品排行(按销量倒序):

SELECT d.id, d.name, SUM(od.qty) AS sale_quantity FROM order_detail od LEFT JOIN dish d ON od.dish_id = d.id LEFT JOIN orders o ON od.order_id = o.id WHERE o.pay_time >= CURDATE() AND o.pay_time < CURDATE() + INTERVAL 1 DAY AND o.pay_status = 1 GROUP BY d.id, d.name ORDER BY sale_quantity DESC LIMIT 10;

小时维度订单分布,用于判断忙闲时段:

SELECT HOUR(pay_time) AS hour, COUNT(*) AS order_count FROM orders WHERE pay_time >= CURDATE() AND pay_time < CURDATE() + INTERVAL 1 DAY AND pay_status = 1 GROUP BY HOUR(pay_time) ORDER BY hour;

这三个SQL基本覆盖了我的统计需求。如果你需要更细的维度,可以额外维护一张日汇总表,每天凌晨用定时任务把前一天的数据聚合写入,报表查询时直接读汇总表而不是实时跑原始订单表。数据量上来之后这个优化会非常重要。

5.2 经营看板的可视化呈现

后端提供统计接口后,商家后台前端用轻量图表库渲染趋势折线图、菜品排行条形图、时段分布柱状图。我做的是一个可切换时间的维度:今日、近7日、近30日,对应的SQL只是把时间范围参数改一下,聚合逻辑完全复用。数据刷新策略是:打开页面时拉取一次,之后每5分钟自动拉取一次。实时性要求不高的场景完全够用,也没必要为这个专门接WebSocket。

6. 部署上线与微信生态配置:审核期反复踩坑的避坑全集

功能全部写完、本地自测通过,并不代表可以上线。微信小程序的审核、域名配置、HTTPS证书、类目选择,每一步都有坑。我把自己踩过的和帮别人解决过的高频问题集中列一下。

6.1 前后端联调与真机预览的必备设置

开发阶段用微信开发者工具中的"不校验合法域名"选项很爽,但上线前一定要做三件事:

第一,小程序后台配置request合法域名、socket合法域名、uploadFile合法域名。这里要注意:域名必须是HTTPS,且不能带端口(默认443),而且ICP备案一定要完成。我见过很多项目卡在域名备案上,一等就是好几天。

第二,本地开发环境联调时,我发现一个效率提升的技巧:用微信开发者工具自带的"自定义条件编译"功能,根据编译模式动态切换API的baseURL。开发环境指向本地局域网IP加后端端口,生产环境指向正式域名。在代码里做一个环境判断,不要每次发版前手动改一堆请求地址。

第三,尽可能用真机预览。开发者工具的模拟器里很多能力跟真机有差异,特别是网络请求的TLS版本兼容性、微信支付的拉起表现、WebSocket在弱网环境的断线重连。这些只有真机测过才敢放心提审。

6.2 审核被拒的常见原因与解决办法

餐饮点餐小程序在提审时最常遇到的是类目审核问题。如果小程序涉及"餐饮服务"或"点餐平台",可能需要对应的资质文件。一个规避思路:如果你的系统是给单一商家使用的,可以走"餐饮商家自营"类目,需要的资质比平台型要少;如果你做的是多商家入驻的聚合点餐平台,类目要求会严格很多,通常需要食品经营许可证等资质。这一点在项目规划和论文说明里都要写清楚,别等到提审被拒了再调整方向。

另一个高频被拒原因是"用户隐私保护指引"没有配置完整。小程序的隐私协议里必须明确声明收集了哪些用户信息(微信昵称、头像、手机号、位置信息),以及用途。我在前端弹窗收集用户信息前,先调了wx.getPrivacySetting接口判断用户是否同意过隐私协议,不同意则用官方提供的隐私弹窗组件引导用户同意。

关于虚拟支付千万别碰,餐饮实体商品走微信支付商户通道没有问题,但如果你在系统里加了"会员卡充值""虚拟优惠券购买"这类项目,就涉及虚拟支付,小程序平台对这类管控极严,动不动就封禁支付能力。我这个系统里只做线下商品的在线支付,不做虚拟商品交易。

6.3 服务器部署与上线后的日常运维

部署这块我建议用轻量云服务器加Docker Compose编排,把后端服务、MySQL、Redis、WebSocket服务分别做成容器,然后用Nginx做反向代理和HTTPS终结。Nginx配置文件里记得把WebSocket的Upgrade头配置好,不然长连接会被Nginx截断:

server { listen 443 ssl; server_name api.yourshop.com; ssl_certificate /your/path/fullchain.pem; ssl_certificate_key /your/path/privkey.pem; location /api/ { proxy_pass http://backend-server:8080; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } location /ws/ { proxy_pass http://backend-server:9090; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header Host $host; } }

数据库备份我直接用mysqldump加crontab,每天凌晨两点执行一次全量备份,保留最近7天。上线一个月后你的数据会变成最宝贵的资产,订单记录、用户信息、营业数据,一旦丢失就是事故级别的损失。系统上线后还有一个不能漏的动作:申请"小程序订单管理"相关的消息订阅模板。比如用户下单成功后,给用户推送一条"商家已接单"的模板消息,这种通知能明显提升用户体验。订阅消息的申请要在小程序后台的"订阅消息"里选模板,审核也需要一点时间,所以尽量提前申请。

7. 压测与稳定性:一个容易被毕设忽视、但真实项目必须面对的问题

如果你只是交个毕设,可能压测不是必须的,但如果你想把这个项目作为求职项目经历放进简历,或者你真的打算给商家部署使用,稳定性是你必须面对的。

我在这套系统上做过一轮并发压测,工具用的JMeter,场景是模拟50个用户同时提交订单。第一次压测结果问题很明显:下单接口在数据库层面有大量的行锁竞争,订单表插入和明细表插入是两笔操作,虽然放在了一个事务里,但在高并发下还是会因为锁等待出现超时。

优化措施如下:

  • 订单号生成从数据库自增ID改成了"时间戳+商户ID+随机数"的后端生成策略;另外写了一个专门的号段生成器,用Redis的INCR提前取号段,降低对订单表的插入争用。
  • 菜品销量字段的扣减改成先查Redis缓存,再异步批量回写数据库。这样用户端看到的是实时销量,数据库的写入压力则小很多。
  • 数据库连接池参数根据压测结果做了调整:初始连接数调到5,最大连接数调到50,连接等待超时时间设置为500ms。
  • 下单接口的幂等Redis key设置了2小时的过期时间,防止Redis内存无限增长。

优化后重新压测,50并发下单接口的平均响应时间稳定在200ms以内,无超时,无数据错乱。如果你用云数据库,记得在压测前把实例规格临时调大一点,压完再调回来,这样能省不少钱。我自己是直接在本地服务器压的,配置就是2核4G,压测结果作为论文里性能测试章节的数据支撑完全够用。

关于稳定性,还要注意小程序端的请求超时时间设置。默认的wx.request超时时间是60秒,对于点餐场景来说太长了。如果用户网络不好,用户会一直卡在"提交中"的加载状态。我把超时时间统一设成10秒,并且加了失败重试机制:请求超时后自动重试一次,如果还是失败就明确提示用户网络异常,让用户检查网络后再试。同时在下单按钮上做了防重复提交的loading状态控制,点击后立刻禁用按钮,避免用户因为焦躁连点导致多个订单。

8. 踩坑实录:几个看似不起眼但足以让你熬夜的细节问题

这些是我在实际开发和上线过程中真实遇到过的问题,每一个都花了不少时间排查。写出来给你省点力气。

坑一:时间字段的类型选择

小程序端和后端联调时,时间字段如果返回的是"2025-01-12T10:30:00.000Z"这种ISO格式,前端 new Date() 解析是没问题的,但如果你直接在页面里做字符串截取展示,容易出现8小时时差。因为ISO格式默认是UTC时间,中国时区要加8小时。我最后统一的做法是:后端接口返回的所有时间字段都转成时间戳字符串(毫秒级),前端统一用自己封装的时间格式化函数处理。这样彻底避开时区解析混乱的问题。

坑二:微信支付金额的单位

微信支付金额的单位是分,这是文档明确写的,但真的很容易忽略。如果你传了"28.00"而不是"2800",微信支付接口会直接报错"金额不合法"。我在下单接口的后端代码里写了一个统一转换函数,接收前端传入的元金额字符串,内部转成整数分,所有跟金额相关的计算都用分,只有返回前端展示时才转回元。这个约定同时写进了项目文档,前端对接的时候也会少踩这个坑。

坑三:小程序冷启动时的登录竞态

小程序冷启动时,首页多个组件会同时开始请求数据,但这些请求依赖登录态token。如果token还没拿到就发请求,后端会返回401,然后各个请求各自触发重新登录,造成请求风暴。我的解法是:前端封装的request方法里做一个"登录中间态"处理。第一个请求发现没有token时,先发起登录流程,其他请求进入等待队列;登录完成后,把队列里的请求全部带token重放。这样整个启动过程只会触发一次登录,后续请求全部复用同一个token。

坑四:菜品图片的OSS防盗链

如果你用了云存储的图片,C端小程序请求图片时如果带了Referer头(比如从某个网页跳转过来),而云存储设置了防盗链规则,图片会加载失败。微信小程序的web-view里打开页面时Referer是小程序域名,一般没问题;但如果有人在浏览器里直接访问你的小程序H5版页面,图片就可能全部裂开。我的做法是云存储统一开启白名单Referer,把小程序域名、商家后台域名加进白名单,同时配置图片URL签名有效期,防止被人盗刷流量。

9. 项目源码结构与论文说明:你拿到手的到底有什么

最后说下整套项目源码的目录结构,方便你拿到之后快速定位代码。

wx-restaurant/ ├── miniprogram/ # 小程序前端项目 │ ├── pages/ │ │ ├── index/ # 首页:分类+菜品列表 │ │ ├── cart/ # 购物车页 │ │ ├── order/ # 订单列表、订单详情 │ │ ├── profile/ # 个人中心 │ │ └── checkout/ # 确认下单页 │ ├── utils/ # request封装、工具函数 │ └── app.js # 全局逻辑、登录状态管理 ├── admin-web/ # 商家后台(网页端) │ ├── pages/dashboard # 营业看板 │ ├── pages/dish # 菜品管理 │ ├── pages/order # 订单处理 │ └── pages/settings # 商家设置 ├── server/ # 后端服务(Java Spring Boot) │ ├── controller/ # 接口层 │ ├── service/ # 业务逻辑层 │ ├── mapper/ # 数据访问层 │ ├── config/ # 微信配置、Redis配置 │ └── websocket/ # 实时推送服务 ├── sql/ # 数据库初始化脚本 └── docs/ # 论文说明文档、接口文档、部署文档

论文说明部分,我建议至少包含这几章:选题背景与意义、需求分析(用例图、功能需求、非功能需求)、系统设计(架构图、数据库ER图、接口设计)、系统实现(核心代码与逻辑说明)、系统测试(功能测试用例、性能测试结果)、总结与展望。我这里准备的文档里提供了一套完整的论文框架和每个章节的写作素材,你可以按自己学校要求调整格式。论文里的架构图我建议自己用Visio或者draw.io画一遍,不要直接贴别人的,因为导师可能会问细节。

源码的使用方式很简单:先按sql目录里的脚本建库,再改后端配置文件里的数据库连接、微信小程序AppID与Secret、商户号与证书路径,然后分别启动后端服务和前端项目,用微信开发者工具导入miniprogram目录即可看到效果。商家后台是独立的Web项目,npm install之后npm run dev就能跑起来。

个人在折腾这套系统的过程中最大的体会是:点餐系统不算难,但它是"麻雀虽小,五脏俱全"的典型。你在这里面做的每一个决策——从状态机的设计、金额精度的处理、接口是否幂等、实时通知选什么方案——都在悄悄决定这个系统是不是真的能拿去给人用。很多毕设项目能演示但不敢上线,往往就是缺在这些细节上。如果你按这篇的思路把每个模块都做扎实,这套系统不管是用来毕业还是用来接单,都拿得出手。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询