service.xpcool.com/docs/change-log/2026-09-14.md
夏犀麟 e79690518e
Some checks failed
Build and Deploy (service.xpcool.com) / build-and-deploy (push) Failing after 54s
fix(notice): 修复通知历史状态回填与配置占位符问题
- 修正 status 列默认值为 0,避免历史失败记录被误标为成功
- 历史数据回填改为幂等更新,可重复执行
- 过滤未解析的 ${...} 配置占位符,优化 Bark 推送错误提示
- LogDetail 记录不存在时统一返回参数错误,避免暴露 SQL 细节
2026-09-14 23:53:56 +08:00

96 lines
7.5 KiB
Go
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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.

# 变更日志 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`