45f739a8a31e5e6050d40f08ace81ce5b82ae845
Reviewer cross-check of2ce59ebon real dumps found a Samsung sample where the true bottom bar is a label-less 31px FrameLayout whose only text node is zero-size ([0,0][0,0]). A whole-panel leaf scan fell through to the next lowest labelled leaf, which lives in the PAYMENT-METHOD row directly above the bottom bar ("使用#微信支付,更换先用后付可0元下单"), and the climb-to-clickable-ancestor landed the click on "change payment method" instead of the order button. That must never happen. finalSubmitTargets is now a strict two-step "row, then leaf" pick instead of a single whole-panel leaf scan: 1. Row: among visible/enabled/non-zero-size CLICKABLE nodes inside the recognized panel's container with height <= 30% of screen height (the guard from2bc624f), pick the one with the lowest bottom edge; ties go to the rightmost. This row, and only this row, may hold the order button. If its own subtree matches a payment-method alias (textAliases.specPanel.paymentAreaAliases: 微信支付/先用后付/支付方式) or SUBMIT_TARGET_BLOCKED_MARKERS, fail explicitly (outcome=row_blocked) - never fall back to a higher row. 2. Leaf: within that row's own subtree (or the row itself), among visible/non-zero-size nodes with a non-blank own label whose nearest clickable ancestor is EXACTLY that row, pick the bottom-right-most one (unchanged rationale from2ce59eb: PurchaseUiDriver.clickFresh re-finds by preferredOrDescendantLabel()+className+center±32 before climbing to the nearest clickable ancestor, so the target must carry a real label). If the row has no such leaf, fail explicitly (outcome=bottom_row_unlabelled) - never fall back to a higher row either. hasFinalSavedAddressEvidence, finalConfirmation and submitOrderOnce still all consume this one finalSubmitTargets. Tests: SpecPanelFixtures.sheet(Sheet(submit = "hidden")) already models the Samsung shape (31px hidden bottom bar above a real payment-method row) - added a test asserting it now fails explicitly with no click, verifying the payment row is never touched. Added a second test where the payment row is itself the bottom-most clickable row (no submit region at all) and must be rejected by its own alias match. Fixed readySheet() (used by the address-save-wait test) to stop compounding liveShapedSheet()'s own hidden 31px placeholder with a separate real submit button - the two used to tie and could flip which one the rightmost tie-break picked; it now builds the same shape directly with submit="none" so "r/final" is the sole, unambiguous bottom row. Updated one diagnostic key assertion (tie= -> rowTie=) for the row-level tie-break. Every other #335 test (legacy 提交订单, 570 structure + ReFindingDriver re-find/climb, payment-word blocked, outside-panel-container, no-determinable-container) passed unmodified. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NTDbDcwbDw1TSAcE6wfh2F
GoAuto 移动采集管理平台
GoAuto 使用 go-admin、go-admin-ui 和 Android Portal/Agent 跑通 PDD 商品采集闭环:人工添加 PDD 链接、创建采集规则、创建任务、由 Android 执行并在任务详情查看结构化结果。
当前 MVP 只包含 PDD 商品、采集规则、采集任务、Android 执行和任务详情结果。顺云宝、Shopee、采购、批量任务、规则发布流程、全局停机和实时屏幕均不在当前范围。
阅读入口
旧版 ADB/Portal 验证代码、日志和诊断资料已归档到本机 demo/,该目录不进入 Git。
当前状态
- 需求和技术边界已确认。
- Harness Coding 文档和工单已建立。
- 服务端与 Android 端为可交互 HTML 原型。
server/已固定导入 go-adminv2.3.0。web/已固定导入 go-admin-uiv3.0.0。android/已建立 Kotlin/SDK 34 Agent 骨架。- 最小闭环 8 张业务表、迁移和唯一约束测试已经落地。
- 设备首次自注册、Token 认证、停用和吊销接口已经落地。
- Token 心跳、在线/离线、空闲/忙碌和离线任务失败已经落地。
验证
.\scripts\verify.ps1 -Component all
也可以把 all 改为 server、web 或 android 单独验证。
Languages
HTML
49.6%
Go
27.2%
Kotlin
10.3%
Vue
7.7%
JavaScript
2.2%
Other
2.9%