三端各自的定位
起步时只有 PC 管理后台,端多了之后最大的风险是功能在三个端重复生长,改一处要改三处。我们在架构评审时把边界先划清楚:
| 端 | 用户 | 核心职责 | 不做什么 |
|---|---|---|---|
| PC 管理后台 | 前台、站长、总部 | 建单、结算、库存、报表、配置 | 不做技师现场操作 |
| 技师 App | 技师 | 领料、报工、拍照、质检签字 | 不做价格和库存设置 |
| 车主小程序 | 车主 | 查记录、看进度、预约、评价 | 不做任何内部管理功能 |
判断标准就一条:谁在现场,操作就落在谁的设备上。技师蹲在地沟里,让他跑去前台录报工是反人性的;反过来,结算这种要反复核对金额的动作,放在 PC 上做。
一套 API 服务三端
三个端走同一个 API 服务,差异收敛在网关层。鉴权有三种来源:PC 后台用 JWT 长令牌加二次校验;技师 App 用 JWT 加设备指纹绑定,换机必须站长解锁;小程序用 code 换 openid,再映射到系统里的车主账号,签发短时 token。网关统一做限流和参数脱敏,比如小程序侧的任何接口都拿不到配件成本价字段,这是在网关响应过滤里做的,不靠前端自觉。
接口版本管理用 URL 前缀 /v1/。小程序的发布有审核周期,App 有强制更新机制,PC 随发随更,三端版本节奏不同,没有版本前缀的话老版本小程序会打到新接口上。目前 /v1 已经累积了两次不兼容变更,都在网关做了双写兼容期。
进度同步:长连接与轮询并存
工单状态一变(接车、维修中、待质检、已交车),三端都要感知。方案上我们对比过:
| 方案 | 适用端 | 优点 | 缺点 |
|---|---|---|---|
| WebSocket 长连接 | 技师 App、PC | 实时,服务器可主动推 | 门店网络下连接不稳定 |
| 定时轮询 | 车主小程序 | 简单,穿透各种网络 | 延迟分钟级,空请求多 |
| 微信订阅消息 | 车主小程序 | 不占连接,触达强 | 一次性授权,见下篇 |
最后没有强行统一:App 和 PC 挂长连接,小程序退化为"轮询 + 订阅消息兜底"。整体链路是:
工单状态变更 --> 业务服务 --> 消息队列 --> 推送网关 --WebSocket--> App/PC
|
+--> 订阅消息服务 --> 微信模板消息 --> 车主
踩坑:安静死掉的长连接
上线第一周,三家试点门店的技师 App 反馈"进度不更新,杀掉重开才有"。排查发现车间是金属棚顶,路由器对空闲连接做了 5 分钟强踢,TCP 半死连接服务端检测不到,消息全推进了黑洞,一周累计丢了 137 条进度推送。
修复分两层。一是心跳间隔从默认的 60 秒压到 25 秒,低于路由器空闲阈值;二是给每条推送加单调递增的 seq,客户端重连成功后带 last_seq 请求增量补发,推送网关按连接保留最近 200 条。上线后再没收到丢消息的反馈。
弱网离线缓存是另一半工作。技师在举升机下面没信号,App 把报工、领料操作先落本地队列,带 client_seq 和时间戳,恢复网络后按序上送。冲突合并目前的策略很朴素:同一工单同一字段,服务端版本新的赢,服务端记录冲突日志。技师补录的工时和站长同时改的派工单撞上的情况,现实里一个星期也遇不到一次,我们没有为极低概率场景上复杂的合并算法,先保持简单,等真实冲突日志攒出模式再说。