4.0 KiB
4.0 KiB
99 实现受控真实下单并停在支付前
- 类型:需求
- 父级大工单:#96
- 所属 MVP / 版本:#97
- 状态:已完成,用户验收通过
- 日期:2026-08-10
- Gitea 工单:http://ilaer.eicp.net:8418/chengma/cmautobuy/issues/99
背景与目标
Client 原来只支持采购演练,会停在最终提交订单之前。本任务增加默认关闭、绑定 Client 和 Android 设备的真实下单能力,只允许创建一笔未付款订单,并保证进入 不可逆阶段后只核对订单,绝不重新下单。
最终方案
- SQLite 升级到版本 3,在任务上保存 Admin 下发的不可变
execution_mode;历史任务默认为dry_run。 - 设置页增加“真实下单(不支付)”卡片。启用时必须精确输入“创建未付款订单”,授权绑定当前 Client ID 和已保存 Android 设备;缺失、损坏或绑定不一致时按关闭处理。
TaskDispatcher只在授权匹配且 live Adapter 就绪时向 Admin 声明purchase_mode=live,不会把任务从演练自行提升为真实。- 演练与真实采购使用不同 Adapter 接口。演练接口没有提交方法;真实接口只增加一次性提交方法,两者都没有付款或取消订单方法。
- 最终点击前重新核对确认页、规格、数量、价格、库存和唯一提交目标。先用 SQLite 事务写入
irreversible_action_at,再允许单击一次。 - 点击返回或抛错后都转入只读订单核对。存在不可逆任务时,核单优先于 Outbox、其他本地任务和领取新任务。
实现与建单方案一致。真实订单匹配和向 Admin 上报结果不在本任务范围内,由后续工单完成。
改了哪些
client/src/live_purchase_authorization.py:保存和校验本地真实下单授权。client/src/settings_ui.py、client/src/settings_ui_event.py:增加中文授权界面和后台保存、Admin 能力登记。client/src/admin_gateway.py、client/src/http_admin_gateway.py、client/src/task_models.py:传递并校验 live 能力和任务执行模式。client/src/db_schema.py、client/src/task_repository.py:增加数据库迁移、不可逆事务和只读核单状态转换。client/src/pdd_purchase_adapter.py、client/src/pdd_u2_purchase_adapter.py:分离演练/live 接口并限制最终点击最多一次。client/src/purchase_task_service.py、client/src/task_dispatcher.py:实现最终复核、不可逆先落库和核单优先级。client/test/:补充授权、迁移、协议、调度、一次性点击和恢复测试。docs/client/:同步架构、数据、接口、界面和安全基线。
验收结果
| 验收标准 | 结果 |
|---|---|
| 新装、升级和未确认设备默认关闭 live | 通过 |
| 环境变量和普通启动参数不能开启 live | 通过 |
| Client、设备或 Adapter 不匹配时只声明 dry_run | 通过 |
| 提交前重新核对确认页和全部安全字段 | 通过(自动化测试) |
| 不可逆标记事务成功后才允许点击 | 通过(自动化测试) |
| 最终提交目标唯一且最多点击一次 | 通过(自动化测试) |
| 安全异常停止并转人工或核单 | 通过(自动化测试) |
| 不存在付款方法和付款点击路径 | 通过(代码检查) |
| dry_run 和采集任务无回归 | 通过 |
测试
- 执行的命令:
cd client; C:\Python310\python.exe -m pytest -q --disable-warnings - 结果:
286 passed, 527 warnings in 13.17s - 没验证到的部分:未使用真实 PDD 账号和 Wi-Fi Android 设备点击最终提交订单;未验证真实订单生成后的匹配与 Admin 上报,这两项留给独立真机验收和后续工单。
遗留问题
- live 任务提交后暂时保持“只允许核对订单”;订单唯一匹配及成功上报由后续工单实现。
- 真机验收必须重新获得当次明确授权,不因本工单自动化测试通过而自动执行。
相关提交
e960cab实现受控真实下单安全边界