feat(web): SYB 商品批量发起图搜任务 #280

Open
opened 2026-09-14 10:17:49 +08:00 by ila · 2 comments
Owner

所属 MVP:#275 | 来源:用户 2026-09-14 需求讨论(原话摘要见 #275)

目标

采购员可以在 SYB 商品页多选商品,一次性发起图搜任务。

前置依赖

#278。

方案

  1. SYB 商品页表格支持多选,新增「批量图搜」按钮,位置紧邻现有「关联 PDD」。
  2. 按 shopee_product 去重:一个虾皮商品有几十条 SYB 明细共用同一张图,必须合并为一个任务,不能搜几十遍。
  3. 批次上限与提示:一次图搜约占用设备数十秒,几百个任务会长时间占满设备。需要明确的批次上限与"预计耗时"提示。
  4. 已有关联的商品默认排除,可显式勾选覆盖。

明确不做

不新增菜单、不新增页面。发起入口就在采购员已经在用的 SYB 商品页。

设计证据

现有页面新增多选与一个批量操作按钮。需提供标注截图或明确复用现有批量操作规范后再实施。

验收

  • 同一虾皮商品的多条明细只产生一个图搜任务。
  • 超过批次上限有拦截与提示。
  • 已关联商品默认不在发起范围内。
  • 发起后可在采集任务列表看到对应任务。

验证

Go 单元测试 + Web 构建 + .\scripts erify.ps1 -Component all。

风险

批量创建会长时间占用设备。依赖 #277 的调度垫底保证采购任务可插队。

文档影响

新增用户操作入口,需更新对应 Wiki 的业务规则或操作说明页面。

> 所属 MVP:#275 | 来源:用户 2026-09-14 需求讨论(原话摘要见 #275) ## 目标 采购员可以在 SYB 商品页多选商品,一次性发起图搜任务。 ## 前置依赖 #278。 ## 方案 1. SYB 商品页表格支持多选,新增「批量图搜」按钮,位置紧邻现有「关联 PDD」。 2. **按 `shopee_product` 去重**:一个虾皮商品有几十条 SYB 明细共用同一张图,必须合并为一个任务,不能搜几十遍。 3. 批次上限与提示:一次图搜约占用设备数十秒,几百个任务会长时间占满设备。需要明确的批次上限与"预计耗时"提示。 4. 已有关联的商品默认排除,可显式勾选覆盖。 ## 明确不做 不新增菜单、不新增页面。发起入口就在采购员已经在用的 SYB 商品页。 ## 设计证据 现有页面新增多选与一个批量操作按钮。**需提供标注截图或明确复用现有批量操作规范后再实施。** ## 验收 - [ ] 同一虾皮商品的多条明细只产生一个图搜任务。 - [ ] 超过批次上限有拦截与提示。 - [ ] 已关联商品默认不在发起范围内。 - [ ] 发起后可在采集任务列表看到对应任务。 ## 验证 Go 单元测试 + Web 构建 + `.\scripts erify.ps1 -Component all`。 ## 风险 批量创建会长时间占用设备。依赖 #277 的调度垫底保证采购任务可插队。 ## 文档影响 新增用户操作入口,需更新对应 Wiki 的业务规则或操作说明页面。
Author
Owner

核对范围与方法(2026-09-15)

  • 被核对分支:release/283 @ c80d0c9;基线 main @ c14f5f5。
  • 该分支是打包分支,同时含 #272 #273 #274 #276 #278 #279 #280 #282 #283,本次只就 #275~#280 的验收项作结论。
  • 执行内容:go build ./...、go test ./...(server)、npm run build:prod(web)、逐条对照工单验收项读取 diff。
  • 未执行:真机验证、Android 构建与单测(见 #277 结论,Android 侧无可验证的实现)。

结论:部分完成,不达标

已完成

  • POST /api/admin/v1/collection-tasks/image-search/batch + SYB 商品页「图搜采集」按钮与两步对话框(确认 / 结果)。
  • 按 shopee_product 去重已实现(task/image_search.go 中以 ShopeeProductID 为键的 groups 归并,多条 SYB 明细合并为一个任务)。验收第 1 条满足。
  • 已关联商品默认跳过,提供「覆盖已有关联」勾选;结果表区分 已创建 / 已跳过(IMAGE_SEARCH_ALREADY_LINKED) / 失败。验收第 3、4 条满足。
  • npm run build:prod 通过。

未完成的验收项

  • 批次上限(方案第 3 条 / 验收第 2 条)。 代码中只有单张参考图 imageSearchMaxBytes = 10MB 的大小限制,没有任何"一次最多 N 个任务"的拦截,也没有预计耗时提示。

    该项的风险在当前状态下未被任何机制缓解:#277 的调度垫底(采购 > 采集 > 图搜)同样未实现,因此一次大批量创建会无限制占用设备,且采购任务无法插队。

设计证据

本工单要求"需提供标注截图或明确复用现有批量操作规范后再实施",未见相关记录。

状态维持待实施。

## 核对范围与方法(2026-09-15) - 被核对分支:`release/283` @ `c80d0c9`;基线 `main` @ `c14f5f5`。 - 该分支是打包分支,同时含 #272 #273 #274 #276 #278 #279 #280 #282 #283,本次只就 #275~#280 的验收项作结论。 - 执行内容:`go build ./...`、`go test ./...`(server)、`npm run build:prod`(web)、逐条对照工单验收项读取 diff。 - **未执行**:真机验证、Android 构建与单测(见 #277 结论,Android 侧无可验证的实现)。 ## 结论:部分完成,不达标 ### 已完成 - `POST /api/admin/v1/collection-tasks/image-search/batch` + SYB 商品页「图搜采集」按钮与两步对话框(确认 / 结果)。 - **按 `shopee_product` 去重已实现**(`task/image_search.go` 中以 `ShopeeProductID` 为键的 `groups` 归并,多条 SYB 明细合并为一个任务)。验收第 1 条满足。 - 已关联商品默认跳过,提供「覆盖已有关联」勾选;结果表区分 已创建 / 已跳过(`IMAGE_SEARCH_ALREADY_LINKED`) / 失败。验收第 3、4 条满足。 - `npm run build:prod` 通过。 ### 未完成的验收项 - [ ] **批次上限(方案第 3 条 / 验收第 2 条)。** 代码中只有单张参考图 `imageSearchMaxBytes = 10MB` 的大小限制,没有任何"一次最多 N 个任务"的拦截,也没有预计耗时提示。 该项的风险在当前状态下**未被任何机制缓解**:#277 的调度垫底(采购 > 采集 > 图搜)同样未实现,因此一次大批量创建会无限制占用设备,且采购任务无法插队。 ### 设计证据 本工单要求"需提供标注截图或明确复用现有批量操作规范后再实施",未见相关记录。 状态维持待实施。
Author
Owner

上线信息(共用)

  • 合并提交:1d01186,已推送 be03972..1d01186 到 main。
  • 发布目录:/home/goauto/releases/20260915-1d01186,二进制 SHA-256 前缀 65e404c4721d592a(本地与服务器一致)。
  • systemctl is-active goauto.service = active,监听 127.0.0.1:8010。
  • 数据库迁移:新执行 2 个,跳过 45 个已应用。迁移前已做全库逻辑备份(66 张表,gzip 校验通过),路径在运维备份目录,不在此列出。
  • 迁移前后 collection_task 222 行、shopee_product 26901 行,逐一相符。

外部入口验证:

检查 结果
GET / HTTP 200
GET /api/admin/v1/collection-tasks {"code":401,"msg":"cookie token is empty"}
POST /api/admin/v1/collection-tasks/image-search/batch {"code":401,...}
不存在路由对照 HTTP 404

最后两行是关键对照:图搜接口返回 401 而非 404,证明新路由已注册。

回退方式:把 current 软链切回 20260914-be03972-r2 后重启。两条迁移均为加列与放宽约束,不阻碍回退到旧二进制。

实施

提交:be491c7、c80d0c9、56706a0、ba7d2a6、b7babfb。

  • POST /api/admin/v1/collection-tasks/image-search/batch,SYB 商品页「图搜采集」按钮与两步对话框。
  • 按 shopee_product 去重(以 ShopeeProductID 为键的 groups 归并)。
  • 已关联商品默认跳过,提供「覆盖已有关联」勾选;结果表区分 已创建 / 已跳过 / 失败。

上一轮评论提出的缺口已补:批次上限

imageSearchMaxBatchTasks = 50,作用于去重后的任务数,在 groups 构建之后、创建任何任务之前判定,超限整批拒绝(IMAGE_SEARCH_BATCH_TOO_LARGE),不部分创建。按单次图搜 20~40 秒估算,50 个任务约占用设备 17~33 分钟。Web 确认对话框显示去重后任务数与预计耗时区间,超限时按钮禁用。

新增三个测试,其中关键一条是「入参 55 条明细全部指向同一个蝦皮商品,去重后 1 个任务,应当成功」,证明上限确实作用于去重后条数。

[必须] 上限实现为普通常量,不可由环境变量覆盖。确认对话框必须在提交前禁用按钮,前端持有同一个数字;env 覆盖只会让服务端与前端静默不一致。改动时两侧必须同改。(实施中一度做成可 env 覆盖,审核时已移除。)

验证

go test ./app/goauto/task/... 通过;npm run build:prod 通过。

状态

已上线,保持待验收。界面变化的标注截图或复用规范说明仍未提供(工单设计证据要求),验收时需补。

## 上线信息(共用) - 合并提交:`1d01186`,已推送 `be03972..1d01186` 到 `main`。 - 发布目录:`/home/goauto/releases/20260915-1d01186`,二进制 SHA-256 前缀 `65e404c4721d592a`(本地与服务器一致)。 - `systemctl is-active goauto.service` = `active`,监听 `127.0.0.1:8010`。 - 数据库迁移:新执行 2 个,跳过 45 个已应用。迁移前已做全库逻辑备份(66 张表,gzip 校验通过),路径在运维备份目录,不在此列出。 - 迁移前后 `collection_task` 222 行、`shopee_product` 26901 行,逐一相符。 外部入口验证: | 检查 | 结果 | |---|---| | `GET /` | HTTP 200 | | `GET /api/admin/v1/collection-tasks` | `{"code":401,"msg":"cookie token is empty"}` | | `POST /api/admin/v1/collection-tasks/image-search/batch` | `{"code":401,...}` | | 不存在路由对照 | HTTP 404 | 最后两行是关键对照:图搜接口返回 401 而非 404,证明新路由已注册。 回退方式:把 `current` 软链切回 `20260914-be03972-r2` 后重启。两条迁移均为加列与放宽约束,不阻碍回退到旧二进制。 ## 实施 提交:`be491c7`、`c80d0c9`、`56706a0`、`ba7d2a6`、`b7babfb`。 - `POST /api/admin/v1/collection-tasks/image-search/batch`,SYB 商品页「图搜采集」按钮与两步对话框。 - 按 `shopee_product` 去重(以 `ShopeeProductID` 为键的 `groups` 归并)。 - 已关联商品默认跳过,提供「覆盖已有关联」勾选;结果表区分 已创建 / 已跳过 / 失败。 ### 上一轮评论提出的缺口已补:批次上限 `imageSearchMaxBatchTasks = 50`,作用于**去重后**的任务数,在 `groups` 构建之后、创建任何任务之前判定,超限整批拒绝(`IMAGE_SEARCH_BATCH_TOO_LARGE`),不部分创建。按单次图搜 20~40 秒估算,50 个任务约占用设备 17~33 分钟。Web 确认对话框显示去重后任务数与预计耗时区间,超限时按钮禁用。 新增三个测试,其中关键一条是「入参 55 条明细全部指向同一个蝦皮商品,去重后 1 个任务,应当成功」,证明上限确实作用于去重后条数。 `[必须]` 上限实现为普通常量,**不可由环境变量覆盖**。确认对话框必须在提交前禁用按钮,前端持有同一个数字;env 覆盖只会让服务端与前端静默不一致。改动时两侧必须同改。(实施中一度做成可 env 覆盖,审核时已移除。) ## 验证 `go test ./app/goauto/task/...` 通过;`npm run build:prod` 通过。 ## 状态 已上线,保持待验收。界面变化的标注截图或复用规范说明仍未提供(工单设计证据要求),验收时需补。
Sign in to join this conversation.
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: OPC/goauto#280