Some checks failed
Build and Deploy (service.xpcool.com) / build-and-deploy (push) Failing after 54s
- 修正 status 列默认值为 0,避免历史失败记录被误标为成功
- 历史数据回填改为幂等更新,可重复执行
- 过滤未解析的 ${...} 配置占位符,优化 Bark 推送错误提示
- LogDetail 记录不存在时统一返回参数错误,避免暴露 SQL 细节
79 lines
6.4 KiB
Go
79 lines
6.4 KiB
Go
-- 017_notice_log_enhance.sql
|
||
-- 通知历史记录增强:notice_log 扩展字段(批次/类型统计/耗时/来源/重试/备注)
|
||
-- + 删除/清空/详情 接口权限 + 字典选项接口权限。
|
||
-- 幂等:ALTER TABLE ADD COLUMN 用 information_schema 判断(MySQL 8 不支持 COLUMN IF NOT EXISTS);
|
||
-- 菜单用 INSERT ... ON DUPLICATE KEY UPDATE;角色绑定用 INSERT IGNORE。
|
||
-- 依赖:016_user_notice_job.sql 已执行(notice_log / admin_menu / admin_role_menu 已存在)。
|
||
|
||
-- ============ 1) notice_log 扩展字段 ============
|
||
-- batch_id:同一次业务触发(如一次任务失败同时发 bark + pushplus)共用,便于按批次追溯
|
||
SET @has_col := (SELECT COUNT(*) FROM information_schema.COLUMNS WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME='notice_log' AND COLUMN_NAME='batch_id');
|
||
SET @sql := IF(@has_col=0, 'ALTER TABLE notice_log ADD COLUMN batch_id VARCHAR(32) NOT NULL DEFAULT '''' COMMENT ''批次号(同一次业务触发)'' AFTER id', 'SELECT 1');
|
||
PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
|
||
|
||
-- status:0待发送 1成功 2失败(result 为旧字段 1成功 0失败,保留兼容)
|
||
-- 默认 0(待发送):新增列时历史行先统一为 0,再由下方「历史数据回填」按 result 推导,
|
||
-- 若默认写 1 会导致历史失败记录被误标为成功。
|
||
SET @has_col := (SELECT COUNT(*) FROM information_schema.COLUMNS WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME='notice_log' AND COLUMN_NAME='status');
|
||
SET @sql := IF(@has_col=0, 'ALTER TABLE notice_log ADD COLUMN status TINYINT NOT NULL DEFAULT 0 COMMENT ''0待发送 1成功 2失败'' AFTER body', 'SELECT 1');
|
||
PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
|
||
|
||
-- retry_count:已重试次数
|
||
SET @has_col := (SELECT COUNT(*) FROM information_schema.COLUMNS WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME='notice_log' AND COLUMN_NAME='retry_count');
|
||
SET @sql := IF(@has_col=0, 'ALTER TABLE notice_log ADD COLUMN retry_count INT NOT NULL DEFAULT 0 COMMENT ''已重试次数'' AFTER error', 'SELECT 1');
|
||
PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
|
||
|
||
-- duration_ms:渠道接口耗时
|
||
SET @has_col := (SELECT COUNT(*) FROM information_schema.COLUMNS WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME='notice_log' AND COLUMN_NAME='duration_ms');
|
||
SET @sql := IF(@has_col=0, 'ALTER TABLE notice_log ADD COLUMN duration_ms INT NOT NULL DEFAULT 0 COMMENT ''渠道接口耗时(毫秒)'' AFTER retry_count', 'SELECT 1');
|
||
PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
|
||
|
||
-- source:触发来源 auto/manual/test
|
||
SET @has_col := (SELECT COUNT(*) FROM information_schema.COLUMNS WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME='notice_log' AND COLUMN_NAME='source');
|
||
SET @sql := IF(@has_col=0, 'ALTER TABLE notice_log ADD COLUMN source VARCHAR(20) NOT NULL DEFAULT ''auto'' COMMENT ''触发来源 auto/manual/test'' AFTER duration_ms', 'SELECT 1');
|
||
PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
|
||
|
||
-- remark:备注
|
||
SET @has_col := (SELECT COUNT(*) FROM information_schema.COLUMNS WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME='notice_log' AND COLUMN_NAME='remark');
|
||
SET @sql := IF(@has_col=0, 'ALTER TABLE notice_log ADD COLUMN remark VARCHAR(500) NOT NULL DEFAULT '''' COMMENT ''备注'' AFTER source', 'SELECT 1');
|
||
PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
|
||
|
||
-- 索引:渠道+时间、状态+时间、批次
|
||
SET @has_idx := (SELECT COUNT(*) FROM information_schema.STATISTICS WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME='notice_log' AND INDEX_NAME='idx_channel');
|
||
SET @sql := IF(@has_idx=0, 'ALTER TABLE notice_log ADD INDEX idx_channel (channel_code, created_at)', 'SELECT 1');
|
||
PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
|
||
|
||
SET @has_idx := (SELECT COUNT(*) FROM information_schema.STATISTICS WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME='notice_log' AND INDEX_NAME='idx_status');
|
||
SET @sql := IF(@has_idx=0, 'ALTER TABLE notice_log ADD INDEX idx_status (status, created_at)', 'SELECT 1');
|
||
PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
|
||
|
||
SET @has_idx := (SELECT COUNT(*) FROM information_schema.STATISTICS WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME='notice_log' AND INDEX_NAME='idx_batch');
|
||
SET @sql := IF(@has_idx=0, 'ALTER TABLE notice_log ADD INDEX idx_batch (batch_id)', 'SELECT 1');
|
||
PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
|
||
|
||
-- 历史数据回填:按旧字段 result 推导 status(幂等,可重复执行)
|
||
UPDATE notice_log SET status=1 WHERE result=1 AND status<>1;
|
||
UPDATE notice_log SET status=2 WHERE result=0 AND status<>2;
|
||
UPDATE notice_log SET source='test' WHERE event_type='test' AND source<>'test';
|
||
|
||
-- ============ 2) 菜单:通知历史记录(替换原「通知日志」并调整排序) ============
|
||
-- 982 原为「通知日志」,此处改名为「通知历史」以贴合需求(保留 id 以延续角色绑定)
|
||
UPDATE admin_menu SET name='通知历史', icon='mdi:history', component='system/notice/log/index', permission='notice:log', sort=3
|
||
WHERE id=982 AND type=1;
|
||
|
||
-- ============ 3) type=2 API 权限:通知历史记录 ============
|
||
-- 路径必须与 api/notice/notice.go 的 g.Meta path 完全一致(含 /api/service/admin 前缀)
|
||
INSERT INTO admin_menu (id, parent_id, name, icon, type, path, component, permission, sort, status, hidden, created_at, updated_at) VALUES
|
||
(9821, 982, '查询', '', 2, 'POST /api/service/admin/notice/log/list', '', 'notice:log:list', 1, 1, 0, NOW(), NOW()),
|
||
(9822, 982, '详情', '', 2, 'POST /api/service/admin/notice/log/detail', '', 'notice:log:detail', 2, 1, 0, NOW(), NOW()),
|
||
(9823, 982, '删除', '', 2, 'POST /api/service/admin/notice/log/delete', '', 'notice:log:delete', 3, 1, 0, NOW(), NOW()),
|
||
(9824, 982, '清空', '', 2, 'POST /api/service/admin/notice/log/clear', '', 'notice:log:clear', 4, 1, 0, NOW(), NOW()),
|
||
(9825, 982, '选项', '', 2, 'POST /api/service/admin/notice/log/options','', 'notice:log:options',5, 1, 1, NOW(), NOW())
|
||
ON DUPLICATE KEY UPDATE parent_id=VALUES(parent_id), name=VALUES(name), type=VALUES(type),
|
||
path=VALUES(path), permission=VALUES(permission), sort=VALUES(sort), status=VALUES(status),
|
||
hidden=VALUES(hidden), deleted_at=NULL;
|
||
|
||
-- ============ 4) 超管角色绑定 ============
|
||
INSERT IGNORE INTO admin_role_menu (role_id, menu_id, created_at, updated_at)
|
||
SELECT 1, id, NOW(), NOW() FROM admin_menu WHERE id IN (982, 9821, 9822, 9823, 9824, 9825);
|