菜单消费账单核对与并行支付设计

1. 目标

CusumptionMachine 菜单消费页点击支付后的交互,由“选择支付方式弹框”调整为“账单核对弹框”:主屏展示已选菜品明细和订单总金额,同时监听刷卡与扫码,先取得有效支付凭证的一路发起支付;弹框内保留人脸支付入口,人脸识别成功后继续使用菜单消费现有刷脸支付链路。

2. 已确认范围

3. 方案比较

方案 A:新增菜单消费专用账单核对弹框(采用)

新增一个以菜单菜品为数据源的账单核对弹框,并通过设备类型创建对应的卡、码监听器。弹框负责账单展示、支付会话互斥、硬件资源释放和人脸入口;MainActivity 继续负责卡号校验、付款码清洗、人脸识别和支付请求。

优点:职责清晰,不污染称重商品模型,不复制 SellWeight 已知有问题的刷脸请求代码,也能保留 CusumptionMachine 的多设备适配。

方案 B:扩展现有支付方式选择弹框

PaymentWayChoosePop 内增加账单和硬件监听。缺点:该弹框原本负责手动选择支付方式,改造后同时承担账单、串口和会话协调,职责冲突且容易影响其他调用方。

方案 C:直接复制 SellWeight 的 BillCheckPop

缺点:SellWeight 使用 ProductBean 和固定称重设备串口,无法直接承载菜单 DishBean,也不适配当前项目的多设备驱动,且其刷脸链路存在金额和请求分流问题。

4. 主流程

  1. 用户点击菜单消费支付按钮。
  2. 如果购物车为空,提示先选择菜品并结束;不再进行 100 元金额预警。
  3. 主屏打开账单核对弹框,展示当前已选菜品和总金额。
  4. 弹框进入单次支付会话:设备 4、5、7 同时启动各自刷卡和扫码监听;设备 1、2、3 启动现有扫码流程,不创建不支持的刷卡监听;人脸支付按钮按现有支付开关控制显示。
  5. 卡号或付款码先到达并通过基础校验的一路获得本次会话处理权。
  6. 弹框立即标记会话结束,关闭所有已启动的监听器并关闭自身,迟到回调直接丢弃。
  7. MainActivity 按凭证类型继续处理:刷卡先查本地人员库,存在后调用现有 requestPayment("", "", cardCode);扫码清洗并去除支付码前缀,调用现有 requestPayment(payCode, "", "")
  8. 支付成功或失败后的行为沿用现有菜单消费逻辑。

5. 人脸支付流程

  1. 用户点击账单核对弹框中的人脸支付按钮。
  2. 弹框先结束当前卡码监听会话并释放硬件资源。
  3. 主屏打开菜单消费现有 FaceRecognitionPop,不复制 SellWeight 的刷脸实现。
  4. 识别成功后使用 user.getUserId() 调用现有 requestPayment("", userId, "")
  5. 识别失败、超时或取消时沿用现有提示,并且不自动恢复已关闭的账单弹框。

6. 组件职责

菜单账单核对弹框

MainActivity

设备监听适配层

7. 异常与资源释放

8. 界面范围

9. 验收标准

10. 不在本次范围