From fbfa2fce3d2c18f163b8dc0bb48d93b90063c027 Mon Sep 17 00:00:00 2001 From: chengma Date: Fri, 7 Aug 2026 15:17:32 +0800 Subject: [PATCH] =?UTF-8?q?docs:=20=E5=BD=92=E6=A1=A3=E4=BB=BB=E5=8A=A1=20?= =?UTF-8?q?#19?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 如实记录打回两次的过程,以及两次都是架构角色的检查指令给窄了: 第一次给的 grep 只覆盖「四个模块」,漏掉「四个页面」这个变体; 第二次改成直接给 6 处确切行号,并点明哪两处的「四个」是对的不许改。 未验证四项:浏览器实机交互、主题与缩放、采购任务真实创建路径 (入口尚未实现,验证用的是手工插库)、目标列规格顺序与工单示意图不同。 Co-Authored-By: Claude Opus 5 --- docs/task/19-admin-采集采购页.md | 191 +++++++++++++++++++++++++++++++ 1 file changed, 191 insertions(+) create mode 100644 docs/task/19-admin-采集采购页.md diff --git a/docs/task/19-admin-采集采购页.md b/docs/task/19-admin-采集采购页.md new file mode 100644 index 0000000..ea65163 --- /dev/null +++ b/docs/task/19-admin-采集采购页.md @@ -0,0 +1,191 @@ +# 19 Admin 采集采购页,采集与采购统一展示 + +- 类型:需求(界面) +- 父级大工单:#14 +- 所属 MVP / 版本:#15 / MVP +- 关联:#18(缺陷暴露于该工单交付后) +- 状态:待验收 +- 日期:2026-08-07 +- Gitea 工单:http://ilaer.eicp.net:8418/chengma/cmautobuy/issues/19 + +## 背景与目标 + +`tasks` 是**一张表**,用 `task_type` 区分采集和采购。但原来的「采购任务」页 +是骨架——`var rows []gin.H` 从不查库,页面永远为空;TODO 写的还是 +只查 `task_type = 'purchase'`。 + +所以 #18 建出来的采集任务**在界面上哪儿都看不到**。用户实际遇到的场景: +在 PDD 商品页勾选商品、点「创建采集任务」,然后采购任务页什么都没有。 +查证时库里确实有 2 条 `collect` 任务,`assigned_client` 为 NULL、状态 `pending`。 + +`collect_status` 只能告诉你「这个商品采到没有」,看不出任务本身怎么了: +被谁领走了、什么时候领的、失败在哪一步。 + +## 最终方案 + +### 模块名「采集采购」 + +用户指定。直接点出这一页装的是哪两类任务,比泛称「任务」更能让操作员 +一眼知道点进去看什么。 + +路由 `/tasks` 和 `objectName` **不变**——改路由会让已有书签和文档里的 +链接全失效,而这一项没有任何收益。 + +### 列不按类型并列,用「目标」概括 + +两种任务的业务字段完全不同:采购有订单号、颜色尺码、数量、价格上限, +采集只有 PDD 链接。**并列会让采集任务行一半是空列**。 + +```text +☐ │ COL-8020a8729f111c15 │ 采集 │ PDD 737116531267 │ 待分配 │ — +☐ │ PUR-001 │ 采购 │ SO-001 · M/黑色 · 2件 · ≤¥42.00 │ 待分配 │ — +``` + +目标列所需字段全在 `tasks` 表上,不需要 join。采集任务 join `pdd_products` +取标题作为增强,join 不到或商品已软删除时退回显示 `pdd_goods_id`。 + +`[必须]` 拼接逻辑在 **service 层**组装成一个字符串,模板只负责显示。 +散在模板里没人维护得住。 + +### 统计与列表共用同一个筛选条件 + +`[必须]` 统计跟随当前筛选。分开写两条 SQL 的话,总有一天会忘了给统计 +也加条件,数字和表格对不上,操作员会以为页面坏了。 + +实现把筛选条件的拼装抽成共用函数,两边必然一致。 + +### 无主任务显示 `—` + +#17 之后采集任务默认无主(`assigned_client IS NULL`),这一列会大量为空。 +`[必须]` 显示 `—`,不是空白也不是 ``。 + +### 详情弹窗只读 + +采购专有字段(数量、价格上限、目标规格)在采集任务的弹窗里**整段不出现**, +不显示空行。改派、重试、取消是后续工单,本工单不做。 + +复用 #18 的弹窗机制(`data-detail-url` 那套服务端渲染片段)—— +该机制本来就是通用的,`app.js` 无需改动。 + +## 与建单方案的差异 + +1. **模块名从「任务」改成「采集采购」**(工单实施前已按用户要求修改工单正文并记录理由)。 +2. **删掉了初版加的 `HasAnyTasks` / `CountAllTasks` 查询。** 无筛选且结果为空, + 按定义就等价于「从来没有过任务」,多一次查询是冗余。`IsFiltered` 一个字段 + 就能驱动两种空状态文案。 +3. **`app.js` 未改动**,虽然在工单的预计文件表里。#18 的弹窗机制是通用的。 +4. **增加 `IsWarn`**(`failed` / `manual_review` 行标黄),与 PDD 页已有约定一致。 + 工单未要求,属于视觉一致性。 +5. **额外更新了模块计数**(见下)。 + +## 改了哪些 + +- `admin/repository/task.go`:`TaskFilter` / `TaskListRow` / `ListTasks` / + `CountTasksByStatus`(与列表共用筛选拼装)/ `DeleteTasks`。 +- `admin/service/task.go`:新建。类型与状态文案、目标列组装、 + `ListTasksView` / `StatusLine` / `GetTaskDetail` / `DeleteTasks`。 +- `admin/service/task_test.go`:新建,25 个用例。 +- `admin/handler/web/others.go`:`TaskList` / `TaskDetail` / `TaskDelete` 真实实现。 +- `admin/handler/web/web.go`:`GET /tasks/detail` 路由。 +- `admin/templates/task/list.html`:重写。 +- `admin/templates/task/detail_modal.html`:新建。 +- `admin/templates/partials/header.html`:导航改「采集采购」。 +- `admin/static/css/app.css`:折叠结果块样式。 +- `docs/admin/01-requirements.md` §4 / §4.4、`05-ui-specification.md` §7:重写。 + +顺带清理(PDD 页加进来之后一直没跟上的模块计数): + +- `admin/main.go` 包注释、`admin/AGENTS.md`、`admin/templates/partials/footer.html`、 + `docs/README.md`、`docs/admin/00-getting-started.md`(模块表**补上缺失的 + PDD 商品那一行**)、`02-architecture.md`、`06-quality-security.md`。 + +## 验收结果 + +架构角色独立复跑的重点项: + +| 检查 | 结果 | +|---|---| +| 页面同时显示采集和采购 | 通过 | +| **统计跟随筛选** | 通过(全部「共 2 条」→ 采集「共 1 条」→ 采购「共 1 条」→ 无结果「共 0 条」) | +| 类型筛选 / 状态筛选 / 关键词 | 通过 | +| 目标列:采集显示 PDD 标识,采购显示订单号+规格+数量+价格上限 | 通过 | +| 价格显示 `¥42.00` | 通过 | +| **无主任务客户端列显示 `—`** | 通过 | +| **采购专有字段在采集弹窗整段隐藏** | 通过(采集弹窗「数量/价格上限/目标规格」各 0 次;采购弹窗各 1 次) | +| 空状态分两种,筛无结果给「查看全部」入口 | 通过 | +| 导航与页面标题显示「采集采购」 | 通过 | +| 五个页面回归 | 全部 200 | +| `go vet` / `gofmt` / `go test` | 通过 | + +## 测试 + +架构角色亲自执行(Go 1.23.0,`admin/` 目录): + +``` +go vet ./... 无输出 +gofmt -l . 无输出 +go test ./... -count=1 ok repository 1.347s / ok service 3.208s +``` + +本工单新增 25 个用例。 + +端到端(curl,非真机): + +``` +建 PDD 商品 → 建采集任务 → 手工插一条 purchase 任务 + +/tasks + COL-8020a8729f111c15 | 采集 | PDD 737116531267 | 待分配 | — + PUR-001 | 采购 | SO-001 · M/黑色 · 2件 · ≤¥42.00 | 待分配 | — + 共 2 条 · 待分配 2 · 待领取 0 · 已领取 0 · 成功 0 · 需人工 0 · 失败 0 · 已取消 0 + +/tasks?type=collect → 只剩采集那行,共 1 条 +/tasks?type=purchase → 只剩采购那行,共 1 条 +/tasks?type=purchase&status=cancelled + → 「当前筛选条件下没有任务。换个类型、状态或关键词再试。查看全部」 + 共 0 条 +``` + +**未验证到的部分:** + +- **浏览器里的真实交互**:双击开弹窗、Esc 关闭、全选联动、删除二次确认, + 只验证了服务端产出的 HTML,没有在真实浏览器里点过。 +- 深色 / 浅色主题、1366×768、显示缩放下的表现未实测。 +- 采购任务目前**没有创建入口**(属于顺运宝模块,未实现), + 验证用的 `purchase` 任务是手工插库的。真实创建路径未走过。 +- 采购任务目标列的规格顺序按维度名排序(`M/黑色`),是确定的但与工单 + 示意图的 `黑色/M` 顺序不同。`pdd_options` 是裸 map 没有顺序信息, + 按键名排序是合理兜底。 + +## 审查过程 + +打回两次,**两次都是架构角色的检查指令给窄了**,不是实现能力问题。 + +**第一次:** 模块名改了,但模块枚举没跟上——`admin/main.go` 包注释仍写 +「采购任务」且漏了 PDD 商品;`docs/admin/00-getting-started.md` 的模块表 +**少了一整行 PDD 商品**且写着「四个模块」(实现改了这张表的一行, +没注意到表本身已过期)。 + +**第二次:** 第一次打回时给的检查命令是 `grep -rn "四个模块"`, +但过期说法还有「四个**页面**」这个变体,实现照做无误,是命令太窄。 +第二次不再给 grep 模式,直接列出 6 处确切行号,并明确点出 +**哪两处的「四个」是对的、不许改**(`pdd/list.html:5` 的「和另外四个页面保持一致」、 +以及归档文档——归档是历史记录,一律不改)。 + +按 `CLAUDE.md` §7.4,同一类问题打回两次就该怀疑要求本身。 +第二次改成给确切清单而不是让实现去猜模式,一轮解决。 + +其中 `docs/admin/06-quality-security.md` 第 60、153 行最要紧: +它们是**验证清单**,写着「跑一遍四个页面断言 200」,照着做的人 +只会测四个,PDD 页永远不在回归范围里。 + +## 遗留问题 + +1. **改派任务**(`01` §4.3 原有的 `[建议]` 项)顺延到后续工单。 +2. 重试 / 取消任务未做。 +3. 采购任务的创建入口属于顺运宝模块,尚未实现。 +4. 浏览器实机交互和主题 / 缩放需人工过一遍。 + +## 相关提交 + +- `f0d7da3` feat: 采集采购页,采集与采购统一展示 (#19)