Some checks failed
Build and Deploy (service.xpcool.com) / build-and-deploy (push) Failing after 54s
- 修正 status 列默认值为 0,避免历史失败记录被误标为成功
- 历史数据回填改为幂等更新,可重复执行
- 过滤未解析的 ${...} 配置占位符,优化 Bark 推送错误提示
- LogDetail 记录不存在时统一返回参数错误,避免暴露 SQL 细节
96 lines
7.5 KiB
Go
96 lines
7.5 KiB
Go
# 变更日志 — 2026-09-14
|
||
|
||
## 请求
|
||
|
||
通知模块新增「通知历史记录」表格界面:有分页、有查询,记录每次通知的渠道、类型、分组、详细内容等。
|
||
前端项目 `E:\Project\admin.xpcool.com` 一起实现并联调。
|
||
|
||
## 变更
|
||
|
||
### 后端 —— 通知历史记录能力扩展
|
||
|
||
- `api/notice/notice.go` — 通知历史记录契约扩展:
|
||
- `NoticeLogItem` 由 11 字段扩到 27 字段(新增 `batchId`/`ruleName`/`eventName`/`noticeType`/`typeName`/
|
||
`group`/`groupName`/`channelName`/`userName`/`status`/`statusName`/`retryCount`/`durationMs`/`source`/`remark`)。
|
||
- `NoticeLogListReq` 新增 `keyword`/`noticeType`/`group`/`userId`/`batchId`/`status`/`orderBy`/`orderDir`;
|
||
`NoticeLogListRes` 新增 `stats` 统计概览。
|
||
- 新增端点:`POST /notice/log/detail`(详情)、`/notice/log/delete`(批量删除)、
|
||
`/notice/log/clear`(按保留天数/时间范围清空)、`/notice/log/options`(字典选项)。
|
||
- `internal/model/dto/notice_meta.go`(**新增**)— 通知字典:渠道(bark/pushplus/webhook/email/internal)、
|
||
事件(7 种)、类型(job/security/recruit/test/manual/system)、分组(auto_job/server/recruitment/system)
|
||
的编码常量 + 中文名映射 + 选项下发 + 事件/类型/分组三级推导函数。
|
||
- `internal/model/dto/notice.go` — `NoticeLogVO`/`NoticeLogFilter` 同步扩展,并新增 `Normalize()`
|
||
归一化分页/排序(`Status` 与兼容字段 `Result` 的优先级合并)。
|
||
- `internal/model/entity/notice.go`、`internal/model/do/notice.go` — `NoticeLog` 新增
|
||
`batch_id`/`status`/`retry_count`/`duration_ms`/`source`/`remark` 六个字段。
|
||
- `internal/service/notice/notice.go` —
|
||
- `LogList`:重写为多维筛选(关键字/类型/分组/事件/渠道/接收人/批次/状态/时间范围/排序)+ 统计概览,
|
||
列表与统计共用同一套 `logQuery` 条件保证口径一致;批量补齐规则名与接收人(避免 N+1)。
|
||
- 新增 `LogDetail`/`LogDelete`/`LogClear`。
|
||
- `Send` 引入 `batchId`(同一次业务触发的多条投递共用);`deliver`/`Test` 记录耗时、来源、状态、备注。
|
||
- 写库统一改用 `do.NoticeLog` / `do.NoticeRule` / `do.NoticeChannel`(原先用 `map[string]interface{}`,
|
||
不符合 AGENTS.md「数据库操作必须用 DO 对象」)。
|
||
- `internal/controller/notice/notice.go` — 新增 `LogDetail`/`LogDelete`/`LogClear`/`MetaOptions`,
|
||
并抽出 `toLogItem`/`toMetaItems` 做 dto → 契约转换。
|
||
- `manifest/sql/017_notice_log_enhance.sql`(**新增**)— `notice_log` 加 6 列 + 3 个索引;
|
||
按旧字段 `result` 回填 `status`;菜单 982 改名「通知历史」;新增 5 条 type=2 接口权限
|
||
(`notice:log:list/detail/delete/clear/options`);超管角色绑定。
|
||
|
||
### 前端 —— `E:\Project\admin.xpcool.com`
|
||
|
||
- `apps/web-tdesign/src/api/notice.ts` — 通知历史记录 API 客户端:类型与查询参数扩展,
|
||
新增 `getNoticeLogDetail` / `deleteNoticeLog` / `clearNoticeLog` / `getNoticeMetaOptions`,
|
||
以及 `NOTICE_STATUS_OPTIONS` / `noticeStatusTheme` 等展示辅助。
|
||
- `apps/web-tdesign/src/views/system/notice/log/index.vue` — **重写**为完整「通知历史」页面:
|
||
- 顶部 4 张统计卡(总数/成功/失败/成功率),随筛选条件同步刷新;
|
||
- 筛选区 9 个条件(时间范围、关键字、分组、类型、事件、渠道、接收人、状态、排序);
|
||
- vxe 表格:多选列 + 通知时间/分组/类型/事件/渠道/接收人/标题/详细内容/结果/耗时/错误 + 行操作;
|
||
- 详情抽屉(基本信息 + 标题/内容/目标/错误分区展示,均支持一键复制);
|
||
- 批量删除、清空历史(可选「保留最近 N 天」);按权限码控制按钮显隐。
|
||
|
||
### 联调
|
||
|
||
- 本地库执行 `017_notice_log_enhance.sql`:`notice_log` 现 17 列、3 个新索引;
|
||
菜单 `982 / 9821-9825` 就位;14 条历史失败记录 `status` 正确回填为 2。
|
||
- 后端 5 个新接口 + 原有 list 全部通过 RBAC 权限映射,返回 `code=0`。
|
||
- 真实投递一条测试通知,验证 `batchId` / `durationMs` / `source` / `userName` / `target` / `remark`
|
||
六项新字段正确落库与回显;统计概览 `1/0/1` 与筛选条件联动正确。
|
||
- 经前端 Vite 代理(20100 → 10100)完整跑通 登录 → 字典选项 → 分页列表 → 详情。
|
||
- 前端 `vue-tsc` 类型检查、`oxfmt` 格式检查、`oxlint` 全部 0 错误。
|
||
- **联调中修复 1 个缺陷**:`LogDetail` 对不存在的 ID 会把 `sql.ErrNoRows` 包装上抛,
|
||
被 gf 归为内部错误 `code=50` 并回显 SQL 细节;改为与项目既有写法一致
|
||
(忽略 Scan 错误、以 `Id==0` 判定),现返回 `code=10001`「通知记录不存在」。
|
||
|
||
## 决策与理由
|
||
|
||
- **类型/分组不落库,由 `event_type` 派生**:二者与事件是一对多的确定映射,落库会引入双写不一致;
|
||
改为只存事件编码,展示与筛选在服务层推导(`NoticeEventToType` / `NoticeTypeToGroup`)。
|
||
- **`status` 与旧的 `result` 并存**:`result` 是已有数据在用的字段(1成功/0失败),直接改语义会破坏历史数据。
|
||
新增 `status`(0待发送/1成功/2失败)表达三态,查询时用 `(status=1 OR (status=0 AND result=1))` 兼容历史行。
|
||
- **字典选项由后端 `/notice/log/options` 统一下发**:前端原先把事件类型硬编码在页面里
|
||
(`NOTICE_EVENT_OPTIONS` 只有 4 项,且与 `notice_rule.event_type` 种子语义有偏差),
|
||
新增事件就要改两处;改为后端单一事实源,前端只做渲染。
|
||
- **清空提供「保留最近 N 天」而非纯全清**:历史记录是排查问题的依据,全清不可逆;
|
||
默认保留 30 天,`keepDays=0` 才真正全清,属于对误操作的兜底。
|
||
- **列表与统计共用 `logQuery`**:避免"列表按分组筛选、统计按全量"这类口径不一致,
|
||
前端统计卡与表格永远对同一批数据。
|
||
- **迁移脚本中 `status` 默认值取 0 而非 1**:`ALTER TABLE ADD COLUMN ... DEFAULT 1` 会把**所有历史行**
|
||
一并置为 1(含失败记录),造成"历史失败记录显示成功"。改为默认 0 后按 `result` 回填,语义正确且可重跑。
|
||
- **提示文案与枚举中文名收口到 `dto` 层**:中文名映射只在 `notice_meta.go` 定义一次,
|
||
API、服务、前端展示三处复用,避免同义词漂移。
|
||
|
||
## 待办与风险
|
||
|
||
- ⚠️ **`internal/service/recruitment/noise_test.go` 是 0 字节空文件**(未跟踪),会让
|
||
`go build ./...` 与 `go test ./...` 直接报 `expected 'package', found 'EOF'`。
|
||
本次联调为编译通过曾临时移走,**已原样还原**;需删除该文件或补上包声明。
|
||
- ⚠️ 工作区另有他人未提交改动:`internal/service/recruitment/bark.go` 修改、
|
||
`live_diag_test.go` 与 `testdata/rszk.html` 删除;前端 `api/wallpaper.ts`、
|
||
`views/wallpaper/*` 处于暂存状态。均非本次范围。
|
||
- 手动「测试发送」在目标凭据为空时会直接返回参数错误、**不写历史记录**(沿用原有行为)。
|
||
若希望失败尝试也可追溯,需在 `Test` 的提前返回分支补记日志。
|
||
- 历史记录只增不减,长期需要定期清理策略(目前靠页面「清空」手动处理),
|
||
后续可考虑挂到 `auto_job` 定时任务上。
|
||
- 本地联调环境:Node 22.22.2 + corepack `pnpm@11.16.0`;后端 10100、前端 dev 20100,
|
||
前端 `vite.config.ts` 已把 `/api/service` 代理到 `http://localhost:10100`。
|