结论先行
餐饮自助点单场景里,最常见的错误方案就是:顾客前端下单后每 3 秒轮询一次,看看后厨收到了没。企业版给出的不是轮询,而是一条前端事件链:订单先过 self-order 控制器,是否立即推送后厨取决于支付状态与门店配置,后厨屏再通过服务层订阅通知更新界面。
第一层:入口或表面动作
pos_self_order_preparation_display.controllers.orders.process_order() 在调用父类处理订单后,不是简单返回 JSON,而是立刻 _send_to_preparation_display()。但这个发送动作内部又有护栏:只有当配置没有强制有效自助支付方式,或订单状态已经是 paid,才会 pos.prep.order.process_order(pos_order.id)。这说明前端下单并不等于后厨立刻开做,支付条件才是能否放行的边界。
第二层:真正的业务护栏
如果是线上支付场景,pos_online_payment_self_order_preparation_display.payment_transaction._process_pos_online_payment() 会在交易确认后再次调用 pos.prep.order.process_order()。于是你会看到两段接力:一段来自下单控制器,一段来自支付回调模型。两者合起来解决的是“未支付订单能否上后厨屏”的问题,而不是让浏览器自己盯状态。
第三层:状态落点与边界
前端展示这边,preparation_display_service.js 对 PrepDisplay 打补丁,在 setup() 后监听 PAPER_STATUS 等通知,拿到新消息就更新 pos.config.has_paper。虽然这个补丁展示的是纸张状态,但它说明 preparation display 的思路是基于通知总线维护 UI 状态,而不是页面定时重拉整个订单列表。后厨屏前端相信的是事件流,不是刷新频率。
为什么这套设计更稳
这条链特别适合拿来讲前端跨模块协同:控制器负责把用户动作落成订单,支付模型负责把交易事实补上,preparation display 服务负责消费通知更新可视界面。你如果只在自助点单页面里加轮询,不仅会平白制造请求压力,还会把“支付确认前不能出餐”的业务规则埋进浏览器定时器里。
实战启示
所以真正该调试的不是“为什么厨房没刷新”,而是这三层有没有接上:process_order 是否把订单创建出来、payment transaction 是否完成并触发 prep 处理、display service 是否订阅到通知。把问题拆成这条事件链,前端就不再只是页面,而是 POS 业务中继。
DISCUSSION
评论区