断网还能收钱的收银机:给水果店做的一套离线优先小工具
「断网了你这软件还能收钱吗?」
小区门口水果店,老板娘陈姐的第一句话不是问功能,是这个。她指着收银台底下那台路由器:「上个月移动修线路,断了半天,那个连锁收银软件整个点不开,我拿本子手写了四十多单,晚上对账差了三十块钱,说不清是谁的。」
她之前用的是某连锁收银 SaaS,一年会员费两千八,按月扣。断网就是整台机器报废,因为单子全在云端,本地不留任何东西。这是很多甲方分不清的关键点:SaaS 的离线能力是厂商给的,离线优先是架构上你自己留的。
我把账摊开给她算:水果店高峰在傍晚五点到八点,一单平均 40 秒,断网一小时就是 90 单。本地不落单,这 90 单要么丢单要么手写,两条路都是灾难。所以我报了 1.2 万、两周工期,方案就一句话:单子永远先落本地,网络只是锦上添花。
离线优先的四个落地点
第一,SQLite 是唯一的真实数据源,网络不是。 商品、价格、订单、日结,全在本地一个 SQLite 文件里。云端服务器只做两件事:连锁多店时同步商品价格、晚上汇总报表。就算服务器彻底挂了,店里照常卖货。这是整个方案的地基,先把这个定下来,后面全是工程问题。
第二,断网判断别自己发明。 .NET 里现成的 NetworkChange.NetworkAvailabilityChanged 事件,加上下单接口的真实探测,两层信号取与。只在界面右上角放一条状态指示,绝不弹窗打断收银——陈姐原话:「你弹窗我就慌,一慌就按错。」断网期间下单流程和联网时一模一样,只是单据状态字段置为「待同步」。
第三,同步队列要幂等。 每张小票一个 GUID 单号,本地生成,上传时服务端按单号去重。断网两小时攒下 17 单,网络恢复后队列逐条重传,服务端收到重复单直接丢弃。这里踩过一个真实的坑:SQLite 多线程写入报 database is locked,查了半天是收银线程和小票打印线程同时写库。解法是开 WAL 模式加 busy_timeout,两行配置,之后一次没再复现。
第四,小票打印走 ESC/POS 指令直发。 58mm 热敏打印机,不需要装厂商驱动,C# 直接往 USB 端口写字节流。断网时打印完全不受影响,因为它压根不经过网络。收银环节里唯一「物理离线」的一环,反而最稳。
对账是甲方真正检验你的时刻
上线第三天陈姐打电话来,语气不太好:「今天的钱对不上。」我远程看了数据:本地日结合计 4,367 元,微信商户后台 4,367 元,支付宝后台 4,367 元——一分不差。她说的对不上,是她自己漏盘了一筐橘子的钱,账是平的。
我把日结页改了改:按支付方式分组合计,再并排显示本地单据数和云端已同步单据数,差多少单一目了然。第二天她发来一句:「今天对得上了,三分钟对完。」后来她跟同一条街的奶茶店推荐了我,那是另一个单子的事了。
这类项目给我的判断一直很一致:甲方搜「收银系统」出来的是 SaaS 广告,但夫妻店、小镇门店这些场景,一套离线优先的本地小工具,比月费制的连锁方案更贴身,也更便宜。报价 1.2 万听着不小,陈姐算的是另一笔账:省掉的会员费、手写对账错的糊涂账、断网趴窝一小时九十几单的险情——半年不到就回本了。
技术上的收获浓缩成一句:离线优先最难的不是「断网能跑」,是恢复联网后那 17 单怎么一条不丢、一条不重地补上去。GUID 单号加幂等去重,八行代码的方案,值这个项目的一半报价。
有定制软件需求(.NET 桌面端 / 小程序 / APP),直接联系:微信/手机 17788568694
(转载请注明作者与出处)
手机 17788568694 | 微信 17788568694(与手机同号)| QQ 76656825

浙公网安备 33010602011771号