做无人自助台球这套系统,很多人第一反应是"做个扫码开台的小程序不就行了"。真下场做过一轮之后才发现,台球这个场景比想象中要复杂得多:灯光要随开台自动通电,开锁要防掉线,计费要防争议,老板要看实时的经营数据,还得让用户从"约球——到店——开台——计时——结账——离店"这条链路全程无感。我这次上线的"科技领航,共享无人自助台球软件",本质上就是把一整套IoT硬件、计费引擎、用户端小程序和商家管理后台串起来,做成一个真正能落地运营的SaaS产品。这篇文章我会把从方案选型到核心功能实现、再到部署和排障的完整过程摊开来讲,适合正在做同类无人自助项目、或者准备把传统球房改造成24小时自助模式的朋友参考。
1. 项目定位与整体方案拆解
1.1 目标场景与商业闭环
做无人自助台球不是单纯省一个人工那么简单。传统球房最大的成本除了房租就是夜班值守,而台球消费的高峰恰恰集中在晚上六点到凌晨两点。如果能把这段时段的看店人力去掉,球房就具备了24小时营业的可能,坪效和使用率都会明显提升。
我这次软件的服务对象是两类人:一类是球房老板,他们要的是省人、增收、管账清晰;另一类是打球用户,他们要的是到店即打、无人打扰、计费透明。这个软件要解决的,就是让这两类人通过一套系统完成交易闭环。整个商业闭环是:用户线上约台和支付押金,到店扫码开门,控制器通电亮灯,计时开始,离店自动结算,平台与商家按比例分账。
1.2 技术选型的关键权衡
无人自助台球场景的设备端核心是一个嵌入式控制器加门锁,控制器需要联网、接收云端指令、驱动继电器通断,还要上报设备状态。当时我考虑过几套方案:
- 方案A:纯蓝牙Mesh方案,用户到店通过小程序蓝牙连接设备开锁。好处是省流量、不需要球房有外网,坏处是远距离管理和后续升级功能受限,老板看不到实时在线状态。
- 方案B:纯MQTT上云方案,所有控制器通过Wi-Fi接入公网,云端统一下发指令。好处是无论人在哪里都能管控,坏处是对球房网络稳定性要求高,断电断网的极端情况需要做好本地兜底。
- 方案C:本地网关加云端的混合架构。控制器走局域网网关,网关负责本地策略缓存,同时对接云端服务。造价稍高,但可靠性最强。
最后我选了方案B为主、配合本地策略兜底的做法。原因很直接:自助台球的核心价值就是远程化、无人化,IoT设备的在线率和可控性必须优先保证。Wi-Fi智能插座级别的硬件成本能控制在较低范围,大多数球房本身也有宽带和路由,部署难度低。对于断电、断网这种极端情况,我在控制器固件里做了开锁状态保持和离线缓存,这个后面在设备容错部分细讲。
1.3 与纯扫码计时方案的差异点
市面上一部分所谓"自助台球"其实是半自助:一套扫码计时系统加一个机械锁,用户扫码后手动开灯,离店后手动关灯。这套东西便宜,但体验割裂,灯光忘关、计费超时都是常见投诉。
我这次做的"共享无人自助"强调的不是"扫码付款开台"这一个点,而是"全链路无人干预"。从门锁、灯光、计费、异常报警到离店断电,全自动完成。灯光和门锁必须和订单状态强绑定:订单开始,继电器吸合,灯光通电;订单结束,继电器断开,灯光熄灭。这套逻辑看着简单,实际涉及订单状态机、设备状态同步、掉线重连、防误判等多层问题,也是后面要花最多篇幅来讲的部分。
2. 核心功能模块与关键技术实现
2.1 硬件控制层:IoT终端与开锁/通电逻辑
硬件控制层是整套系统的"手和脚"。我使用的IoT终端核心是一块ESP32模组加两路继电器:一路控制门锁电磁铁,一路控制台球桌上方灯组的电源。模组通过Wi-Fi连接云端MQTT服务器,同时保留了本地HTTP接口用于调试。
开锁通电的核心流程是:
- 用户在小程序下单并支付押金后,云端订单状态变为"待开台"。
- 小程序端调用开台接口,云端下发"开锁+通电"指令到MQTT主题。
- 控制器收到指令后先驱动门锁继电器吸合1.5秒,让电磁锁弹开,再吸合灯光继电器,并返回状态上报"已开台"。
- 云端收到状态上报后,将订单状态更新为"进行中",并开始计费计时。
这里有个特别容易踩坑的地方:电磁锁的电流冲击和继电器的寿命问题。如果频繁通断,继电器容易粘连,导致锁体一直保持在开启状态。我在固件里做了保护逻辑,每次开锁后强制延时5秒才能再次触发,同时每个订单最多允许三次开锁操作,超过次数会自动触发异常工单上报。
2.2 计费引擎与金额精度处理
台球计费并不是简单的"每分钟多少钱"。实际场景中,大多数球房区分工作日、节假日、峰时、谷时,还有会员价和非会员价,部分球房还叠加"第一小时xx元、续费每小时xx元"的阶梯价。用传统定时任务去逐个订单算费,数据量大且容易出错,所以我做了一个独立计费引擎。
计费引擎的核心是一个按分钟推进的定时任务,它只负责计算"当前时间点这个订单应该扣多少钱",然后把金额追加到订单累计费额中。计费规则全部配置化,运营人员在管理后台可实时调整价格策略,无需发版。
金额处理上必须讲一个细节:所有金额字段在数据库中一律使用整数分存储,禁止使用浮点数。微信支付和支付宝支付的单位都是分,计费引擎在计算时也用整型毫分或分,避免浮点误差导致的"多扣一分钱"的客诉。比如某球房工作日第一小时价格为28元,续费价格为15元每小时:
- 前60分钟:每分钟扣除0.4667元,累计显示四舍五入到分。
- 第61分钟起:每分钟扣除0.25元。
我在实现时不是用"每分钟扣一次"的物理时间片,而是用"按秒统计、按分累计"的方式:每分钟结束时,计费引擎读取该分钟内的实际时长,乘以单价后累计到费额字段。这样即使出现网络延迟或服务重启,补算逻辑也能保持精准,不会因丢秒造成少扣费,也不会出现用户申诉"多打了几分钟多扣了钱"的问题。
还有一个坑:掉线期间的计费。用户在开台状态下如果网络中断,控制器会保持灯光和锁体状态不变,但云端无法计时。我的处理方式是:控制器本地记录开台时的时间戳,恢复网络后立即上报"离线期间的时间段",云端补算该段计费。这个补算逻辑要求控制器的本地时钟尽量准确,所以固件里每次连接MQTT时都会同步一次NTP时间。
2.3 用户端小程序与会员体系
用户端我选择了微信小程序,核心原因是微信生态在台球人群中的渗透率极高,小程序无需下载安装,用户从扫码到开台可以控制在15秒以内。
小程序主要包含以下页面和功能:
- 首页:附近球房列表、距离排序、营业状态、在线空闲球台数。
- 球房详情:台型列表(中式八球、斯诺克、九球等)、不同时段价格、环境照片、用户评价。
- 选台开台:选择空闲球台,确认计费规则,支付押金或购买次卡后开台。
- 订单中心:进行中订单展示剩余时间、累计费用;历史订单展示消费明细和发票入口。
- 会员中心:余额充值、优惠券、会员等级、邀请有礼。
这里的会员体系不是简单做个"充值送金额",而是和运营策略深度绑定。比如新用户开台享首单减免,次卡用户优先预定热门台位,会员等级决定折扣和信用免押额度。信用免押这块我接入了微信支付的支付分能力,信用分达标的用户可以直接开台,不需要预先支付押金,离店后自动从余额或绑定扣款渠道扣除费用。这个功能对用户体验的提升非常明显,实测数据显示信用免押的开台转化率比押金模式高出三成以上。
小程序端还需要特别注意GPS定位权限和球房位置的反向校验。用户开台后,如果跑到距离球房1公里外,系统不会立即取消订单,但会推送提醒,防止有人"远程下单,实际占台不用"。
2.4 管理后台与经营数据看板
管理后台是老板们每天都要看的页面,功能上我把它拆成四大块:设备管理、订单管理、营销工具和数据看板。
设备管理这块,老板可以在后台看到每台球桌的在线状态:在线、离线、使用中、空闲、故障锁定。出现离线或故障时,后台会高亮告警,同时推送微信模板消息到老板手机。我做过一轮优化:故障告警不是只看"是否在线",而是结合心跳间隔、继电器状态、订单占用状态综合判断。比如一台球桌处于在线状态,但连续30秒没有心跳,系统先预警"弱网",若超过3分钟没有心跳,则判定离线,并自动冻结该球桌的下单入口,防止用户下单后无法开台。
订单管理这块,除了常规的订单查询和退款操作,我加了"异常订单处理队列"。所有设备无响应、开台超时、结算失败、金额不一致的订单都会自动进入这个队列,按紧急程度排序。老板只需要按顺序处理,不需要翻遍所有订单找问题。
数据看板是我比较自豪的部分。除了营收、单量、客流趋势这些基础数据,我额外做了"台时利用率"和"时段热力分析"两块。台时利用率指的是每个球台的每小时实际被占用时长与全天可运营时长的比值,这个指标能直接反映球房的最大营收上限在哪里。时段热力分析则能看出某个球台在工作日晚上八点到十点被高频预定,那么运营人员可以在这个时段动态上调价格,实现收益最大化。
3. 软件架构设计与部署实操
3.1 架构分层与各层职责
软件架构图在我看来是开发者沟通的第一工具。整个系统我分了四层:设备接入层、业务服务层、数据存储层和前端应用层。
设备接入层跑的是MQTT Broker服务,使用EMQX开源版作为承载。EMQX对海量设备连接的支持很成熟,也支持设备上下线事件的Webhook推送,方便业务侧实时感知设备状态。设备端通过TLS加密连接,MQTT主题按"球房ID/球桌ID/action"的规则设计,避免串台。
业务服务层用Java SpringBoot搭建了五个核心微服务:用户服务、订单服务、设备服务、计费服务、营销服务。微服务之间通过API网关统一路由,服务内部通过消息队列解耦。比如用户下单后,订单服务发出一条"订单已创建"的消息,设备服务接收后下发开台指令,计费服务接收后启动一个计费任务。这套异步设计保证了即使某一服务短暂抖动,也不会影响其他模块运转。
数据存储层使用了MySQL加Redis的组合。MySQL存储订单流水、用户账号、球房信息等核心数据,Redis负责热点数据缓存:球桌在线状态、实时计费中间值、用户登录态。另外还有一套ELK日志系统,所有服务日志和设备心跳日志都汇聚进去,排障时直接按设备ID或订单号搜索日志,效率很高。
前端应用层除了用户小程序,还有Web版管理后台和商家App。Web后台使用Vue3加Element Plus开发,商家App则基于uni-app打包,既支持iOS也支持Android。
3.2 设备端断网容错与本地缓存
无人自助场景最怕的就是断网。用户正打着球,网络断了,如果不能继续开灯计时,那是灾难性的体验。所以设备端的断网容错我做得很重。
控制器固件里写了本地状态机,离线前会记录当前订单号和开台时间。断网后,设备继续维持灯光通电和门锁开启状态,同时本地还在记录时间轴。恢复网络后,控制器先重新连接MQTT,再主动上报离线时间段内的状态变化和累计时长,云端收到后补算计费。
这里要特别强调离线期间的"闸门逻辑":如果用户在离线期间直接关灯走人,没有在线上点击结账,云端是不知道的。处理方式是设备在离线状态下依然监听人体传感器或门磁信号,检测到用户离开后自动断开灯光并记录关灯时间,恢复联网后一并上报。这样即使订单没有正常结束,系统也能判定为"设备侧已关灯,订单可强制完结",避免用户钻空子长期占用球台。
3.3 部署形态与运维要点
我先说一个明确的观点:如果你的球房数量少于10家,完全不需要一上来就上Kubernetes,一台4核8G的云服务器加一台高性能MySQL实例完全够用。我做第一版部署时使用了单机Docker Compose编排,三个核心容器:EMQX、后端服务、MySQL Redis,再加一台Nginx做反向代理,整体成本很低,一个月云资源费用不到300元。
当球房数量超过20家、设备超过200台后,才需要考虑服务横向扩容和消息队列分区。我的建议是先把EMQX单独拆出去跑一台机器,然后后端服务无状态化,前面加负载均衡,数据库上只读副本,这样能扛住一万台设备同时在线。
运维上必须配置好三套告警:设备离线告警、订单异常告警、计费服务Echo异常告警。这三套告警通过企业微信群机器人推送,值班人员看到后可以在手机上直接处理。我实际运营前三个月,告警推送量很大,大部分是弱网抖动,后来在固件里增加了心跳重连退避策略,告警噪音减少了七成。
4. 常见问题与排障实录
4.1 开锁失败与卡单排查
开锁失败是上线初期最大的客诉来源,主要集中在三块:继电器烧毁、Wi-Fi信号弱、云端状态与本地状态不一致。
继电器烧毁多数是因为用了劣质模块,电流余量不足。建议采购时必须选5V/10A以上的工业级继电器模组,并且加装续流二极管保护。Wi-Fi信号弱这个问题更隐蔽,很多球房的无线路由在包间死角位置覆盖很差。我的建议是球房部署时做一次Wi-Fi信号勘测,每个球桌位置用手机测一下信号强度,信号低于-70dBm的球桌必须加装AP面板或Mesh子路由,不要抱侥幸心理。
云端状态与本地状态不一致的问题,我专门加了一个"状态对账"定时任务。每30分钟对全量订单和设备的本地状态做一次比对,发现不一致时自动触发一次同步修正。比如用户在开台状态下被老板手动重启了控制器,控制器本地的状态是"空闲",但云端还挂着"进行中"订单,对账任务会优先按"设备实际状态"为准修正订单,同时推送告警提醒老板处理。
4.2 计费争议与数据一致性
计费争议几乎无法完全避免,但一定要把"谁能查到原始证据"这个问题解决好。我在数据层保留了每一次计费动作的原始记录,包括时间戳、设备心跳时间、实际扣费金额、计算规则版本。用户申诉时,运营人员可以直接拉出完整的时间线:几点开台、几点续费、几点结算,每一分钟的费用是怎么算出来的,全部可追溯。
实际遇到过一种情况很典型:用户开台后手机没有锁屏,离开球房时忘记结算,车辆开出停车场后才想起订单还在计时,最终账单金额远超预期。这种单子从规则上讲没错,但用户感知很差。后来我在运营策略上做了优化:当订单时长超过3小时且用户仍在线,小程序端会推送"请确认是否仍在球场"的弹窗提醒,如果用户5分钟内不做操作,则自动推送一条续费待确认订单。这个机制显著降低了长尾争议订单的数量。
4.3 软件著作权与合规上线
很多做SaaS的团队容易忽略,软件著作权证书不只是申请高新技术企业的加分项,更是上架各应用市场、对接支付渠道、参与招投标的硬门槛。我这次项目上线前就把软件著作权申请材料准备好了,包括源程序前30页和后30页、软件说明书和申请表。需要注意提交的源程序每页必须50行以上,页眉标明软件名称和版本号,说明书里要有软件架构图、核心功能说明和操作流程说明。
支付渠道合规方面,小程序内有"充值"和"购买商品"两个动作,必须申请微信支付商户号,并完成小程序支付功能的类目审核。台球行业属于休闲娱乐类目,一般不会遇到特别严苛的资质卡点,但营业执照经营范围一定要包含"体育场馆服务"或"健身休闲活动",否则个别地区会驳回支付申请。这一点在项目启动前就要和财务确认好,不要等到上线前才去补资质。
关于支付分、信用免押这类能力,也需要在小程序后台开通对应的接口权限。开通后要注意用户协议和隐私保护指引必须明确列出"平台将收集您的支付分信息用于信用评估",审核人员会重点检查隐私政策是否完整。我一开始没在意这段文字,结果小程序的版本审核被驳回了两次,都是因为隐私政策里没有单独说明支付分和位置信息的使用用途。
合同和分账体系也要提前设计。共享无人自助台球如果涉及加盟商和平台分账,建议直接使用微信支付的分账能力,让平台作为服务商,商户作为特约商户,交易后通过分账接口把约定比例金额分配给平台方。这种模式比"商户提现后再手工转账"合规得多,也方便后续财务审计。
写在最后
这个软件从第一行代码到第一家球房上线,前后花了大约四个月。回头看我最大的体会是:做无人自助类项目,技术难的不是某个点,而是把硬件、软件、支付、运营、售后串成一条完整的服务链路。任何一个环节掉链子,落到用户身上的体验都会打折扣。如果你也在做类似的项目,我建议你先从最小闭环开始跑:一个球房、两张台子、一台控制器、一个小程序,把全流程跑通之后再谈规模化和功能扩展。忌一开始就追求大而全,系统上线第一天就背上一堆复杂配置文件,后续排障会非常痛苦。最后分享一个小技巧:所有对外暴露的API接口,从一开始就统一设计好错误码规范,开发阶段多花点心思,后面处理线上问题会节省你大量时间。