Client:兼容纵向套餐标题滑出后的续页采集 #168

Closed
opened 2026-08-11 17:24:49 +08:00 by ila · 4 comments
Owner

基本信息

  • 类型:缺陷
  • 父级大工单:#1
  • 所属 MVP / 版本:#2 / Client 可运行任务闭环
  • 阶段:PDD 规格兼容
  • 关联工单:#166、#167
  • 状态:待验收

要解决什么

纵向套餐数量较多时,Client 首屏能识别“套餐”第二规格;向下滑动后,“套餐”标题离开无障碍控件树,但套餐选项仍可见。当前每一屏都会重新依赖可见标题调用 parse_spec_panel(),因此无法再生成 size 维度,并报:

PDD_DATA_SPEC_INCOMPLETE:滚动过程中丢失第二规格:套餐

这是续页归属信息丢失,不代表套餐节点真实消失。

做什么 / 不做什么

  • 做:首次识别第二规格后保存续页采集上下文。
  • 做:标题滑出屏幕后,继续在已锁定的滚动容器和同类选项结构中采集。
  • 做:第二规格签名不再强制依赖当前屏幕可见标题。
  • 做:连续确认容器消失或无法可靠识别时才报数据不完整。
  • 做:增加纵向长套餐标题消失、边界停止及误收按钮的回归测试。
  • 不做:不修改颜色遍历、逐颜色取价和缺价规则。
  • 不做:不点击套餐或尺码。
  • 不做:不修改数据库、Admin 接口和 pdd_data schema。
  • 不做:不执行真实采购、下单或付款。

已确认的实现方案

  1. 首次从 SpecSnapshot 识别到第二规格时,记录名称、滚动方向、滚动容器特征,以及当前选项的节点结构特征。
  2. 后续页面仍能看到标题时沿用正常解析;标题消失时进入“第二规格续页模式”,在同一滚动容器内按已确认结构提取选项。
  3. 续页提取限定在规格面板和锁定容器内,并排除价格、数量、下单按钮及其他操作控件。
  4. 第二规格视口签名直接使用续页提取结果,不再间接依赖 parse_spec_panel() 必须看到标题。
  5. 连续视口无变化认定到达末端;容器短暂解析不到时允许再次确认,持续丢失才返回 PDD_DATA_SPEC_INCOMPLETE。
  6. 保持 #167 横向套餐、普通衣服纵向尺码和原颜色价格流程兼容。

预计修改:

  • client/src/pdd_collect_service.py
  • client/test/test_pdd_collect_service.py
  • docs/task/<工单号>-兼容纵向套餐标题滑出.md

验收标准

  • 纵向长套餐在“套餐”标题滑出屏幕后仍能继续收集后续选项。
  • 所有套餐按页面顺序去重,连续稳定到边后结束。
  • 不会把价格、数量、下单按钮等控件误收为套餐。
  • 横向套餐、普通衣服尺码、颜色价格及默认尺码取消测试保持通过。
  • 第二规格续页采集过程中不点击套餐或尺码。
  • 不修改数据库、Admin 接口、数据结构和采购安全规则。
  • 精确测试、Client 全量测试和 py_compile 通过;不执行真实下单或付款。

验证方式

从 client/ 运行采集服务精确测试、完整 test_*.py 和修改文件 py_compile。使用 Fake Device 模拟纵向长套餐:首屏包含标题,后续屏只有套餐选项,并包含下单或数量干扰节点。真机商品由用户验收。

风险和回退

  • 标题消失后归属依据减少,必须同时限制滚动容器和节点结构,避免收集操作按钮。
  • 容器特征不能只依赖 XML Element 对象;每次控件树重建后要通过稳定属性和区域重新定位。
  • 回退本工单代码提交即可,不涉及数据库迁移。
## 基本信息 - 类型:缺陷 - 父级大工单:#1 - 所属 MVP / 版本:#2 / Client 可运行任务闭环 - 阶段:PDD 规格兼容 - 关联工单:#166、#167 - 状态:待验收 ## 要解决什么 纵向套餐数量较多时,Client 首屏能识别“套餐”第二规格;向下滑动后,“套餐”标题离开无障碍控件树,但套餐选项仍可见。当前每一屏都会重新依赖可见标题调用 `parse_spec_panel()`,因此无法再生成 `size` 维度,并报: `PDD_DATA_SPEC_INCOMPLETE:滚动过程中丢失第二规格:套餐` 这是续页归属信息丢失,不代表套餐节点真实消失。 ## 做什么 / 不做什么 - 做:首次识别第二规格后保存续页采集上下文。 - 做:标题滑出屏幕后,继续在已锁定的滚动容器和同类选项结构中采集。 - 做:第二规格签名不再强制依赖当前屏幕可见标题。 - 做:连续确认容器消失或无法可靠识别时才报数据不完整。 - 做:增加纵向长套餐标题消失、边界停止及误收按钮的回归测试。 - 不做:不修改颜色遍历、逐颜色取价和缺价规则。 - 不做:不点击套餐或尺码。 - 不做:不修改数据库、Admin 接口和 `pdd_data` schema。 - 不做:不执行真实采购、下单或付款。 ## 已确认的实现方案 1. 首次从 `SpecSnapshot` 识别到第二规格时,记录名称、滚动方向、滚动容器特征,以及当前选项的节点结构特征。 2. 后续页面仍能看到标题时沿用正常解析;标题消失时进入“第二规格续页模式”,在同一滚动容器内按已确认结构提取选项。 3. 续页提取限定在规格面板和锁定容器内,并排除价格、数量、下单按钮及其他操作控件。 4. 第二规格视口签名直接使用续页提取结果,不再间接依赖 `parse_spec_panel()` 必须看到标题。 5. 连续视口无变化认定到达末端;容器短暂解析不到时允许再次确认,持续丢失才返回 `PDD_DATA_SPEC_INCOMPLETE`。 6. 保持 #167 横向套餐、普通衣服纵向尺码和原颜色价格流程兼容。 预计修改: - client/src/pdd_collect_service.py - client/test/test_pdd_collect_service.py - docs/task/<工单号>-兼容纵向套餐标题滑出.md ## 验收标准 - [x] 纵向长套餐在“套餐”标题滑出屏幕后仍能继续收集后续选项。 - [x] 所有套餐按页面顺序去重,连续稳定到边后结束。 - [x] 不会把价格、数量、下单按钮等控件误收为套餐。 - [x] 横向套餐、普通衣服尺码、颜色价格及默认尺码取消测试保持通过。 - [x] 第二规格续页采集过程中不点击套餐或尺码。 - [x] 不修改数据库、Admin 接口、数据结构和采购安全规则。 - [x] 精确测试、Client 全量测试和 py_compile 通过;不执行真实下单或付款。 ## 验证方式 从 `client/` 运行采集服务精确测试、完整 `test_*.py` 和修改文件 `py_compile`。使用 Fake Device 模拟纵向长套餐:首屏包含标题,后续屏只有套餐选项,并包含下单或数量干扰节点。真机商品由用户验收。 ## 风险和回退 - 标题消失后归属依据减少,必须同时限制滚动容器和节点结构,避免收集操作按钮。 - 容器特征不能只依赖 XML Element 对象;每次控件树重建后要通过稳定属性和区域重新定位。 - 回退本工单代码提交即可,不涉及数据库迁移。
Author
Owner

实施完成,等待真机验收

  • 实现提交:94793ab
  • 归档提交:1730c57
  • 本地归档:docs/task/168-兼容纵向套餐标题滑出.md

实现结果:

  • 首屏识别第二规格后保存容器和选项结构;
  • “套餐”标题滑出后,从同一容器继续提取同结构选项;
  • 第二规格签名不再依赖当前屏可见标题;
  • 短暂缺少节点会重读一次,持续丢失才失败;
  • 排除价格、数量和提交订单等操作控件。

验证:

  • 采集服务 61 项测试通过;
  • Client 完整 423 项测试通过;
  • py_compile 通过。

未验证:尚未使用发生问题的真机商品重新采集;未执行真实采购、下单或付款。工单保持打开,等待用户验收。

## 实施完成,等待真机验收 - 实现提交:`94793ab` - 归档提交:`1730c57` - 本地归档:`docs/task/168-兼容纵向套餐标题滑出.md` 实现结果: - 首屏识别第二规格后保存容器和选项结构; - “套餐”标题滑出后,从同一容器继续提取同结构选项; - 第二规格签名不再依赖当前屏可见标题; - 短暂缺少节点会重读一次,持续丢失才失败; - 排除价格、数量和提交订单等操作控件。 验证: - 采集服务 61 项测试通过; - Client 完整 423 项测试通过; - `py_compile` 通过。 未验证:尚未使用发生问题的真机商品重新采集;未执行真实采购、下单或付款。工单保持打开,等待用户验收。
Author
Owner

真机验收未通过:续页套餐被价格过滤规则误删

用户使用最新代码重新采集后仍报:
PDD_DATA_SPEC_INCOMPLETE:滚动过程中持续丢失第二规格:套餐

已检查 2026-08-11 17:30:57 保存的失败控件树(仅记录脱敏结论,不上传现场文件):

  • “套餐”标题确实已经滑出当前控件树;
  • 第二规格滚动容器仍存在:android.support.v7.widget.RecyclerView,范围 [0,1130][1080,1968];
  • 容器中仍有多个可点击套餐节点;
  • 真机套餐节点文字采用“套餐名称 + 价格”的形式,例如 100%防晒护颈【黑色2个+浅灰2个】 ¥5.69。

新根因:#168 的 _is_second_dimension_action() 为排除价格控件,当前把所有包含 ¥/¥ 的文字都判为操作项。真实套餐的按钮文字也包含价格,因此续页候选全部被过滤,提取结果为空;重读一次仍为空,最终误报“持续丢失第二规格”。

建议修订:

  1. 只有“纯价格节点”才按价格控件排除,不能按是否包含人民币符号判断;
  2. “套餐名称 + 尾部价格”的可点击同结构节点应作为有效套餐,并在保存规格文字前去掉尾部价格;
  3. 继续用已锁定容器、节点结构和明确操作词排除数量/提交按钮;
  4. 增加真实结构对应的测试:标题滑出、每个套餐都带尾部价格,必须完整采集且不混入价格文本;
  5. 同时检查接近容器全宽的长套餐,避免宽度阈值再次误删。

状态保持打开并退回“进行中/待修复”,现有提交不回退,等待用户确认修订方案后继续实施。

## 真机验收未通过:续页套餐被价格过滤规则误删 用户使用最新代码重新采集后仍报: `PDD_DATA_SPEC_INCOMPLETE:滚动过程中持续丢失第二规格:套餐` 已检查 2026-08-11 17:30:57 保存的失败控件树(仅记录脱敏结论,不上传现场文件): - “套餐”标题确实已经滑出当前控件树; - 第二规格滚动容器仍存在:`android.support.v7.widget.RecyclerView`,范围 `[0,1130][1080,1968]`; - 容器中仍有多个可点击套餐节点; - 真机套餐节点文字采用“套餐名称 + 价格”的形式,例如 `100%防晒护颈【黑色2个+浅灰2个】 ¥5.69`。 新根因:#168 的 `_is_second_dimension_action()` 为排除价格控件,当前把所有包含 `¥/¥` 的文字都判为操作项。真实套餐的按钮文字也包含价格,因此续页候选全部被过滤,提取结果为空;重读一次仍为空,最终误报“持续丢失第二规格”。 建议修订: 1. 只有“纯价格节点”才按价格控件排除,不能按是否包含人民币符号判断; 2. “套餐名称 + 尾部价格”的可点击同结构节点应作为有效套餐,并在保存规格文字前去掉尾部价格; 3. 继续用已锁定容器、节点结构和明确操作词排除数量/提交按钮; 4. 增加真实结构对应的测试:标题滑出、每个套餐都带尾部价格,必须完整采集且不混入价格文本; 5. 同时检查接近容器全宽的长套餐,避免宽度阈值再次误删。 状态保持打开并退回“进行中/待修复”,现有提交不回退,等待用户确认修订方案后继续实施。
Author
Owner

根据真机失败控件树完成第二次修订

  • 修订提交:6ed2305
  • 归档更新提交:c61a028

最终修复:

  • 不再把所有含 ¥/¥ 的节点当作价格控件;
  • 纯价格节点仍排除;
  • “套餐名称 + 尾部价格”的按钮保留为套餐,入库前去掉尾部价格;
  • 已锁定为套餐结构的长按钮不再受 85% 容器宽度阈值限制;
  • 第二规格签名使用同一套规范化文字,避免标题消失后签名始终为空而提前停止。

回归测试已改为模拟 16 个带价格纵向套餐、标题滑出、5 屏遍历、接近全宽长按钮、纯价格节点、数量和提交按钮:

  • 采集服务 61 项通过;
  • Client 全量 423 项通过;
  • 语法检查通过。

状态重新进入“待验收”。请使用同一真机商品重新采集;本次未执行真实采购、下单或付款。

## 根据真机失败控件树完成第二次修订 - 修订提交:`6ed2305` - 归档更新提交:`c61a028` 最终修复: - 不再把所有含 `¥/¥` 的节点当作价格控件; - 纯价格节点仍排除; - “套餐名称 + 尾部价格”的按钮保留为套餐,入库前去掉尾部价格; - 已锁定为套餐结构的长按钮不再受 85% 容器宽度阈值限制; - 第二规格签名使用同一套规范化文字,避免标题消失后签名始终为空而提前停止。 回归测试已改为模拟 16 个带价格纵向套餐、标题滑出、5 屏遍历、接近全宽长按钮、纯价格节点、数量和提交按钮: - 采集服务 61 项通过; - Client 全量 423 项通过; - 语法检查通过。 状态重新进入“待验收”。请使用同一真机商品重新采集;本次未执行真实采购、下单或付款。
Author
Owner

用户于 2026-08-13 明确验收通过。本地归档状态已更新,批量验收记录提交:ad44f83。现关闭工单。

用户于 2026-08-13 明确验收通过。本地归档状态已更新,批量验收记录提交:`ad44f83`。现关闭工单。
ila closed this issue 2026-08-13 15:58:27 +08:00
Sign in to join this conversation.
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: chengma/cmautobuy#168