Files
cmautobuy/docs/task/246-admin档口入库码后台批量回写.md
T
2026-08-15 17:09:09 +08:00

86 lines
5.2 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.
# 246 Admin:档口入库码后台批量回写与进度反馈
- 类型:需求
- 父级大工单:#14
- 所属 MVP / 版本:#224
- 状态:已完成
- 日期:2026-08-15
- Gitea 工单:http://ilaer.eicp.net:8418/chengma/cmautobuy/issues/246
## 背景与目标
原“回写顺运宝”在浏览器请求内同步处理,并把 20 条同时当成选择上限。每条记录可能执行
写前读取、删除旧值、写入新值和写后核对,数量增加后页面会长时间等待,也难以区分仍在
执行、请求超时和结果未知。
本工单允许采购员一次提交当前页全部选中记录,页面立即返回;Admin 在后台安全串行回写,
页面可以刷新查看批次进度和逐条结果。
## 最终方案
- 继续只使用 `syb_inner_code_records` 一张业务表,不新增批次表。MySQL schema v25 增加
`apply_batch_id`、`apply_queued_at`、批次索引,并让状态约束支持 `queued`。
- 提交时使用单个事务把全部选中且仍为 `ready` 的记录改为 `queued`。任一记录状态已变化,
整批回滚,避免部分入队和重复回写。
- HTTP 请求只负责校验顺运宝会话、落库排队和返回页面。Handler 使用单一互斥后台执行器,
每次最多读取 20 条,但每条仍原子领取为 `applying`,逐条执行既有“写前核验、最多一次
写入、写后复读”门禁。
- 页面按 `apply_batch_id` 从业务表聚合进度,使用文字和原生 `progress` 同时显示总数、排队中、
回写中、成功、已存在、跳过、失败、需核对,并用普通 GET 链接手工刷新;模块切换状态会
保留当前批次标识。
- 后台异常时,同批次 `applying` 立即转 `needs_check`,`queued` 恢复 `ready`;Admin 重启时
执行相同安全原则。两种情况都不自动重放真实远端写入。
- 与建单方案一致;实现时进一步补强了“后台进程未退出但执行器异常”的立即状态收敛,避免
必须等到下次重启才能看到 `applying` 的未知结果。
## 改了哪些
- `admin/repository/mysql_db.go`、`admin/repository/mysql_db_integration_test.go`:追加 v25 迁移、
schema 自检和 v24 升级/重放用例。
- `admin/model/inner_code.go`、`admin/repository/inner_code.go`:增加排队状态、单表批次字段、
原子入队/领取、进度聚合、异常和启动恢复。
- `admin/service/inner_code_apply.go`、`admin/service/inner_code_match.go`、
`admin/service/inner_code_page.go`:实现后台分组消费并让排队记录继续占用已匹配明细。
- `admin/handler/web/inner_code.go`、`admin/handler/web/web.go`:提交后立即重定向,后台批次串行
执行并在异常时收敛状态。
- `admin/templates/inner_code/list.html`、`admin/static/css/app.css`、`admin/static/js/app.js`:增加
可访问的进度区、排队中状态、手工刷新和新的提交反馈。
- `admin/**/*_test.go`:覆盖超过 20 条入队、整批冲突回滚、进度聚合、异常恢复、页面语义和
模块状态保留。
- `docs/admin/03-data-model.md`、`docs/admin/05-ui-specification.md`、
`docs/admin/08-顺运宝接口.md`:同步稳定数据、页面和远端安全约束。
## 验收结果
| 验收标准 | 结果 |
|---|---|
| 超过 20 条可一次提交,HTTP 页面不等待远端处理 | 通过:45 条单元测试一次原子入队;Handler 排队后立即 303 |
| 后台每次最多读取 20 条,远端仍逐条且最多写一次 | 通过:分组常量和既有写入未知结果不重试测试通过 |
| 页面显示批次进度并可手工刷新 | 通过:模板语义、原生 `progress`、刷新链接和状态保留测试通过 |
| 重复提交或并发状态变化不会部分入队 | 通过:条件更新、受影响行数校验和事务回滚测试通过 |
| 后台异常和 Admin 重启按远端风险区分恢复 | 通过:`applying → needs_check`、`queued → ready` 自动化测试通过 |
| MySQL v24 → v25、空库和重复迁移 | 部分通过:用例已编写并通过编译;真实 MySQL 8.4 测试环境未启用 |
| 固定 Go 1.23.0 全量检查 | 通过 |
| 不新增批次表、不修改 Client | 通过 |
## 测试
- 执行的命令:
- `$env:GOTOOLCHAIN='go1.23.0'; go vet ./...; go build ./...; go test ./... -count=1`
- `go test ./repository -run 'TestMySQLMigrate_(真实MySQL8|V24升级V25且后台队列状态有效)$' -count=1 -v`
- `git diff --check`
- 结果:固定 Go 1.23.0 的 vet、全量构建和全量测试通过;格式检查通过。MySQL 定向用例因
未设置 `CMAUTOBUY_MYSQL_TEST=1` 而按安全门禁跳过。
- **没验证到的部分**:当前环境没有名称以 `_test` 结尾的独立 MySQL 8.4 测试库,未实际执行
v24→v25、空库和重复迁移 DDL;未向真实顺运宝发送档口入库码写请求;未在浏览器中人工
观察长批次实时进度。禁止使用生产 `autobuy` 数据库或正式货运单代替这些测试。
## 遗留问题
上线前必须先备份生产数据库,并在独立 MySQL 8.4 `_test` 库执行 v24→v25 和重复迁移;
真实顺运宝写入需要由用户选择测试货运单人工验收。
## 相关提交
- `f8f22a1` feat: 档口入库码后台批量回写 (#246)