# 111 识别失效 PDD 商品链接返回首页并安全终止当前任务 - 工单号:#111 - 类型:缺陷 - 父级大工单:#1 - 所属 MVP / 版本:MVP 后续 / PDD 页面识别与采购安全 - 状态:已完成,用户验收通过 - 日期:2026-08-10 - Gitea 工单: ## 背景与目标 失效商品链接可能先唤起 PDD,再返回 PDD 首页。原流程只能等待商品购买入口, 最终得到普通超时,也可能把打开链接前的旧商品页当成本次目标。此次增加可靠的 页面分类和有限重开,使当前任务安全失败,同时不打断连续自动获取。 ## 最终方案 - 采集和采购共用 `pdd_page_classifier.py`,统一分类外部应用、加载、商品页、 首页、网络、登录、验证码、风控、支付/确认和未知页面。 - 首页使用 PDD 控件树、已选中的“首页”和完整底部导航组合识别;连续读取稳定且 超过跳转宽限时间后,第一次重开相同 URL,第二次才返回 `PDD_GOODS_UNAVAILABLE`。 - 打开前后商品页脱敏签名相同时拒绝旧页面,不进入规格选择或下单步骤。 - 商品失效保存为不可重试的 `FAILED`,通过现有失败 Outbox 上报;界面收到 `business_failed` 后继续下一轮自动获取。 - 复用真机读取结果制作最小脱敏首页 XML 固件,不保存推荐商品、账号和未读数量。 - 未修改 Admin API、数据库结构、`pdd_data` 或任务状态枚举。 ## 改了哪些 - `client/src/pdd_page_classifier.py`:新增共享页面分类器和商品深链状态跟踪器。 - `client/src/pdd_collect_service.py`:采集流程接入页面分类、一次重开和旧页保护。 - `client/src/pdd_u2_purchase_adapter.py`:采购流程复用相同规则,并在规格点击前失败关闭。 - `client/src/collect_task_service.py`、`purchase_task_service.py`:保存不可重试业务失败。 - `client/src/pdd_ui_event.py`:商品失效仅结束当前任务,连续模式继续获取。 - `client/test/fixtures/pdd_home_page.xml`:新增真机裁剪脱敏首页固件。 - `client/test/`:增加分类、采集、采购、任务服务和调度回归测试。 - `docs/client/06-quality-security.md`:补充商品深链页面识别安全基线。 ## 验收结果 | 验收标准 | 结果 | |---|---| | 有效商品页正常继续,短暂首页不立即误判 | 通过(状态机与现有真实商品 XML 测试) | | 稳定首页只重开一次,第二次返回指定错误码和中文提示 | 通过 | | 商品失效后不选择规格、不创建订单 | 通过 | | 商品失效不停止连续自动获取 | 通过 | | 网络、加载、外部应用、登录、验证码和风控独立分类 | 通过 | | 旧商品页不作为本次目标商品 | 通过 | | 采集与采购共用分类基础 | 通过 | | 真机首页脱敏 XML 固件覆盖 | 通过 | | 全量测试和离屏启动通过 | 通过 | | 真实下单默认关闭且未下单、未付款 | 通过 | ## 测试 - 执行的命令: - `C:/Python310/python.exe -m unittest discover -s test -p "test_*.py"` - 设置 `QT_QPA_PLATFORM=offscreen` 后实例化 `src.ui_main.MainWindow` - `C:/Python310/python.exe -m py_compile` 检查本工单修改的 Python 文件 - `git diff --check` - 结果:Client 全量 329 个测试通过;离屏启动输出 `OK`;语法和差异检查通过。 - **没验证到的部分**:没有一条由用户确认当前仍然失效的真实商品链接,因此未执行 “同一失效链接两次返回首页”的真机端到端。真机仅安全读取首页控件树并制作脱敏 固件,未点击规格、未创建订单、未下单、未付款。 ## 相关提交 - `8c9dbfe` fix: 识别失效商品链接返回首页 (#111)