diff --git a/docs/task/35-修复-pdd-商品页误判与失败响应.md b/docs/task/35-修复-pdd-商品页误判与失败响应.md new file mode 100644 index 0000000..d2350cf --- /dev/null +++ b/docs/task/35-修复-pdd-商品页误判与失败响应.md @@ -0,0 +1,77 @@ +# 35 修复 PDD 商品页误判与失败响应 + +- 类型:缺陷 +- 父级大工单:#1 +- 所属 MVP / 版本:#2 / MVP +- 状态:待验收 +- 日期:2026-08-07 +- Gitea 工单:http://ilaer.eicp.net:8418/chengma/cmautobuy/issues/35 + +## 背景与目标 + +#32 真机联调时,手机已经显示 PDD 商品页,控件树也包含 PDD 节点和“免拼购买”,但 ColorOS 的 `app_current()` 仍返回无线调试设置页。Client 因此误判页面未加载,30 秒后提交 `PDD_PAGE_TIMEOUT`。 + +Admin 实际接收了失败上报,但旧失败响应没有 `result_id`,Client 又把 200 响应误报成“Admin 拒绝:响应字段不完整”。加载超时还没有保存最后一份 XML,无法从报告中复盘页面。 + +## 最终方案 + +- 等待商品页时每轮都读取无障碍树,不再只有焦点包名为 PDD 时才读取。 +- 商品页就绪要求焦点包为 PDD,或者控件树中至少有 3 个真实 PDD 包节点;同时仍要求购买入口标记存在且页面不在加载中。 +- 只有确认属于 PDD 的页面才检查登录和验证码,避免其他应用的相似文字误触发。 +- 每轮保留最后一份 XML;超时时写入 `data/artifacts/`,诊断信息保存本地路径、SHA-256 和检查屏数。 +- Admin `SubmitFailure` 成功响应增加非空 `result_id`,和 `SubmissionReceipt` 统一。 +- Client 兼容已经进入旧幂等表的 `accepted + task_status + accepted_at` 回执,用原幂等键重试时不会永久卡住。 +- 真正的 2xx 格式异常改为可重试,提示“数据可能已接收”,不再显示“Admin 拒绝”。 +- 启动恢复时把 #35 之前因“Admin 提交响应字段不完整”被标成 `failed` 的 Outbox 恢复为 `pending`。 + +## 改了哪些 + +- `client/src/pdd_collect_service.py`:修复页面就绪判断并保留超时 XML。 +- `client/src/http_admin_gateway.py`:兼容旧失败回执,调整异常响应语义。 +- `client/src/task_repository.py`:恢复历史上误标为永久失败的 Outbox。 +- `admin/service/submit.go`:失败响应增加 `result_id`。 +- `client/test/`、`admin/service/submit_test.go`:增加焦点错报、非 PDD 防误判、诊断文件、旧回执和恢复测试。 +- `docs/client/04-admin-api-contract.md`、`docs/admin/04-client-api.md`:明确失败响应结构。 + +## 验收结果 + +| 验收标准 | 结果 | +|---|---| +| 焦点报告设置页、真实 PDD 控件树时判定就绪 | 通过,含真实 XML 回归 | +| 非 PDD 控件树含“免拼购买”时不误判 | 通过 | +| 登录、验证码、加载中页面继续拦截 | 通过原有回归 | +| 加载超时保存 XML 路径和 SHA-256 | 通过 | +| Admin failure 响应包含非空 `result_id` | 通过 | +| Client 兼容旧 Admin 幂等回执 | 通过 | +| 2xx 格式异常保留为可重试 | 通过 | +| 历史误标失败 Outbox 在启动时恢复 | 通过 | +| 真机重新进入规格面板 | 未验证:ADB 在复验前离线 | +| 不执行加购、下单或付款 | 通过 | + +## 测试 + +```powershell +# client 目录 +C:/Python310/python.exe -m unittest discover -s test -p 'test_*.py' -q + +# admin 目录 +go test ./... + +# Client 离屏冒烟 +$env:QT_QPA_PLATFORM='offscreen' +C:/Python310/python.exe -c "from src.ui_main import MainWindow; from PyQt5.QtWidgets import QApplication; app=QApplication([]); w=MainWindow(); print('OK'); w.close(); app.quit()" +``` + +- Client 150 项测试通过。 +- Admin 全量 Go 测试通过。 +- Client 离屏启动和关闭通过,输出 `OK`。 +- 使用 `737116531267_home.xml` 复现“焦点为无线设置、控件树为 PDD”,页面就绪判断通过。 +- **没验证到的部分**:准备真机复验时 `192.168.0.173:5555` 已从 ADB 设备列表消失,因此没有再次进入规格面板,也没有完成真实 Admin 页面联调;验证过程中没有加购、下单或付款。Windows 高对比度和 200% 缩放未手工验证。 + +## 当前任务恢复说明 + +原任务 `COL-2fd0ccb9c55e450b` 本地仍是 `retry_wait`,旧失败 Outbox 会在新版 Client 启动时恢复。第一次点击“获取任务”会用原幂等键确认旧失败回执,第二次点击才会重新采集该任务。这是单任务模式下的预期行为,不会重复领取或下单。 + +## 相关提交 + +- `c59b4b0` `fix: 修复 PDD 页面误判与失败回执 (#35)`