重构 Android 采购规格动作的可验证点击与容器滚动 #214

Open
opened 2026-09-04 18:12:56 +08:00 by ila · 2 comments
Owner

原始需求摘要

提出时间:2026-09-04。

用户反馈 Android Agent 执行 PDD 采购时多次因按钮无法点击或规格无法选中而失败;既有针对不同页面形态的修复仍反复出现。用户确认参考 D:\OPC\agent_admin\docs\agent 的动作模型,优化当前项目 Agent。

Gitea MCP 回退说明:当前会话未提供项目 Gitea MCP 工具,因此按仓库规则回退 Gitea API;凭据仅从被 Git 忽略的 gitea.env 读取。

目标

  • 将规格入口和精确规格选择收敛为“重新定位 → 安全执行 → 新页面验证 → 有界恢复”的可验证动作。
  • 区分无障碍点击失败、点击已接受但无页面效果、规格面板分类未命中和选中验证失败。
  • 规格查找滚动锁定解析得到的规格面板容器,避免误滑页面中其它滚动区域。

非目标

  • 不修改地址动作、创建订单动作或只读核单流程。
  • 不新增或执行支付动作。
  • 不保存或上传完整控件树、整屏截图或个人数据。
  • 不修改服务端采购规则 schema、Agent API 或数据库。
  • 本工单不执行真机创建订单。

前置依赖与并行性

  • 基于已合入当前开发链的 #206~#211 规格面板诊断、入口识别和有限等待能力。
  • 与 SYB、Admin Web 和服务端任务状态机无真实依赖;只修改 Android 交付单元。
  • 同一 Android 采购执行文件上的其它改动不宜并行,避免行为和测试冲突。

当前事实与根因

  • openSpecPanel 仅在 ACTION_CLICK 返回成功后等待面板证据,因此“点击后未识别到商品规格面板”同时包含“点击无效果”和“面板已开但分类器未识别”两类情况。
  • clickFreshDetailed 当前只沿可点击父链执行 ACTION_CLICK,没有在唯一且有效边界目标上的受控中心手势兜底。
  • 规格查找调用全局 swipePurchase,按最大滚动区域选择目标,没有使用解析器已取得的 specPanelContainer。
  • 规格点击最多重试三次,但没有先检查目标是否已处于精确选中状态。
  • AgentAdmin 的 after、AUTO 点击、SCROLL 和 SELECT_OPTION 是设计提案而非成熟实现,因此只借鉴动作语义,不复制其执行器。

实施方案

  1. 扩展采购驱动,增加只允许规格入口/规格选项使用的受控中心手势方法;重新定位必须保持标签、类型、近似中心唯一匹配,目标可见、启用且边界有效。
  2. 抽取可验证规格点击:先读取后置条件;无障碍点击最多一次并等待新快照;无效果时才允许中心手势最多一次;每次动作后重新读取页面。
  3. 规格入口以“面板打开”为后置条件;失败时分别回传无效果与面板证据未匹配的稳定诊断。
  4. 精确规格选择先检查已选中;只对服务端下发且解析器唯一确认的精确规格执行动作,以选中节点或精确摘要作为后置条件。
  5. 规格滚动使用 specPanelContainer 的新快照定位;优先节点滚动,必要时才在该容器内手势,保持次数与总时间有界。
  6. 中心手势兜底不得用于地址、保存地址、创建订单、订单详情入口或任何支付语义目标。
  7. 补充 JVM 测试覆盖单次无障碍点击、无效果后单次手势、手势后验证、已选中不点击、容器滚动和禁止扩大到不可逆动作。

设计证据

本工单不新增 UI 页面或交互,不需要 UI 原型。架构与安全设计以本工单方案及以下既有规则为依据:

  • GoAuto 精确规格、唯一目标、有限动作、禁止支付和不保存原始控件树边界。
  • AgentAdmin 文档中的 CLICK after、AUTO 兜底、SCROLL 容器重定位与 SELECT_OPTION 先验选中检查,仅作为动作模型参考。

验收标准

  • 规格入口的 ACTION_CLICK 返回成功但页面无变化时,不再直接混同为面板分类失败;允许在严格安全条件下执行一次中心手势并重新验证。
  • 中心手势后出现规格面板时继续任务;仍无变化时返回稳定的点击无效果错误。
  • 页面已变化但规格面板强证据不足时返回独立的面板证据不匹配错误及无敏感标量诊断。
  • 精确规格已经选中时不重复点击;点击失败但新页面已显示精确选中时视为成功。
  • 规格搜索只滚动唯一的规格面板容器,不选择全页其它最大滚动区域。
  • 所有动作次数和等待时间有明确上限;歧义、无安全目标或验证失败均 fail-closed。
  • 地址、创建订单和支付安全边界保持不变。

验证计划

  • Android 采购执行和无障碍驱动 JVM 单元测试。
  • android 单元测试。
  • Debug APK 构建。
  • 仓库 Android 验证脚本(范围允许时)。
  • 真机 PDD 页面需在同一设备、同一 Agent 版本和同一规则快照下另行验收;本工单不点击创建订单。

风险

  • PDD 自定义控件可能返回成功但不触发页面变化;中心手势必须严格限定唯一目标与有效边界。
  • 手势可能命中覆盖层;必须依赖动作后强证据,失败即停止。
  • 规格面板页面形态持续变化;不得通过放宽到相近文本或任意购买按钮解决。

文档影响

有长期文档影响:需要更新 Android-Agent-API-Contract 与 Business-Rules-and-Glossary,记录规格动作受控手势兜底、后置验证、容器滚动及不可逆动作排除边界;按 Wiki-first 流程在线更新、回读 revision 后同步本地镜像。

## 原始需求摘要 提出时间:2026-09-04。 用户反馈 Android Agent 执行 PDD 采购时多次因按钮无法点击或规格无法选中而失败;既有针对不同页面形态的修复仍反复出现。用户确认参考 `D:\OPC\agent_admin\docs\agent` 的动作模型,优化当前项目 Agent。 Gitea MCP 回退说明:当前会话未提供项目 Gitea MCP 工具,因此按仓库规则回退 Gitea API;凭据仅从被 Git 忽略的 `gitea.env` 读取。 ## 目标 - 将规格入口和精确规格选择收敛为“重新定位 → 安全执行 → 新页面验证 → 有界恢复”的可验证动作。 - 区分无障碍点击失败、点击已接受但无页面效果、规格面板分类未命中和选中验证失败。 - 规格查找滚动锁定解析得到的规格面板容器,避免误滑页面中其它滚动区域。 ## 非目标 - 不修改地址动作、创建订单动作或只读核单流程。 - 不新增或执行支付动作。 - 不保存或上传完整控件树、整屏截图或个人数据。 - 不修改服务端采购规则 schema、Agent API 或数据库。 - 本工单不执行真机创建订单。 ## 前置依赖与并行性 - 基于已合入当前开发链的 #206~#211 规格面板诊断、入口识别和有限等待能力。 - 与 SYB、Admin Web 和服务端任务状态机无真实依赖;只修改 Android 交付单元。 - 同一 Android 采购执行文件上的其它改动不宜并行,避免行为和测试冲突。 ## 当前事实与根因 - `openSpecPanel` 仅在 `ACTION_CLICK` 返回成功后等待面板证据,因此“点击后未识别到商品规格面板”同时包含“点击无效果”和“面板已开但分类器未识别”两类情况。 - `clickFreshDetailed` 当前只沿可点击父链执行 `ACTION_CLICK`,没有在唯一且有效边界目标上的受控中心手势兜底。 - 规格查找调用全局 `swipePurchase`,按最大滚动区域选择目标,没有使用解析器已取得的 `specPanelContainer`。 - 规格点击最多重试三次,但没有先检查目标是否已处于精确选中状态。 - AgentAdmin 的 `after`、`AUTO` 点击、`SCROLL` 和 `SELECT_OPTION` 是设计提案而非成熟实现,因此只借鉴动作语义,不复制其执行器。 ## 实施方案 1. 扩展采购驱动,增加只允许规格入口/规格选项使用的受控中心手势方法;重新定位必须保持标签、类型、近似中心唯一匹配,目标可见、启用且边界有效。 2. 抽取可验证规格点击:先读取后置条件;无障碍点击最多一次并等待新快照;无效果时才允许中心手势最多一次;每次动作后重新读取页面。 3. 规格入口以“面板打开”为后置条件;失败时分别回传无效果与面板证据未匹配的稳定诊断。 4. 精确规格选择先检查已选中;只对服务端下发且解析器唯一确认的精确规格执行动作,以选中节点或精确摘要作为后置条件。 5. 规格滚动使用 `specPanelContainer` 的新快照定位;优先节点滚动,必要时才在该容器内手势,保持次数与总时间有界。 6. 中心手势兜底不得用于地址、保存地址、创建订单、订单详情入口或任何支付语义目标。 7. 补充 JVM 测试覆盖单次无障碍点击、无效果后单次手势、手势后验证、已选中不点击、容器滚动和禁止扩大到不可逆动作。 ## 设计证据 本工单不新增 UI 页面或交互,不需要 UI 原型。架构与安全设计以本工单方案及以下既有规则为依据: - GoAuto 精确规格、唯一目标、有限动作、禁止支付和不保存原始控件树边界。 - AgentAdmin 文档中的 CLICK `after`、AUTO 兜底、SCROLL 容器重定位与 SELECT_OPTION 先验选中检查,仅作为动作模型参考。 ## 验收标准 - 规格入口的 `ACTION_CLICK` 返回成功但页面无变化时,不再直接混同为面板分类失败;允许在严格安全条件下执行一次中心手势并重新验证。 - 中心手势后出现规格面板时继续任务;仍无变化时返回稳定的点击无效果错误。 - 页面已变化但规格面板强证据不足时返回独立的面板证据不匹配错误及无敏感标量诊断。 - 精确规格已经选中时不重复点击;点击失败但新页面已显示精确选中时视为成功。 - 规格搜索只滚动唯一的规格面板容器,不选择全页其它最大滚动区域。 - 所有动作次数和等待时间有明确上限;歧义、无安全目标或验证失败均 fail-closed。 - 地址、创建订单和支付安全边界保持不变。 ## 验证计划 - Android 采购执行和无障碍驱动 JVM 单元测试。 - `android` 单元测试。 - Debug APK 构建。 - 仓库 Android 验证脚本(范围允许时)。 - 真机 PDD 页面需在同一设备、同一 Agent 版本和同一规则快照下另行验收;本工单不点击创建订单。 ## 风险 - PDD 自定义控件可能返回成功但不触发页面变化;中心手势必须严格限定唯一目标与有效边界。 - 手势可能命中覆盖层;必须依赖动作后强证据,失败即停止。 - 规格面板页面形态持续变化;不得通过放宽到相近文本或任意购买按钮解决。 ## 文档影响 有长期文档影响:需要更新 `Android-Agent-API-Contract` 与 `Business-Rules-and-Glossary`,记录规格动作受控手势兜底、后置验证、容器滚动及不可逆动作排除边界;按 Wiki-first 流程在线更新、回读 revision 后同步本地镜像。
Author
Owner

实施完成,等待验收

最终方案

  • openSpecPanel 对无障碍点击后的新页面执行强证据验证;页面结构完全无变化时,才对同一唯一安全规格入口执行一次中心手势并再次验证。
  • 将“页面已变化但面板证据不足”与“无障碍点击及手势均无效果”拆分为 PURCHASE_SPEC_PANEL_EVIDENCE_NOT_MATCHED、PURCHASE_SPEC_ENTRY_CLICK_NO_EFFECT。
  • selectSpec 先检查精确规格是否已选中;未选中时最多一次 ACTION_CLICK 加一次受控中心手势,且每次都重新定位并验证。
  • 规格搜索只滚动当前解析得到的唯一 specPanelContainer;Android 优先尝试容器节点滚动动作,再在容器边界内手势。
  • 中心手势策略固定拒绝地址、保存地址、创建/提交/确认订单、确认购买及支付/付款语义;地址、创建订单和核单流程未接入该兜底。

实现文件

  • android/app/src/main/java/cn/ilapage/goauto/agent/automation/PurchaseRehearsalExecutor.kt
  • android/app/src/main/java/cn/ilapage/goauto/agent/automation/GoAutoAccessibilityService.kt
  • android/app/src/test/java/cn/ilapage/goauto/agent/PurchaseRehearsalExecutorTest.kt
  • docs/03-business-rules-and-glossary.md
  • docs/08-agent-api-contract.md

验证结果

  • ./android/gradlew.bat -p android test:通过。
  • ./android/gradlew.bat -p android assembleDebug:通过。
  • ./scripts/verify.ps1 -Component android:通过(单元测试与 Debug APK 构建)。
  • ./android/gradlew.bat -p android testDebugUnitTest --rerun-tasks:通过,确认未依赖 Gradle 缓存。
  • python dev_scripts/harness.py check --strict:通过。
  • 受影响 Wiki 镜像定向 sync 与 sync --check:通过。
  • git diff --cached --check:通过。

测试覆盖:已选规格不重复点击、失败动作后的单次中心手势、手势后选中验证、两种动作均无效果、未知面板证据、精确规格面板容器滚动、不可逆/支付文字手势拒绝。

Wiki

  • Business-Rules-and-Glossary revision:c7f56f233263b3c83df7e31cf75c89c48ff24111
  • Android-Agent-API-Contract revision:a48b6a104c9b96834bbe122a226ba50baf8e4f93

同步时两页线上 Wiki 已包含此前尚未进入本地镜像的 #201/#205/#212/#213 长期事实;为保证镜像与对应 revision 完整一致,本提交按 Wiki-first 规则同步了页面当前完整正文,没有改动这些既有事实。

Git

  • 分支:feat/214-verified-purchase-actions
  • 提交:683aa9c (fix(agent): 验证采购规格点击并锁定面板滚动 (#214))
  • 已推送:origin/feat/214-verified-purchase-actions

未验证与风险

  • 未执行真机 PDD 规格入口/规格选中验收;需要同一设备、此 APK、同一采购规则快照验证。
  • 未修改真实地址、未点击创建订单、未执行支付。
  • 当前工单保持打开并等待用户验收。
## 实施完成,等待验收 ### 最终方案 - `openSpecPanel` 对无障碍点击后的新页面执行强证据验证;页面结构完全无变化时,才对同一唯一安全规格入口执行一次中心手势并再次验证。 - 将“页面已变化但面板证据不足”与“无障碍点击及手势均无效果”拆分为 `PURCHASE_SPEC_PANEL_EVIDENCE_NOT_MATCHED`、`PURCHASE_SPEC_ENTRY_CLICK_NO_EFFECT`。 - `selectSpec` 先检查精确规格是否已选中;未选中时最多一次 `ACTION_CLICK` 加一次受控中心手势,且每次都重新定位并验证。 - 规格搜索只滚动当前解析得到的唯一 `specPanelContainer`;Android 优先尝试容器节点滚动动作,再在容器边界内手势。 - 中心手势策略固定拒绝地址、保存地址、创建/提交/确认订单、确认购买及支付/付款语义;地址、创建订单和核单流程未接入该兜底。 ### 实现文件 - `android/app/src/main/java/cn/ilapage/goauto/agent/automation/PurchaseRehearsalExecutor.kt` - `android/app/src/main/java/cn/ilapage/goauto/agent/automation/GoAutoAccessibilityService.kt` - `android/app/src/test/java/cn/ilapage/goauto/agent/PurchaseRehearsalExecutorTest.kt` - `docs/03-business-rules-and-glossary.md` - `docs/08-agent-api-contract.md` ### 验证结果 - `./android/gradlew.bat -p android test`:通过。 - `./android/gradlew.bat -p android assembleDebug`:通过。 - `./scripts/verify.ps1 -Component android`:通过(单元测试与 Debug APK 构建)。 - `./android/gradlew.bat -p android testDebugUnitTest --rerun-tasks`:通过,确认未依赖 Gradle 缓存。 - `python dev_scripts/harness.py check --strict`:通过。 - 受影响 Wiki 镜像定向 `sync` 与 `sync --check`:通过。 - `git diff --cached --check`:通过。 测试覆盖:已选规格不重复点击、失败动作后的单次中心手势、手势后选中验证、两种动作均无效果、未知面板证据、精确规格面板容器滚动、不可逆/支付文字手势拒绝。 ### Wiki - `Business-Rules-and-Glossary` revision:`c7f56f233263b3c83df7e31cf75c89c48ff24111` - `Android-Agent-API-Contract` revision:`a48b6a104c9b96834bbe122a226ba50baf8e4f93` 同步时两页线上 Wiki 已包含此前尚未进入本地镜像的 #201/#205/#212/#213 长期事实;为保证镜像与对应 revision 完整一致,本提交按 Wiki-first 规则同步了页面当前完整正文,没有改动这些既有事实。 ### Git - 分支:`feat/214-verified-purchase-actions` - 提交:`683aa9c` (`fix(agent): 验证采购规格点击并锁定面板滚动 (#214)`) - 已推送:`origin/feat/214-verified-purchase-actions` ### 未验证与风险 - 未执行真机 PDD 规格入口/规格选中验收;需要同一设备、此 APK、同一采购规则快照验证。 - 未修改真实地址、未点击创建订单、未执行支付。 - 当前工单保持打开并等待用户验收。
Author
Owner

真机安装记录

  • 时间:2026-09-04 18:25:48(Asia/Shanghai)
  • 设备:PKG110(ADB serial 已脱敏不写入工单)
  • APK:#214 提交 683aa9c 构建的 Debug APK
  • 安装方式:adb install -r,结果 Success;未清除应用数据。
  • 安装后版本:versionCode=52、versionName=0.9.39。
  • 安装后只读检查:包已存在,但 GoAuto 无障碍服务当前未列入系统已启用服务;需要手机操作员在系统设置中人工重新开启。
  • 未启动采购任务、未修改地址、未创建订单、未支付。
## 真机安装记录 - 时间:2026-09-04 18:25:48(Asia/Shanghai) - 设备:`PKG110`(ADB serial 已脱敏不写入工单) - APK:#214 提交 `683aa9c` 构建的 Debug APK - 安装方式:`adb install -r`,结果 `Success`;未清除应用数据。 - 安装后版本:`versionCode=52`、`versionName=0.9.39`。 - 安装后只读检查:包已存在,但 GoAuto 无障碍服务当前未列入系统已启用服务;需要手机操作员在系统设置中人工重新开启。 - 未启动采购任务、未修改地址、未创建订单、未支付。
Sign in to join this conversation.
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: OPC/goauto#214