Agent 当前 PDD 商品页临时采集与分享链接识别(先行原型) #101

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

所属与来源

  • 父 MVP:#86 Android Agent 设备端任务中心与现场运维。
  • 关联:#2 PDD 商品采集最小闭环;#90 当前设备任务记录;#100 Agent 四 Tab 信息精简。
  • 来源:用户于 2026-08-26 提出:在 PDD App 已人工打开某个商品详情页时,切回 Agent,在采集 Tab 点击“采集”,由 Admin 创建临时采集任务,Agent 按常规规则采集商品;成功后通过 PDD 分享/复制链接取得 goods_id,组装标准 URL 并提交 Admin。典型场景是原 PDD 商品已售罄,采购员人工找到相似商品后快速补录。
  • 用户已确认采用评审方案,并要求先建立工单。
  • 类型:Android / Server / Agent 临时采集 / PDD 分享链接识别。
  • 当前阶段:先完成 Agent QuantUX 原型、本地 HTML 审核快照,以及临时任务/API/数据方案;用户明确审核通过前不得编写 Android、Server、数据库生产代码。

目标

让现场人员无需先在 Admin 手工录入未知 goods_id 或 PDD URL,即可从当前已打开的 PDD 商品详情页发起一次受控采集,并把结构化商品数据、goods_id 和标准商品 URL 一并提交到 Admin,降低已售罄商品寻找替代商品后的录入成本。

已确认用户流程

  1. 操作员在 PDD App 人工找到并停留在目标商品详情页。
  2. 切回 Agent 的“采集”Tab。
  3. 在编号搜索按钮右侧点击紧凑的“采集”按钮。
  4. Agent 展示确认页/确认框,说明将采集当前 PDD 商品,不要求输入链接;用户确认后请求 Admin 创建绑定当前设备的临时采集任务。
  5. 服务端校验设备在线、空闲、无活动采集/采购任务且具备所需能力;创建成功后返回任务编号和规则快照。
  6. Agent 返回当前 PDD 商品页,先验证仍是唯一、可信的商品详情页,直接执行采集规则;不得通过浏览器重新打开未知链接。
  7. Agent 通过“分享”→“复制链接”取得本次商品分享文本,解析或交由服务端解析 goods_id。
  8. 采集成功时,把结构化商品信息、goods_id、标准 URL 和任务结果一起提交 Admin。
  9. Agent 按现有任务结束、Outbox、串行调度和空闲返回机制处理结果。

交互设计要求

  • 在采集 Tab 现有编号搜索按钮右侧增加“采集”按钮,保持紧凑且触控区域不少于 48dp。
  • 不要求勾选历史任务;按钮语义为“采集当前 PDD 页面”,不能与“重新采集已有任务”混淆。
  • 点击后必须有明确确认,至少说明:
    • 请先在 PDD 打开目标商品详情页;
    • 采集会读取当前商品资料和分享链接;
    • 不会采购、创建订单或支付。
  • 覆盖正常、设备忙、无障碍未开启、服务未连接、任务创建失败、当前页不是商品详情、分享入口缺失、复制链接失败、剪贴板不可用、链接无效、采集部分完成和成功状态。
  • 成功页展示新任务编号、goods_id 和提交结果;不展示原始分享文案、控件树或截图。
  • 复用 Agent QuantUX App及 #100 最新确认后的四 Tab 布局;不得覆盖既有原型版本。
  • 完整原型必须导出至 prototypes/<本工单号>/v1/index.html,资源使用相对路径并可离线浏览。

临时任务与服务端方案

  • 临时采集仍属于标准采集任务,复用设备租约、规则快照、串行互斥、状态机、结果提交和 Outbox;通过明确的来源/模式标记区分“当前页面发起”,不另造一套执行引擎。
  • 创建时未知 goods_id/URL,因此只能保存创建请求所需的最小事实:任务编号、当前设备、来源、规则快照、状态和审计时间;不得伪造 URL 快照。
  • 临时任务必须固定分派给发起请求的当前设备,不允许其他设备领取。
  • 最终成功或部分完成前必须取得唯一有效 goods_id,并形成标准 URL:
    https://mobile.yangkeduo.com/goods.html?goods_id={goods_id}
  • 服务端在最终提交事务中校验并保存任务身份,同时创建或复用相同 goods_id 的 PDD 商品档案,并应用现有 PDD 商品覆盖规则;具体字段约束、唯一键冲突和幂等键在实施前写入 API/数据设计。
  • 发现相同 goods_id 时不得创建重复 PDD 商品。
  • 本功能不会自动替换原已售罄 PDD 商品,也不会自动修改虾皮→PDD 关联;后续由采购员在现有商品/映射页面人工确认。
  • 同一设备已有活动采集或采购任务时拒绝创建,并用普通人能理解的文字提示。
  • 连续点击和网络重放必须通过请求 ID 幂等,不能创建多个临时任务。

补充决策(2026-08-26 用户确认)

  • 返回当前 PDD 页面:开始前先检查服务地址、无障碍和近期 PDD 商品详情页证据。任务创建成功后,Agent 仅把自身任务移到后台并恢复此前的 PDD 任务栈;不得从桌面重新启动 PDD,也不得通过浏览器打开链接。恢复后重新核验前台包名、Activity 和商品详情页强证据,不满足即失败。
  • 原子创建并占槽:Agent 先取得采集/采购共用的本地互斥锁;服务端在同一事务内校验设备在线、空闲和能力,创建标准“当前页面”采集任务、绑定发起设备、建立活动租约并返回任务及规则快照。普通轮询在此窗口内不得再领取其他任务。客户端使用 requestId 幂等,重复点击或网络重放只返回同一任务。
  • 默认采集规则:管理端必须指定一条已启用且可用的“Agent 手动采集默认规则”。服务端创建任务时固化该规则快照;未配置、已删除、已停用或不兼容时不创建任务,并提示“请先配置 Agent 手动采集规则”。
  • 先识别商品,再采集资料:恢复并验证 PDD 商品页后,先执行“分享→复制链接”,由服务端解析和确认 goods_id;商品身份无法确认时尽早失败,不继续采集或写入商品。身份确认后再采集标题、店铺、规格和价格并提交。分享面板无论成功失败都应尽力关闭。
  • 失败与释放:回到 PDD 失败、用户离开商品页、Agent 被停止、分享内容无效、超时或规则失败时,任务明确失败并幂等释放设备租约和本地互斥锁,默认不自动重试。最终结果继续复用 Outbox;失败清理不得造成设备长期忙碌。
  • 重复商品处理:相同 goods_id 复用现有 PDD 商品并按现有“最新结果覆盖”语义更新;不存在时创建。不得产生重复商品,不自动替换旧 PDD 商品,也不修改虾皮关联。
  • 来源展示:任务列表和详情显示来源“Agent 当前页面”,它只是来源/模式,不新增任务状态。
  • 数据兼容门禁:当前阶段只输出临时任务、API 和数据草案。未知 goods_id 创建任务涉及的 URL/goods_id 可空约束及最终提交事务必须在生产实施前明确;如需数据库迁移,须再次取得用户确认。
  • 设计基线:以 #100 已确认并实现的 Agent 四 Tab 布局(提交 a181b2a)为基线,不覆盖 #100 的历史原型。

分享链接与 goods_id 方案

参考本地 D:/chengma/cmroubao_old 已验证思路:

  • 无障碍规则负责在可信商品详情页唯一定位“分享”,在可信分享面板唯一定位“复制链接”,并关闭分享面板。
  • “分享/复制链接”动作纳入服务端集中管理的采集规则或受控 Agent 动作,不把易变页面流程散落在临时采集业务代码中。
  • Android 记录复制动作时间,启动短暂的前台中转 Activity 后读取剪贴板,拒绝旧剪贴板、多个条目、空内容和超长内容。
  • Agent 不记录或上传与本次采集无关的剪贴板内容。
  • 服务端集中解析分享文本和短链接:只接受 HTTPS,域名白名单限定 p.pinduoduo.com 与 mobile.yangkeduo.com;逐跳校验有限重定向、限制响应大小和超时,最终提取纯数字 goods_id。
  • 如果 Agent 已从直链可靠取得 goods_id,也必须由服务端执行同一格式与一致性校验。
  • 分享链接 goods_id 与页面/最终提交中的其他身份信息冲突时明确失败,不覆盖已有商品。
  • 失败原因至少区分:分享入口不可用、复制链接不可用、剪贴板读取受限、分享内容无效、短链解析网络失败、goods_id 缺失、身份冲突。

参考代码仅作为实现证据,不直接整模块复制:

  • PinduoduoClipboardRelay.kt
  • PinduoduoSharedProductLinkResolver.kt
  • AndroidPinduoduoCandidateDriver.kt
  • BuyerAccessibilityService.kt

API 与数据草案(v1,待原型审核后实施)

Agent 接口

  1. POST /api/agent/v1/current-page-collection-tasks

    • Device Token 确定当前设备;请求体仅含 requestId。
    • 服务端锁定设备行并在同一事务内检查在线、空闲、跨采集/采购活动槽、能力和默认规则,创建来源为 agent_current_page 的标准采集任务,固定设备、固化规则快照、直接进入 running、建立租约并返回任务载荷。
    • 该接口等价于本模式专用的“创建+领取+开始”,故 Agent 不再调用普通 next → claim → start;这样正常轮询没有抢占窗口。
    • 相同设备和 requestId 重放返回同一任务,不续租、不创建第二条任务。
  2. POST /api/agent/v1/current-page-collection-tasks/{taskId}/identify

    • 请求体为 requestId 和从新鲜剪贴板分享文本中唯一提取出的 shareUrl;Android 不上传整段分享文案或其他剪贴板内容。
    • 服务端只接受白名单 HTTPS URL,逐跳校验并解析 goods_id;请求体和重定向明细不得进入操作日志。
    • 在事务中按 goods_id 查找或创建 PDD 商品、把 pddProductId、标准 URL 和 goods_id 快照绑定到任务;若同商品已有活动采集任务或身份冲突则失败并结束当前任务。
    • 相同 requestId 幂等返回同一识别结果;不同身份不得覆盖首次已确认身份。
  3. 识别成功后继续复用:

    • POST /api/agent/v1/tasks/{taskId}/result 提交结构化结果;
    • POST /api/agent/v1/tasks/{taskId}/fail 提交失败。
    • 结果接口要求任务已经完成身份绑定,且提交中的 goods_id 与任务快照一致;同一事务覆盖 PDD 商品最新资料并重建任务结果子表。
    • 成功、部分完成和失败都幂等释放租约与设备执行槽,默认不重试。

最小数据变更

  • collection_task.pdd_product_id、url_snapshot、goods_id_snapshot 改为只允许 agent_current_page 且尚未完成身份识别的运行中任务暂时为空;普通采集任务仍强制非空。
  • collection_task 增加受约束的来源字段,当前仅 admin 与 agent_current_page;列表/详情把后者显示为“Agent 当前页面”,不新增状态。
  • 商品活动唯一槽只有在任务已绑定 pdd_product_id 后参与;当前页面任务创建时先由设备运行槽防并发,identify 事务绑定商品时再检查并占商品活动槽。
  • 增加单行 Agent 手动采集设置,保存默认 collection_rule_id。运行时仍检查规则存在、未删除、已启用且能力兼容;规则快照一经任务创建不可变。
  • 不新增临时任务表、不保存原始分享文案、控件树或截图;结构化结果继续使用既有任务结果子表。
  • 数据迁移必须同时补充状态/来源检查约束、MySQL 8.4 唯一索引兼容测试、旧数据回填为 admin 和回滚方案。执行迁移前再次等待用户确认。

失败语义

  • 创建前失败不产生任务,例如:DEVICE_BUSY → “设备正在执行任务,请稍后再试”;AGENT_MANUAL_RULE_NOT_CONFIGURED → “请先配置 Agent 手动采集规则”。
  • 创建后失败必须落任务失败并释放设备,例如:CURRENT_PDD_PAGE_NOT_FOUND → “没有找到商品详情页”;PDD_SHARE_UNAVAILABLE / PDD_SHARE_LINK_INVALID → “无法识别商品链接”。
  • 服务端保留稳定错误码供排错,Agent 默认展示简短中文原因和下一步;不把堆栈、HTTP 细节或原始控件文字展示给采购员。

安全与能力边界

  • 不打开浏览器、不自动搜索或选择相似商品;相似商品由人工找到。
  • 不自动替换现有 PDD 商品或虾皮关联。
  • 不创建采购任务、不选择采购规格、不修改地址、不创建订单,永久禁止支付。
  • 不使用 OCR/VLM,不猜测 goods_id,不把相近商品当作目标。
  • 不保存原始控件树、截图、原始剪贴板内容或完整分享文案。
  • 任务执行必须携带 taskId、deviceId 和 ruleSnapshot,一台设备仍只串行执行一个任务。
  • 找不到唯一控件、登录失效、验证码、风控或人机验证时明确失败。
  • 真机验证只能使用用户明确授权的测试商品和设备。

前置依赖与并行性

  • 依赖 #2 已有采集任务、规则、PDD 商品写回和结果提交能力。
  • 依赖 #86/#90 已有 Agent 采集 Tab、当前设备身份及任务详情能力。
  • UI 以 #100 最新获批布局为基线;可先独立制作原型,但生产实施应在 #100 相关界面变更稳定后合并。
  • 与 #92 Outbox 可并行设计;最终结果提交必须复用其已实现契约,不重复建设队列。
  • 与采购工单无直接依赖,不得耦合采购流程。

原型与实施门禁

第一阶段:设计

  • 更新 QuantUX Agent 原型,覆盖入口、确认、执行、成功及主要失败状态。
  • 导出本地 HTML 审核快照并验证入口、交互和资源完整性。
  • 补充临时任务创建、分享解析、最终提交的 API/数据草案。
  • 用户明确审核原型与范围通过后,才能进入生产实施。

第二阶段:生产实施(审核后)

  • Server:临时任务创建、资格/幂等校验、PDD 分享链接解析、最终事务写回。
  • Android:采集 Tab 入口、确认与状态反馈、当前页面任务执行、前台剪贴板中转、结果提交。
  • 规则:分享、复制链接、关闭面板的受控动作和错误映射。
  • 自动化测试、服务端契约测试及获授权真机验证。

验收标准

设计验收

  • 采集 Tab 有清晰且紧凑的“采集”入口,不与历史任务重新采集混淆。
  • 可演示确认、创建中、执行中、成功、部分完成及主要失败状态。
  • 成功状态展示任务编号、goods_id 和提交结果。
  • 原型不包含采购、创建订单或支付能力。
  • 本地 HTML 可离线浏览,用户明确审核通过。

后续生产验收

  • 当前设备在线空闲时可幂等创建固定分派的临时采集任务。
  • Agent 不重开浏览器链接,能验证并采集当前 PDD 商品详情页。
  • 能安全取得本次复制的分享内容,并由服务端解析、校验唯一 goods_id。
  • 成功/部分完成结果写入唯一 PDD 商品档案和任务详情;相同 goods_id 不产生重复商品。
  • 不自动替换旧商品或虾皮关联。
  • 忙碌、页面错误、链接无效、网络失败及身份冲突均明确失败且不误写数据。
  • 重复请求、断网恢复和结果重放不产生重复任务或重复商品。
  • 不保存原始控件树、截图或无关剪贴板内容。
  • Android、Server 与共享契约测试通过;真机验证另获授权并记录实际覆盖范围。

验证计划

  • 原型:在线入口及本地 HTML 的导航、确认、状态、异常和离线资源检查。
  • Server:创建资格、设备绑定、活动槽、请求幂等、域名/重定向/响应大小限制、goods_id 唯一冲突及事务回滚测试。
  • Android:前台剪贴板新鲜度、多条/空/旧内容、Activity 生命周期、分享面板返回、规则失败映射和 Outbox 重放测试。
  • 真机:至少在一台已授权设备验证直链与 PDD 短链各一次;不执行采购与支付。

风险

  • PDD 分享面板或“复制链接”文案变化:通过服务端规则版本和唯一页面证据控制,失败时停止。
  • Android 新版本限制后台剪贴板:使用短暂、可见生命周期内的前台中转 Activity,并做新鲜度校验。
  • 恶意或异常短链接造成 SSRF/大响应:服务端严格 HTTPS 主机白名单、逐跳校验、有限重定向、大小和超时限制。
  • 当前页被用户切换:执行前和关键动作后重复核验 PDD 包名、页面和身份,冲突即失败。
  • 未知 goods_id 的临时任务会触及既有 URL 快照约束:实施前必须先确认迁移与兼容策略;数据库迁移属于高风险,执行时再次等待用户确认。

文档影响

  • 当前建单和原型阶段无长期事实变化,跳过 Wiki。
  • 生产实施后预计更新:
    • Android Agent API 契约;
    • 业务规则与术语;
    • Android 运行/排错说明;
    • 架构和采集任务数据约束。
  • 若最终实现未改变长期契约,须在工单中说明原因后跳过 Wiki。
## 所属与来源 - 父 MVP:#86 Android Agent 设备端任务中心与现场运维。 - 关联:#2 PDD 商品采集最小闭环;#90 当前设备任务记录;#100 Agent 四 Tab 信息精简。 - 来源:用户于 2026-08-26 提出:在 PDD App 已人工打开某个商品详情页时,切回 Agent,在采集 Tab 点击“采集”,由 Admin 创建临时采集任务,Agent 按常规规则采集商品;成功后通过 PDD 分享/复制链接取得 goods_id,组装标准 URL 并提交 Admin。典型场景是原 PDD 商品已售罄,采购员人工找到相似商品后快速补录。 - 用户已确认采用评审方案,并要求先建立工单。 - 类型:Android / Server / Agent 临时采集 / PDD 分享链接识别。 - 当前阶段:**先完成 Agent QuantUX 原型、本地 HTML 审核快照,以及临时任务/API/数据方案;用户明确审核通过前不得编写 Android、Server、数据库生产代码。** ## 目标 让现场人员无需先在 Admin 手工录入未知 goods_id 或 PDD URL,即可从当前已打开的 PDD 商品详情页发起一次受控采集,并把结构化商品数据、goods_id 和标准商品 URL 一并提交到 Admin,降低已售罄商品寻找替代商品后的录入成本。 ## 已确认用户流程 1. 操作员在 PDD App 人工找到并停留在目标商品详情页。 2. 切回 Agent 的“采集”Tab。 3. 在编号搜索按钮右侧点击紧凑的“采集”按钮。 4. Agent 展示确认页/确认框,说明将采集当前 PDD 商品,不要求输入链接;用户确认后请求 Admin 创建绑定当前设备的临时采集任务。 5. 服务端校验设备在线、空闲、无活动采集/采购任务且具备所需能力;创建成功后返回任务编号和规则快照。 6. Agent 返回当前 PDD 商品页,先验证仍是唯一、可信的商品详情页,直接执行采集规则;**不得通过浏览器重新打开未知链接**。 7. Agent 通过“分享”→“复制链接”取得本次商品分享文本,解析或交由服务端解析 goods_id。 8. 采集成功时,把结构化商品信息、goods_id、标准 URL 和任务结果一起提交 Admin。 9. Agent 按现有任务结束、Outbox、串行调度和空闲返回机制处理结果。 ## 交互设计要求 - 在采集 Tab 现有编号搜索按钮右侧增加“采集”按钮,保持紧凑且触控区域不少于 48dp。 - 不要求勾选历史任务;按钮语义为“采集当前 PDD 页面”,不能与“重新采集已有任务”混淆。 - 点击后必须有明确确认,至少说明: - 请先在 PDD 打开目标商品详情页; - 采集会读取当前商品资料和分享链接; - 不会采购、创建订单或支付。 - 覆盖正常、设备忙、无障碍未开启、服务未连接、任务创建失败、当前页不是商品详情、分享入口缺失、复制链接失败、剪贴板不可用、链接无效、采集部分完成和成功状态。 - 成功页展示新任务编号、goods_id 和提交结果;不展示原始分享文案、控件树或截图。 - 复用 Agent QuantUX App及 #100 最新确认后的四 Tab 布局;不得覆盖既有原型版本。 - 完整原型必须导出至 `prototypes/<本工单号>/v1/index.html`,资源使用相对路径并可离线浏览。 ## 临时任务与服务端方案 - 临时采集仍属于标准采集任务,复用设备租约、规则快照、串行互斥、状态机、结果提交和 Outbox;通过明确的来源/模式标记区分“当前页面发起”,不另造一套执行引擎。 - 创建时未知 goods_id/URL,因此只能保存创建请求所需的最小事实:任务编号、当前设备、来源、规则快照、状态和审计时间;不得伪造 URL 快照。 - 临时任务必须固定分派给发起请求的当前设备,不允许其他设备领取。 - 最终成功或部分完成前必须取得唯一有效 goods_id,并形成标准 URL: `https://mobile.yangkeduo.com/goods.html?goods_id={goods_id}` - 服务端在最终提交事务中校验并保存任务身份,同时创建或复用相同 goods_id 的 PDD 商品档案,并应用现有 PDD 商品覆盖规则;具体字段约束、唯一键冲突和幂等键在实施前写入 API/数据设计。 - 发现相同 goods_id 时不得创建重复 PDD 商品。 - 本功能不会自动替换原已售罄 PDD 商品,也不会自动修改虾皮→PDD 关联;后续由采购员在现有商品/映射页面人工确认。 - 同一设备已有活动采集或采购任务时拒绝创建,并用普通人能理解的文字提示。 - 连续点击和网络重放必须通过请求 ID 幂等,不能创建多个临时任务。 ## 补充决策(2026-08-26 用户确认) - **返回当前 PDD 页面**:开始前先检查服务地址、无障碍和近期 PDD 商品详情页证据。任务创建成功后,Agent 仅把自身任务移到后台并恢复此前的 PDD 任务栈;不得从桌面重新启动 PDD,也不得通过浏览器打开链接。恢复后重新核验前台包名、Activity 和商品详情页强证据,不满足即失败。 - **原子创建并占槽**:Agent 先取得采集/采购共用的本地互斥锁;服务端在同一事务内校验设备在线、空闲和能力,创建标准“当前页面”采集任务、绑定发起设备、建立活动租约并返回任务及规则快照。普通轮询在此窗口内不得再领取其他任务。客户端使用 requestId 幂等,重复点击或网络重放只返回同一任务。 - **默认采集规则**:管理端必须指定一条已启用且可用的“Agent 手动采集默认规则”。服务端创建任务时固化该规则快照;未配置、已删除、已停用或不兼容时不创建任务,并提示“请先配置 Agent 手动采集规则”。 - **先识别商品,再采集资料**:恢复并验证 PDD 商品页后,先执行“分享→复制链接”,由服务端解析和确认 goods_id;商品身份无法确认时尽早失败,不继续采集或写入商品。身份确认后再采集标题、店铺、规格和价格并提交。分享面板无论成功失败都应尽力关闭。 - **失败与释放**:回到 PDD 失败、用户离开商品页、Agent 被停止、分享内容无效、超时或规则失败时,任务明确失败并幂等释放设备租约和本地互斥锁,默认不自动重试。最终结果继续复用 Outbox;失败清理不得造成设备长期忙碌。 - **重复商品处理**:相同 goods_id 复用现有 PDD 商品并按现有“最新结果覆盖”语义更新;不存在时创建。不得产生重复商品,不自动替换旧 PDD 商品,也不修改虾皮关联。 - **来源展示**:任务列表和详情显示来源“Agent 当前页面”,它只是来源/模式,不新增任务状态。 - **数据兼容门禁**:当前阶段只输出临时任务、API 和数据草案。未知 goods_id 创建任务涉及的 URL/goods_id 可空约束及最终提交事务必须在生产实施前明确;如需数据库迁移,须再次取得用户确认。 - **设计基线**:以 #100 已确认并实现的 Agent 四 Tab 布局(提交 `a181b2a`)为基线,不覆盖 #100 的历史原型。 ## 分享链接与 goods_id 方案 参考本地 `D:/chengma/cmroubao_old` 已验证思路: - 无障碍规则负责在可信商品详情页唯一定位“分享”,在可信分享面板唯一定位“复制链接”,并关闭分享面板。 - “分享/复制链接”动作纳入服务端集中管理的采集规则或受控 Agent 动作,不把易变页面流程散落在临时采集业务代码中。 - Android 记录复制动作时间,启动短暂的前台中转 Activity 后读取剪贴板,拒绝旧剪贴板、多个条目、空内容和超长内容。 - Agent 不记录或上传与本次采集无关的剪贴板内容。 - 服务端集中解析分享文本和短链接:只接受 HTTPS,域名白名单限定 `p.pinduoduo.com` 与 `mobile.yangkeduo.com`;逐跳校验有限重定向、限制响应大小和超时,最终提取纯数字 goods_id。 - 如果 Agent 已从直链可靠取得 goods_id,也必须由服务端执行同一格式与一致性校验。 - 分享链接 goods_id 与页面/最终提交中的其他身份信息冲突时明确失败,不覆盖已有商品。 - 失败原因至少区分:分享入口不可用、复制链接不可用、剪贴板读取受限、分享内容无效、短链解析网络失败、goods_id 缺失、身份冲突。 参考代码仅作为实现证据,不直接整模块复制: - `PinduoduoClipboardRelay.kt` - `PinduoduoSharedProductLinkResolver.kt` - `AndroidPinduoduoCandidateDriver.kt` - `BuyerAccessibilityService.kt` ## API 与数据草案(v1,待原型审核后实施) ### Agent 接口 1. `POST /api/agent/v1/current-page-collection-tasks` - Device Token 确定当前设备;请求体仅含 `requestId`。 - 服务端锁定设备行并在同一事务内检查在线、空闲、跨采集/采购活动槽、能力和默认规则,创建来源为 `agent_current_page` 的标准采集任务,固定设备、固化规则快照、直接进入 `running`、建立租约并返回任务载荷。 - 该接口等价于本模式专用的“创建+领取+开始”,故 Agent 不再调用普通 `next → claim → start`;这样正常轮询没有抢占窗口。 - 相同设备和 `requestId` 重放返回同一任务,不续租、不创建第二条任务。 2. `POST /api/agent/v1/current-page-collection-tasks/{taskId}/identify` - 请求体为 `requestId` 和从新鲜剪贴板分享文本中唯一提取出的 `shareUrl`;Android 不上传整段分享文案或其他剪贴板内容。 - 服务端只接受白名单 HTTPS URL,逐跳校验并解析 goods_id;请求体和重定向明细不得进入操作日志。 - 在事务中按 goods_id 查找或创建 PDD 商品、把 `pddProductId`、标准 URL 和 goods_id 快照绑定到任务;若同商品已有活动采集任务或身份冲突则失败并结束当前任务。 - 相同 `requestId` 幂等返回同一识别结果;不同身份不得覆盖首次已确认身份。 3. 识别成功后继续复用: - `POST /api/agent/v1/tasks/{taskId}/result` 提交结构化结果; - `POST /api/agent/v1/tasks/{taskId}/fail` 提交失败。 - 结果接口要求任务已经完成身份绑定,且提交中的 goods_id 与任务快照一致;同一事务覆盖 PDD 商品最新资料并重建任务结果子表。 - 成功、部分完成和失败都幂等释放租约与设备执行槽,默认不重试。 ### 最小数据变更 - `collection_task.pdd_product_id`、`url_snapshot`、`goods_id_snapshot` 改为只允许 `agent_current_page` 且尚未完成身份识别的运行中任务暂时为空;普通采集任务仍强制非空。 - `collection_task` 增加受约束的来源字段,当前仅 `admin` 与 `agent_current_page`;列表/详情把后者显示为“Agent 当前页面”,不新增状态。 - 商品活动唯一槽只有在任务已绑定 `pdd_product_id` 后参与;当前页面任务创建时先由设备运行槽防并发,identify 事务绑定商品时再检查并占商品活动槽。 - 增加单行 Agent 手动采集设置,保存默认 `collection_rule_id`。运行时仍检查规则存在、未删除、已启用且能力兼容;规则快照一经任务创建不可变。 - 不新增临时任务表、不保存原始分享文案、控件树或截图;结构化结果继续使用既有任务结果子表。 - 数据迁移必须同时补充状态/来源检查约束、MySQL 8.4 唯一索引兼容测试、旧数据回填为 `admin` 和回滚方案。执行迁移前再次等待用户确认。 ### 失败语义 - 创建前失败不产生任务,例如:`DEVICE_BUSY` → “设备正在执行任务,请稍后再试”;`AGENT_MANUAL_RULE_NOT_CONFIGURED` → “请先配置 Agent 手动采集规则”。 - 创建后失败必须落任务失败并释放设备,例如:`CURRENT_PDD_PAGE_NOT_FOUND` → “没有找到商品详情页”;`PDD_SHARE_UNAVAILABLE` / `PDD_SHARE_LINK_INVALID` → “无法识别商品链接”。 - 服务端保留稳定错误码供排错,Agent 默认展示简短中文原因和下一步;不把堆栈、HTTP 细节或原始控件文字展示给采购员。 ## 安全与能力边界 - 不打开浏览器、不自动搜索或选择相似商品;相似商品由人工找到。 - 不自动替换现有 PDD 商品或虾皮关联。 - 不创建采购任务、不选择采购规格、不修改地址、不创建订单,永久禁止支付。 - 不使用 OCR/VLM,不猜测 goods_id,不把相近商品当作目标。 - 不保存原始控件树、截图、原始剪贴板内容或完整分享文案。 - 任务执行必须携带 `taskId`、`deviceId` 和 `ruleSnapshot`,一台设备仍只串行执行一个任务。 - 找不到唯一控件、登录失效、验证码、风控或人机验证时明确失败。 - 真机验证只能使用用户明确授权的测试商品和设备。 ## 前置依赖与并行性 - 依赖 #2 已有采集任务、规则、PDD 商品写回和结果提交能力。 - 依赖 #86/#90 已有 Agent 采集 Tab、当前设备身份及任务详情能力。 - UI 以 #100 最新获批布局为基线;可先独立制作原型,但生产实施应在 #100 相关界面变更稳定后合并。 - 与 #92 Outbox 可并行设计;最终结果提交必须复用其已实现契约,不重复建设队列。 - 与采购工单无直接依赖,不得耦合采购流程。 ## 原型与实施门禁 ### 第一阶段:设计 - 更新 QuantUX Agent 原型,覆盖入口、确认、执行、成功及主要失败状态。 - 导出本地 HTML 审核快照并验证入口、交互和资源完整性。 - 补充临时任务创建、分享解析、最终提交的 API/数据草案。 - **用户明确审核原型与范围通过后,才能进入生产实施。** ### 第二阶段:生产实施(审核后) - Server:临时任务创建、资格/幂等校验、PDD 分享链接解析、最终事务写回。 - Android:采集 Tab 入口、确认与状态反馈、当前页面任务执行、前台剪贴板中转、结果提交。 - 规则:分享、复制链接、关闭面板的受控动作和错误映射。 - 自动化测试、服务端契约测试及获授权真机验证。 ## 验收标准 ### 设计验收 - [ ] 采集 Tab 有清晰且紧凑的“采集”入口,不与历史任务重新采集混淆。 - [ ] 可演示确认、创建中、执行中、成功、部分完成及主要失败状态。 - [ ] 成功状态展示任务编号、goods_id 和提交结果。 - [ ] 原型不包含采购、创建订单或支付能力。 - [ ] 本地 HTML 可离线浏览,用户明确审核通过。 ### 后续生产验收 - [ ] 当前设备在线空闲时可幂等创建固定分派的临时采集任务。 - [ ] Agent 不重开浏览器链接,能验证并采集当前 PDD 商品详情页。 - [ ] 能安全取得本次复制的分享内容,并由服务端解析、校验唯一 goods_id。 - [ ] 成功/部分完成结果写入唯一 PDD 商品档案和任务详情;相同 goods_id 不产生重复商品。 - [ ] 不自动替换旧商品或虾皮关联。 - [ ] 忙碌、页面错误、链接无效、网络失败及身份冲突均明确失败且不误写数据。 - [ ] 重复请求、断网恢复和结果重放不产生重复任务或重复商品。 - [ ] 不保存原始控件树、截图或无关剪贴板内容。 - [ ] Android、Server 与共享契约测试通过;真机验证另获授权并记录实际覆盖范围。 ## 验证计划 - 原型:在线入口及本地 HTML 的导航、确认、状态、异常和离线资源检查。 - Server:创建资格、设备绑定、活动槽、请求幂等、域名/重定向/响应大小限制、goods_id 唯一冲突及事务回滚测试。 - Android:前台剪贴板新鲜度、多条/空/旧内容、Activity 生命周期、分享面板返回、规则失败映射和 Outbox 重放测试。 - 真机:至少在一台已授权设备验证直链与 PDD 短链各一次;不执行采购与支付。 ## 风险 - PDD 分享面板或“复制链接”文案变化:通过服务端规则版本和唯一页面证据控制,失败时停止。 - Android 新版本限制后台剪贴板:使用短暂、可见生命周期内的前台中转 Activity,并做新鲜度校验。 - 恶意或异常短链接造成 SSRF/大响应:服务端严格 HTTPS 主机白名单、逐跳校验、有限重定向、大小和超时限制。 - 当前页被用户切换:执行前和关键动作后重复核验 PDD 包名、页面和身份,冲突即失败。 - 未知 goods_id 的临时任务会触及既有 URL 快照约束:实施前必须先确认迁移与兼容策略;数据库迁移属于高风险,执行时再次等待用户确认。 ## 文档影响 - 当前建单和原型阶段无长期事实变化,跳过 Wiki。 - 生产实施后预计更新: - Android Agent API 契约; - 业务规则与术语; - Android 运行/排错说明; - 架构和采集任务数据约束。 - 若最终实现未改变长期契约,须在工单中说明原因后跳过 Wiki。
Author
Owner

#101 v1 原型已完成,等待审核

已按用户确认的补充方案完成第一阶段,尚未修改 Android、Server 或数据库生产代码。

设计证据

覆盖范围

  • 采集 Tab 的紧凑“采集”入口,和编号搜索同一行,触控区 48dp。
  • 当前商品确认,明确不采购、不创建订单、不支付。
  • 创建任务、设备原子占槽、恢复 PDD、先识别 goods_id、再采集并提交的执行反馈。
  • 成功、部分完成、默认规则未配置/设备忙/无障碍或服务异常、当前页错误、分享链接识别失败。
  • 成功结果展示任务编号、goods_id、PDD 商品写入结果和来源“Agent 当前页面”。
  • 已补充 API/数据草案:专用原子创建接口、identify 接口、既有 result/fail 复用、任务字段临时可空范围、来源字段、默认规则设置和迁移门禁。

验证

  • QuantUX 导出一致性验证:PASS,10 个界面、159 个组件、25 条交互连线,无运行时错误和不支持组件。
  • 离线 HTML 静态检查通过:入口、确认、成功、部分完成、前置失败、页面错误、链接错误和来源文案齐全;无远程脚本/样式依赖;无“支付”或“创建订单”动作按钮。
  • python dev_scripts/harness.py check --strict:通过。
  • git diff --check:通过。
  • 本机独立 quantux_verify.py 因环境未安装 quickjs 未运行;未擅自安装依赖。服务端同版本导出验证已通过。

文档与风险

  • 当前仍是设计证据,无已实现长期事实,按工单约定跳过 Wiki。
  • 生产实现会涉及数据库迁移;必须在用户审核 v1 通过并再次明确确认迁移后才能执行。

状态:等待用户审核 #101 v1 原型。

## #101 v1 原型已完成,等待审核 已按用户确认的补充方案完成第一阶段,尚未修改 Android、Server 或数据库生产代码。 ### 设计证据 - QuantUX App:`6a8eb736191a826306a7f360` - 在线地址:https://qux.ilapage.cn/#/apps/6a8eb736191a826306a7f360.html - 本地离线快照:`prototypes/101/v1/index.html` - Git 提交:`acdd59a` - 基线:#100 已确认的 Agent 四 Tab 深色布局;未覆盖 #100 历史原型。 ### 覆盖范围 - 采集 Tab 的紧凑“采集”入口,和编号搜索同一行,触控区 48dp。 - 当前商品确认,明确不采购、不创建订单、不支付。 - 创建任务、设备原子占槽、恢复 PDD、先识别 goods_id、再采集并提交的执行反馈。 - 成功、部分完成、默认规则未配置/设备忙/无障碍或服务异常、当前页错误、分享链接识别失败。 - 成功结果展示任务编号、goods_id、PDD 商品写入结果和来源“Agent 当前页面”。 - 已补充 API/数据草案:专用原子创建接口、identify 接口、既有 result/fail 复用、任务字段临时可空范围、来源字段、默认规则设置和迁移门禁。 ### 验证 - QuantUX 导出一致性验证:`PASS`,10 个界面、159 个组件、25 条交互连线,无运行时错误和不支持组件。 - 离线 HTML 静态检查通过:入口、确认、成功、部分完成、前置失败、页面错误、链接错误和来源文案齐全;无远程脚本/样式依赖;无“支付”或“创建订单”动作按钮。 - `python dev_scripts/harness.py check --strict`:通过。 - `git diff --check`:通过。 - 本机独立 `quantux_verify.py` 因环境未安装 `quickjs` 未运行;未擅自安装依赖。服务端同版本导出验证已通过。 ### 文档与风险 - 当前仍是设计证据,无已实现长期事实,按工单约定跳过 Wiki。 - 生产实现会涉及数据库迁移;必须在用户审核 v1 通过并再次明确确认迁移后才能执行。 状态:**等待用户审核 #101 v1 原型。**
Author
Owner

开始实施(2026-08-27)

用户已明确确认“执行 #101,并允许数据库迁移”。

本次严格按已审核的 #101 v1 设计实施:

  • Server:当前页面临时采集任务原子创建、分享链接身份识别、现有结果写回复用;
  • Android:采集 Tab“采集”入口、确认、当前 PDD 页面恢复、分享/复制链接识别和常规采集;
  • 数据:仅为 agent_current_page 任务增加必要来源、临时空快照与默认规则配置约束;
  • 测试与长期契约文档同步。

明确不包含:自动搜索/选择相似商品、自动替换旧商品或虾皮关联、采购、创建订单、支付、OCR/VLM,以及保存原始控件树、截图或完整分享文案。

## 开始实施(2026-08-27) 用户已明确确认“执行 #101,并允许数据库迁移”。 本次严格按已审核的 #101 v1 设计实施: - Server:当前页面临时采集任务原子创建、分享链接身份识别、现有结果写回复用; - Android:采集 Tab“采集”入口、确认、当前 PDD 页面恢复、分享/复制链接识别和常规采集; - 数据:仅为 `agent_current_page` 任务增加必要来源、临时空快照与默认规则配置约束; - 测试与长期契约文档同步。 明确不包含:自动搜索/选择相似商品、自动替换旧商品或虾皮关联、采购、创建订单、支付、OCR/VLM,以及保存原始控件树、截图或完整分享文案。
Author
Owner

实施完成,待验收(2026-08-27)

实现结果

  • Android Agent 版本提升为 0.9.0(versionCode 13);采集 Tab 新增“采集”入口、确认与失败提示。
  • Agent 仅在近期确实进入过 PDD 且当前空闲时发起;创建任务后用返回动作恢复原 PDD 任务栈,不通过浏览器重开未知链接。
  • 新增受控“分享 → 复制链接”识别,前台中转 Activity 只读取本次新鲜、单条、纯文本剪贴板内容;Android 只上传唯一白名单 URL,不保存或上传完整分享文案。
  • 服务端新增当前页面任务原子创建及商品身份识别接口,绑定发起设备、规则快照与租约,支持请求幂等;相同 goods_id 复用 PDD 商品。
  • collection_task 新增来源与识别幂等信息,PDD 商品外键在识别前允许为空;新增单行 Agent 手动采集默认规则设置。
  • 现有结构化结果、部分完成、失败和 PDD 商品最新数据覆盖流程继续复用;当前页面任务不允许重置。
  • 规则契约新增 collector.pdd.current-page-share.v1 与可配置分享/复制入口、超时参数。
  • 未增加采购、创建订单、修改地址或支付路径;未保存控件树、截图或完整剪贴板内容。

数据库迁移

用户已明确授权数据库迁移。本机 MySQL 8.4 已执行迁移 1787790000000_agent_current_page_collection:

  • 首次执行:新增 1、跳过 21,成功;默认手动采集规则种子为规则 ID 3。
  • 幂等复跑:新增 0、跳过 22,成功。
  • 未删除业务数据。

验证

  • cd server && go test ./...:通过。
  • cd android && .\gradlew.bat testDebugUnitTest assembleDebug:通过,APK 构建成功。
  • python dev_scripts/harness.py check --strict:通过。
  • python dev_scripts/harness.py sync --check:通过。
  • git diff --cached --check:通过;敏感值扫描 0 命中。
  • 本地提交:28c3cb5 feat: collect current PDD page from Agent (#101)(尚未推送)。

Wiki-first 证据

线上页面已更新并回读,随后本地镜像一致性检查通过:

  • Android-Agent-API-Contract:79f7b1e9e9058db1e9453db6f74dbe7219ffb16f
  • Business-Rules-and-Glossary:579d9b25297d7b404c68aca4a29ef3179555baa9
  • Architecture-and-Code-Map:ecfe6f881cb937688547b0fe819734813d93dd1b
  • Local-Development-and-Verification:9253f4f7557eeb014032edd7b0645de19a1516f5

尚未验证 / 边界

  • 未安装 APK、未做真机 PDD 分享短链/直链采集;本次只有数据库迁移授权,没有新增真机操作授权。
  • #101 复用当前同步结果/失败提交路径;断网结果 Outbox 仍依赖独立工单 #92,本次未扩展其范围,故未宣称断网恢复验收通过。
  • 管理端默认规则已提供管理员 API 并由迁移种子完成本机初始配置;本工单获批原型不含新的 Admin 配置页面。

工单保持打开,等待用户真机验收。

## 实施完成,待验收(2026-08-27) ### 实现结果 - Android Agent 版本提升为 **0.9.0(versionCode 13)**;采集 Tab 新增“采集”入口、确认与失败提示。 - Agent 仅在近期确实进入过 PDD 且当前空闲时发起;创建任务后用返回动作恢复原 PDD 任务栈,不通过浏览器重开未知链接。 - 新增受控“分享 → 复制链接”识别,前台中转 Activity 只读取本次新鲜、单条、纯文本剪贴板内容;Android 只上传唯一白名单 URL,不保存或上传完整分享文案。 - 服务端新增当前页面任务原子创建及商品身份识别接口,绑定发起设备、规则快照与租约,支持请求幂等;相同 goods_id 复用 PDD 商品。 - `collection_task` 新增来源与识别幂等信息,PDD 商品外键在识别前允许为空;新增单行 Agent 手动采集默认规则设置。 - 现有结构化结果、部分完成、失败和 PDD 商品最新数据覆盖流程继续复用;当前页面任务不允许重置。 - 规则契约新增 `collector.pdd.current-page-share.v1` 与可配置分享/复制入口、超时参数。 - 未增加采购、创建订单、修改地址或支付路径;未保存控件树、截图或完整剪贴板内容。 ### 数据库迁移 用户已明确授权数据库迁移。本机 MySQL 8.4 已执行迁移 `1787790000000_agent_current_page_collection`: - 首次执行:新增 1、跳过 21,成功;默认手动采集规则种子为规则 ID 3。 - 幂等复跑:新增 0、跳过 22,成功。 - 未删除业务数据。 ### 验证 - `cd server && go test ./...`:通过。 - `cd android && .\gradlew.bat testDebugUnitTest assembleDebug`:通过,APK 构建成功。 - `python dev_scripts/harness.py check --strict`:通过。 - `python dev_scripts/harness.py sync --check`:通过。 - `git diff --cached --check`:通过;敏感值扫描 0 命中。 - 本地提交:`28c3cb5 feat: collect current PDD page from Agent (#101)`(尚未推送)。 ### Wiki-first 证据 线上页面已更新并回读,随后本地镜像一致性检查通过: - Android-Agent-API-Contract:`79f7b1e9e9058db1e9453db6f74dbe7219ffb16f` - Business-Rules-and-Glossary:`579d9b25297d7b404c68aca4a29ef3179555baa9` - Architecture-and-Code-Map:`ecfe6f881cb937688547b0fe819734813d93dd1b` - Local-Development-and-Verification:`9253f4f7557eeb014032edd7b0645de19a1516f5` ### 尚未验证 / 边界 - 未安装 APK、未做真机 PDD 分享短链/直链采集;本次只有数据库迁移授权,没有新增真机操作授权。 - #101 复用当前同步结果/失败提交路径;断网结果 Outbox 仍依赖独立工单 #92,本次未扩展其范围,故未宣称断网恢复验收通过。 - 管理端默认规则已提供管理员 API 并由迁移种子完成本机初始配置;本工单获批原型不含新的 Admin 配置页面。 工单保持打开,等待用户真机验收。
Author
Owner

用户于 2026-08-28 明确确认本工单验收通过。按项目流程记录验收结论并关闭工单;本次仅更新工单状态,无新增长期文档事实,不重复同步 Wiki。

用户于 2026-08-28 明确确认本工单验收通过。按项目流程记录验收结论并关闭工单;本次仅更新工单状态,无新增长期文档事实,不重复同步 Wiki。
ila closed this issue 2026-08-28 15:07:12 +08:00
Sign in to join this conversation.
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: OPC/goauto#101