diff --git a/docs/task/104-pdd商品批量导入excel链接.md b/docs/task/104-pdd商品批量导入excel链接.md new file mode 100644 index 0000000..efb123e --- /dev/null +++ b/docs/task/104-pdd商品批量导入excel链接.md @@ -0,0 +1,79 @@ +# 104 Admin:PDD 商品支持批量导入 Excel 链接 + +- 类型:需求 +- 父级大工单:#14 +- 所属 MVP / 版本:#15 Admin 四模块可用闭环 +- 状态:待验收 +- 日期:2026-08-10 +- Gitea 工单:http://ilaer.eicp.net:8418/chengma/cmautobuy/issues/104 + +## 背景与目标 + +PDD 商品原来只能逐条粘贴链接创建。采购员需要把一列式 `.xlsx` 中的完整 +PDD 商品链接批量导入商品档案,并在核对统计和失败明细后,显式为本次导入的 +完整商品集合创建采集任务,不受当前列表分页限制。 + +## 最终方案 + +- PDD 工具条增加“批量导入”,弹窗上传不超过 10MB 的 `.xlsx`。 +- 读取第一个非空工作表,要求第一列标题为“拼多多链接”,忽略空工作表和空行, + 最多处理 5000 条非空数据行。 +- 每行复用现有完整链接解析和 `goods_id` 去重规则;无效行保留行号、原始内容和原因, + 其他合法行继续导入。 +- Repository 在不改变原 `EnsurePddProduct` 调用方式的前提下返回新建、复用、复活分类; + 已存在商品保留采集结果,软删除商品沿用原有复活和清理规则。 +- 合法行在同一事务中写入,任一数据库错误整批回滚。 +- 结果区显示总行数、新建、已存在、恢复、文件内重复和失败数量;保存本次合法且去重后的 + `goods_id` 隐藏集合,显式确认后复用现有可选客户端和批量采集规则。 +- 上传不会自动建任务;提交按钮在上传或创建任务期间显示忙碌状态并防止重复提交。 +- 上传文件使用服务端生成的临时文件名,解析完成即删除;不保存原始上传文件。 +- 与原方案相比,发现 CSRF 中间件会先于 Handler 解析 multipart,因此把 PDD 和既有蝦皮 + 上传请求体上限前移到 CSRF 解析之前,确保大小限制真正生效;普通表单和 Client API 不变。 +- 没有新增数据库结构、迁移或依赖,也没有改变 Client 四接口。 + +## 改了哪些 + +- `admin/handler/web/csrf.go`:在 CSRF 解析 multipart 前应用上传请求体上限。 +- `admin/handler/web/pdd.go`、`web.go`:增加导入路由、临时文件处理和统一列表结果渲染。 +- `admin/service/pdd_import.go`:实现文件校验、流式逐行解析、去重、统计和事务编排。 +- `admin/repository/pdd.go`:为既有建档逻辑增加新建/复用/复活结果分类。 +- `admin/templates/pdd/list.html`:增加上传弹窗、结果区、失败明细和本批采集确认弹窗。 +- `admin/static/js/app.js`、`admin/static/css/app.css`:增加上传反馈、支持两个采集确认入口及结果布局。 +- `admin/service/pdd_import_test.go`、`admin/pdd_import_template_test.go`:覆盖格式、边界、事务、 + 重复导入、HTML 转义和跨分页集合渲染。 +- `admin/testdata/pdd_links.xlsx`:可提交的脱敏一列式测试固件。 +- `docs/admin/01-requirements.md`、`05-ui-specification.md`、`06-quality-security.md`:同步稳定需求、UI 和测试安全规则。 + +## 验收结果 + +| 验收标准 | 结果 | +|---|---| +| PDD 页显示批量导入弹窗,写路由受登录和 CSRF 保护 | 通过 | +| 真实 `raw_data/pdd链接.xlsx` 的 8 条链接及两个域名可识别,空 Sheet2/Sheet3 忽略 | 通过(Go 解析器人工核对) | +| 扩展名、xlsx 文件头、空文件、10MB、表头和 5000 条上限校验 | 通过 | +| 新建、复用、复活、文件内重复分别处理,重复导入不清空采集结果 | 通过 | +| 无效行不阻塞合法行,完整显示行号、原文和原因 | 通过 | +| 数据库中途失败时合法行整体回滚 | 通过(自动化事务故障测试) | +| 结果统计完整且不只靠颜色表达 | 通过 | +| 上传不自动建任务,显式确认后才复用现有批量任务规则 | 通过 | +| 本次导入集合不依赖当前分页 | 通过(模板隐藏集合测试) | +| 不新增数据库迁移,不改变 Client 四接口和采购/下单行为 | 通过 | +| Go 1.23.0 build、test、vet 与脱敏固件测试 | 通过 | + +## 测试 + +- 执行的命令: + - `GOTOOLCHAIN=go1.23.0 go mod verify` + - `GOTOOLCHAIN=go1.23.0 go build ./...` + - `GOTOOLCHAIN=go1.23.0 go test ./... -count=1` + - `GOTOOLCHAIN=go1.23.0 go vet ./...` + - `node --check static/js/app.js` + - `go test ./service -run '^TestManualPddRawSample$' -count=1 -v`(临时人工测试只读取 `raw_data`,测试文件未提交) +- 结果:全部通过;真实样本得到 8 行、8 个合法且唯一的商品链接、0 个失败。 +- **没验证到的部分**:未设置 `CMAUTOBUY_MYSQL_TEST=1` 和独立 `_test` 基础库, + 因此没有执行真实 MySQL 8.4 的 HTTP 上传到落库集成测试;没有在浏览器中人工核对 + 1366×768 布局和管理员/采购员实际点击流程。未连接或修改生产数据库。 + +## 相关提交 + +- `188725f` feat: 支持批量导入 PDD 商品链接 (#104)