docs: 归档任务 #51

This commit is contained in:
chengma
2026-08-09 13:51:34 +08:00
parent eea0d65ef8
commit cbc01f8b39
@@ -0,0 +1,88 @@
# 51 Admin:实现采购员账号管理
- 类型:需求
- 父级大工单:#14
- 所属 MVP / 版本:#15 / MVP
- 状态:已完成
- 日期:2026-08-09
- Gitea 工单:<http://ilaer.eicp.net:8418/chengma/cmautobuy/issues/51>
## 背景与目标
#50 建立了首次管理员和网页登录,但管理员还不能维护采购员账号。本任务增加最小
账号管理闭环:管理员可以搜索、新增、启停和重置采购员;采购员继续使用现有业务
页面,但不能进入用户管理;影响登录安全的修改会立即撤销目标账号全部 Session。
## 最终方案
- 新增 `/users` 管理页,沿用全站每页 20 条、SQL 分页、越界兜底和筛选条件保留;
支持用户名字面量搜索和启用/禁用状态筛选。
- 新建账号固定为 `purchaser` 和 `active`,不提供公开注册、第二管理员或角色选择;
用户名继续由 v6 的 `NOCASE UNIQUE` 约束做并发下的最终防重。
- `/users` 路由先经过 #50 的登录认证,再叠加管理员角色中间件。采购员访问返回
`403`,但访问蝦皮、PDD、顺运宝、任务和客户端等现有业务页面不受影响。
- 启停账号与 Session 撤销处于同一个写事务;重置 bcrypt 密码哈希与 Session
撤销也处于同一个事务。失败时整体回滚,不留下“状态已改但旧登录仍有效”的中间态。
- 禁用有效管理员前在事务内统计有效管理员,最后一个有效管理员不能被禁用;页面
同时将唯一管理员的禁用按钮置灰,服务端仍做最终保护。
- 新增采购员、启停和重置密码均使用 POST + CSRF。启停和重置前二次确认;密码
不进入 URL、列表或日志,校验失败时只保留用户名并清空密码。
- 导航只有管理员显示“用户管理”。页面使用可见标签、文字状态和共享弹窗;一个
重置弹窗通过用户编号定位目标,前端不承担权限或 Session 业务逻辑。
实际实现与工单方案一致,没有新增数据库迁移、API Key、Client 登录、物理删除或
细粒度业务页权限。
## 改了哪些
- `admin/repository/user.go`:用户搜索分页、采购员写入、状态与密码事务、Session 撤销、
最后管理员保护。
- `admin/service/user.go`、`admin/service/auth.go`:管理员权限、采购员业务、共享用户名和
密码校验,以及安全区分表单错误和内部错误。
- `admin/handler/web/user.go`、`admin/handler/web/web.go`:管理员中间件和用户管理路由。
- `admin/templates/user/list.html`、`admin/templates/partials/header.html`:用户表格、筛选、
新增/重置弹窗、管理员导航和行内启停。
- `admin/static/js/app.js`、`admin/static/css/app.css`:敏感操作确认、共享重置弹窗、状态
标签和操作区样式。
- `admin/service/user_test.go`、`admin/user_integration_test.go`:角色、唯一性、筛选、事务、
Session 撤销、HTTP 权限和页面泄密回归测试。
## 验收结果
| 验收标准 | 结果 |
|---|---|
| 管理员可创建用户名大小写不敏感且唯一的采购员 | 通过 |
| 管理员可搜索并按状态筛选采购员 | 通过 |
| 管理员可启用和禁用采购员 | 通过 |
| 管理员可重置采购员密码,旧密码失效 | 通过 |
| 禁用或重置密码在同一事务撤销全部 Session | 通过 |
| 采购员可访问业务页但 `/users` 返回 403 | 通过 |
| 不提供公开注册、第二管理员和物理删除入口 | 通过 |
| 最后一个有效管理员不能被禁用 | 通过 |
| 写操作使用 POST、CSRF 和二次确认 | 通过 |
| 页面不泄露密码、哈希和 Session | 通过 |
| 1366×768 用户表格及弹窗可用 | 通过 |
| Go 1.23.0 构建、测试和 vet | 通过 |
## 测试
- 执行的命令:
```powershell
cd D:\chengma\cmautobuy\admin
gofmt -l .
go vet ./...
go build ./...
go test ./... -count=1
```
- 结果:全部通过;`gofmt -l .` 无输出。
- 浏览器验证:使用隔离的临时数据库,在 1366×768 以管理员进入 `/users`,打开
新增弹窗、创建采购员并打开该账号的重置密码弹窗;导航、筛选、表格、焦点、
目标用户名和操作按钮均正常。
- **没验证到的部分**:没有在真实多人同时操作的浏览器环境做人工竞态测试,唯一性、
最后管理员保护和 Session 原子撤销由 SQLite 集成测试覆盖;没有触发真实采购。
## 相关提交
- `eea0d65` feat: 实现 Admin 采购员账号管理 (#51)