docs: import wiki at afc651f75a3a

ila
2026-08-07 16:36:57 +08:00
parent cb91aacb8e
commit 840bb31fd8
+124
@@ -0,0 +1,124 @@
<!-- docs-wiki-sync:docs/tasks/T-248.md@afc651f75a3abc2676bb13aa8a80f6aa6a25a72e -->
> 同步来源:[`docs/tasks/T-248.md`](/chengma/mroubao/src/commit/afc651f75a3abc2676bb13aa8a80f6aa6a25a72e/docs/tasks/T-248.md) · commit `afc651f75a3a`
---
id: T-248
title: 增量回传准确候选并增加第三轮保底搜索
phase: 2
deps:
- T-247
status: DONE
created: 2026-07-30
context_ref: bef6408
work_branch: null
write_paths:
- docs/tasks/T-248.md
- docs/current-state.md
- docs/api.md
- backend-api/migrations/**
- backend-api/internal/**
- android-buyer/app/src/main/**
- android-buyer/app/src/test/**
---
## 需求 / 背景
T-247 将自动图片搜索限制为两轮,并要求同一轮凑齐两个 SKU 硬匹配候选后才回传。
真实拼多多结果中,准确候选可能分布在不同轮次;只在整批完成后回传会丢失已经确认的
商品,也让 Admin 无法观察当前进度。
目标流程调整为:
1. Roubao 始终使用任务参考图进行拼多多图片搜索。
2. 前两轮使用解析后的款式/颜色、尺码和价格信息检查商品;每得到一个完整准确候选就
立即回传 Admin,并在后续轮次继续累计。
3. 两轮结束仍不足 2 个准确候选时,执行第三轮图片搜索,采集拼多多默认结果前两个
不重复商品作为保底候选。
4. Admin 必须能区分准确候选和未通过 SKU 硬匹配的保底候选。
5. Roubao 操作拼多多的外部 UI 动作之间增加 1 至 3 秒随机停顿。
## 修订契约
### 三阶段搜索
- execution 持久化阶段为 `EXACT_ROUND_1`、`EXACT_ROUND_2`、
`FALLBACK_ROUND_3` 和 `COMPLETE`,进程重启后不得从第一轮重新开始。
- 前两轮累计准确候选,按规范 `goods_id` 去重;同一商品不得重复回传或占用多个名额。
- 累计准确候选达到 2 个时跳过剩余轮次并完成采集。
- 两轮结束不足 2 个时必须执行第三轮图片搜索。第三轮按结果排序采集前两个不重复且
身份、链接和证据完整的商品,不要求 SKU 硬匹配;最多有 1 个准确候选加 2 个保底
候选。
- 三轮均有界;第三轮完成或稳定失败后停止外部操作,不进入下单、订单确认或支付。
### 增量回传
- App 每发现一个准确候选,立即将当前累计候选快照加入加密 outbox;网络不可用时本地
保留并按原幂等机制重传。
- 候选提交增加 `collection_complete` 和 `search_round`。后台只在
`collection_complete=true` 时将任务从 `RUNNING` 改为 `WAITING_CONFIRMATION`。
- 同一 execution 的后续快照只能追加或保持已有 `goods_id`,不能删除、替换或降级已有
准确候选;完成后的快照不可再修改。
- 候选增加 `match_type`、`search_round` 和 `result_rank`:
`EXACT_MATCH` 表示颜色/款式和尺码硬约束均复读匹配,`FALLBACK` 表示仅来自第三轮
默认排序。保底候选不能生成自动推荐。
- Admin 在搜索未完成时显示候选和当前轮次,但保持选择/推送禁用;完成后准确候选优先,
保底候选显示明确警告。
### 外部动作节奏
- 打开拼多多、打开图片搜索、选择图片、打开/返回商品、滑动结果、打开/关闭规格、
选择规格和分享复制链接等外部 UI 动作之间,使用可取消的 1 至 3 秒随机停顿。
- 页面识别、OCR、截图哈希、SQLite/SharedPreferences 和 HTTP/outbox 操作不增加随机
停顿;页面跳转继续以状态检测和有界 timeout 为准,随机停顿不能替代就绪检查。
- 停顿使用协程 `delay`,不得阻塞 Android 主线程;测试可注入确定性延迟。
## 方案
1. 将两次 attempt gate 升级为持久化三阶段 gate,记录当前轮次、已完成和最后失败。
2. 候选自动化增加准确/保底采集模式、跨轮已见商品集合及采集事件;准确模式保留严格
SKU 选择,保底模式读取规格和身份但不强制选择目标 SKU。
3. MainActivity 按 execution 累计候选;准确候选新增时立即排队提交累计快照,第三轮
完成后提交最终快照。
4. 扩展候选 API 和 SQLite batch 表,允许同一 execution 在 `RUNNING` 状态幂等更新
未完成快照;只允许候选单调追加,并在完成快照事务中保存决策数据集、产生
`CANDIDATES_READY` 事件和切换任务状态。
5. Admin 候选数据沿用现有详情接口与鉴权证据路由,补充采集阶段、匹配类型和完成状态。
6. 提供统一 `PinduoduoActionPacer`,由各 Android driver 在成功发出外部动作后调用,
默认随机 1000 至 3000 毫秒,单测使用零延迟 fake。
## 验收要点
- [x] 第一、第二轮准确候选跨轮累计,按 `goods_id` 去重。
- [x] 每新增一个准确候选就产生可幂等重试的未完成累计快照,后台任务保持 `RUNNING`。
- [x] 累计两个准确候选后发送完成快照并进入 `WAITING_CONFIRMATION`,不执行第三轮。
- [x] 两轮不足两个时执行第三轮,回传默认排序前两个不重复 `FALLBACK` 候选。
- [x] Admin 数据明确展示 `EXACT_MATCH`/`FALLBACK`、轮次、排序和采集是否完成。
- [x] 完成快照不能被旧快照或重试覆盖,已有准确候选不能删除或降级。
- [x] 拼多多外部动作之间默认随机停顿 1 至 3 秒,等待可取消且不阻塞主线程。
- [x] Android/Go 单测、race、vet、Debug/Release 构建通过。
- [ ] 真机 smoke 不进入下单、订单确认或支付,结束后按用户要求保持 Roubao 停止。
## 边界
- 保底候选只是图片搜索默认排序结果,不宣称 SKU 匹配成功。
- 本任务最多保存 2 个准确候选和 2 个保底候选,总候选数不超过 3。
- 不绕过拼多多登录、验证码、风险控制或支付边界。
- 不记录拼多多 Cookie、Token、原始分享短链或参考图内容日志。
## 执行记录
- 2026-07-30:新增 v19 迁移和累计候选 API。未完成快照只更新 Admin 执行审计并保持
`RUNNING`;最终快照才生成候选决策数据集、`CANDIDATES_READY` 事件并切换
`WAITING_CONFIRMATION`。后端事务拒绝候选删除、替换、轮次回退和完成后的旧快照。
- 2026-07-30:Android attempt gate 从两轮升级为三阶段;候选证据、来源类型、轮次和
排名按 execution 持久化。前两轮严格选择并复读 SKU,第三轮不选择目标 SKU,只收集
默认结果中两个身份完整且未重复的保底商品。
- 2026-07-30:每个新增候选立即把累计快照加入既有加密 outbox;最终最多为两个准确
候选,或一个准确候选加两个保底候选。Admin 显示匹配类型、轮次、结果排名和采集状态。
- 2026-07-30:新增统一拼多多动作 pacer;打开、点击、滑动、返回、规格选择和分享复制
成功后随机等待 1000 至 3000 ms,页面识别、OCR、截图和网络回传不增加随机延迟。
- 2026-07-30:`go test ./...`、`go test -race ./...`、`go vet ./...` 和三个 Go
入口构建通过;Android 单测及 Debug/Release 构建通过。Debug APK
`1.4.16 (21)` 已覆盖安装到 PKG110,随后 force-stop 并确认进程不存在。
- 2026-07-30:按用户要求未启动真实采购,因此真实拼多多三轮搜索和 Admin 最终候选
展示仍需使用新任务完成 smoke;本次没有触发下单、订单确认或支付。