用户点击「结算」后,服务器通过阿里云 IoT RRpc 向设备发送 close_order 命令。正常情况下,设备关机后会通过 AMQP 推送 order_close 事件,服务器收到后完成扣款和状态更新。
异常场景:order_close 事件未到达平台时:
三道防线逐层递进,确保订单最终能被结算、设备最终能被释放:
| 防线 | 触发时机 | 策略 | |------|----------|------| | 防线一 | 用户点击结算时 | RRpc 失败后重试 + 主动查询设备回退 | | 防线二 | 定时任务(每5分钟) | 扫描超时订单,查询设备兜底结算 | | 防线三 | 用户启动设备时 | 检查设备是否有僵死订单,有则先清理 |
文件: WashOrderServiceImpl.closeOrder()
用户点击结算
├─ 发送 close_order RRpc
├─ 失败 → 重试 1 次
└─ 重试仍失败 → queryOrder() 主动查询
├─ 设备已关闭 → 直接结算
├─ 设备仍在运行 → forceCloseOrder() 强制关闭
└─ 设备不可达 → 提示用户稍后重试
文件: StaleOrderReconciliationJob.java
模块: car-wash-admin
执行频率: 每 5 分钟
阈值配置: kym.stale-order-threshold-seconds(默认 1800 秒 = 30 分钟)
扫描条件:
order_status = 0(开机)pay_status = 0(未支付)start_time < now - threshold处理策略:
queryOrder() RRpc
order_update 保存的数据兜底结算,close_type 标记为 reconcilestopReason 为异常,等待人工介入文件: WashOrderServiceImpl.createOrder() → checkAndResolveStaleOrder()
在创建新订单前:
queryOrder() 确认设备实际状态| 文件 | 操作 | 说明 |
|---|---|---|
car-wash-service/.../OrderSettlementService.java |
新增 | 结算服务接口 |
car-wash-service/.../OrderSettlementServiceImpl.java |
新增 | 结算逻辑提取(从 OrderCloseEventHandler 抽取) |
car-wash-service/.../OrderCloseEventHandler.java |
修改 | 简化为委托 OrderSettlementService |
car-wash-service/.../AwoaraEventHandlerFactory.java |
修改 | 适配新构造参数 |
car-wash-service/.../WashOrderServiceImpl.java |
修改 | closeOrder 增强 + createOrder 预检 |
car-wash-admin/.../StaleOrderReconciliationJob.java |
新增 | 僵死订单定时对账任务 |
# application.yml(可选,默认 1800 秒 = 30 分钟)
kym:
stale-order-threshold-seconds: 1800
建议设置为设备 operationTimeout(默认 3600 秒)的一半,既不会误伤正常订单,也能及时处理异常。