Files
cmautobuy/docs/task/19-admin-采集采购页.md
T
chengmaandClaude Opus 5 fbfa2fce3d docs: 归档任务 #19
如实记录打回两次的过程,以及两次都是架构角色的检查指令给窄了:
第一次给的 grep 只覆盖「四个模块」,漏掉「四个页面」这个变体;
第二次改成直接给 6 处确切行号,并点明哪两处的「四个」是对的不许改。

未验证四项:浏览器实机交互、主题与缩放、采购任务真实创建路径
(入口尚未实现,验证用的是手工插库)、目标列规格顺序与工单示意图不同。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-07 15:17:32 +08:00

192 lines
8.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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`),这一列会大量为空。
`[必须]` 显示 `—`,不是空白也不是 `<nil>`。
### 详情弹窗只读
采购专有字段(数量、价格上限、目标规格)在采集任务的弹窗里**整段不出现**,
不显示空行。改派、重试、取消是后续工单,本工单不做。
复用 #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)