Files
cmautobuy/docs/task/100-真实采购订单核对与崩溃恢复.md
T
2026-08-10 16:54:47 +08:00

4.2 KiB

100 完善真实提交后的未付款订单核对与崩溃恢复

背景与目标

真实订单提交后可能跳转、断网或崩溃,不能依赖成功页面判断结果。本任务增加独立 只读核单流程:找到唯一匹配的未付款订单才上报采购成功,其他情况转人工,并保证 重启后只核单或补报,绝不重新下单。

最终方案

  • 最终提交前把完整规格、数量、单价和总价快照与 irreversible_action_at 放在同一 SQLite 事务中保存。
  • 只读核单领域服务按商品编号、完整规格、数量、确认总价、下单时间范围和 unpaid 状态严格匹配。
  • 只有一个完全匹配的候选时,原子保存 live pdd_data、执行结果和 purchase_result Outbox。
  • 没有候选、多个候选、字段缺失或不符、非未付款、设备读取失败全部保持 manual_review,不创建成功 Outbox。
  • 相同任务执行使用稳定 result-v1 幂等键。结果落库后即使重启,也只补交 Outbox,不再读取手机。
  • 新增 uiautomator2 只读核单 Adapter,只允许启动 PDD、白名单导航、返回、滚动和读取;接口没有提交、取消或付款方法。
  • 订单候选只保存订单编号、商品编号、规格、数量、总价、下单时间和付款状态,不保存收货人、地址或电话。
  • 任务详情使用中文显示“订单已提交,只允许核对未付款订单”“已提交待付款,等待向 Admin 上报”和人工处理状态。

实现方案与工单一致。为满足金额精确匹配,补充了“最终确认快照与不可逆标记同事务保存”,已在实施前回写工单。

改了哪些

  • client/src/pdd_purchase_reconcile_adapter.py:定义只读查询、候选和扫描结果模型。
  • client/src/pdd_u2_purchase_reconcile_adapter.py:实现白名单导航、订单 XML 解析和滚动扫描。
  • client/src/purchase_reconcile_service.py:集中执行严格匹配并区分成功与人工处理。
  • client/src/purchase_task_service.py:进入不可逆阶段时一并保存最终确认快照。
  • client/src/task_repository.py:原子保存匹配结果和幂等 Outbox,并保留不可逆诊断。
  • client/src/task_detail_view.py、client/src/ui_main.py:增加中文状态并注入正式只读核单 Adapter。
  • client/test/:覆盖唯一、无、多候选、字段不符、非未付款、断线、崩溃恢复、幂等补报和脱敏 XML。
  • docs/client/:同步架构、状态、结果契约、界面和采购安全规则。

验收结果

验收标准 结果
不可逆标记存在时采购 Adapter 调用次数为 0 通过
唯一匹配且未付款才成功并幂等回传 通过(自动化测试)
0 个、多候选、字段不符或非未付款转人工 通过(自动化测试)
断网、崩溃、重启只核单补报,不重下 通过(自动化测试)
只读接口没有提交、取消和付款方法 通过(代码检查和测试)
数据和诊断不保存凭据及不必要个人数据 通过(代码检查)
详情明确显示中文人工处理步骤 通过(离屏界面测试)

测试

  • 执行的命令:cd client; C:\Python310\python.exe -m pytest -q --disable-warnings
  • 结果:291 passed, 527 warnings in 13.32s
  • 执行的命令:设置 QT_QPA_PLATFORM=offscreen 后创建并关闭 MainWindow
  • 结果:打印 OK;测试环境提示 PyQt5 字体目录缺失,不影响窗口创建。
  • 没验证到的部分:未连接 Wi-Fi Android 设备,未验证真实 PDD 订单页的导航、控件树字段和滚动行为;未执行真实下单、取消或付款。真实核单留给集成工单。

遗留问题

  • PDD 真实订单页若不在无障碍控件树中暴露商品编号或下单时间,会安全转人工,不能放宽匹配条件猜测订单。
  • 真机核单需要脱敏采集实际订单页 XML 后,再按独立工单校准解析规则。

相关提交

  • df67b0e 完善真实采购订单核对与恢复