service.xpcool.com/manifest/sql/016_user_notice_job.sql

153 lines
12 KiB
Go
Raw Permalink 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.

-- 016_user_notice_job.sql
-- 用户管理扩展 + 通知模块 + 自动任务模块建表 + 菜单 + 种子
-- 幂等ALTER TABLE ADD COLUMN IF NOT EXISTSMySQL 8 不支持 COLUMN IF NOT EXISTS用存储过程判断
-- 菜单用 INSERT ... ON DUPLICATE KEY UPDATE种子用 INSERT IGNORE
-- 依赖service 主库admin_menu/admin_role_menu/admin_user 已存在
-- ============ 1) 用户表扩展Bark 设备ID / pushplus token ============
SET @has_col := (SELECT COUNT(*) FROM information_schema.COLUMNS WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME='admin_user' AND COLUMN_NAME='bark_device_id');
SET @sql := IF(@has_col=0, 'ALTER TABLE admin_user ADD COLUMN bark_device_id VARCHAR(200) NOT NULL DEFAULT '''' COMMENT ''Bark设备ID'' AFTER status', 'SELECT 1');
PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
SET @has_col := (SELECT COUNT(*) FROM information_schema.COLUMNS WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME='admin_user' AND COLUMN_NAME='pushplus_token');
SET @sql := IF(@has_col=0, 'ALTER TABLE admin_user ADD COLUMN pushplus_token VARCHAR(200) NOT NULL DEFAULT '''' COMMENT ''pushplus token'' AFTER bark_device_id', 'SELECT 1');
PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
-- ============ 2) 通知渠道表 ============
CREATE TABLE IF NOT EXISTS `notice_channel` (
`id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
`code` VARCHAR(50) NOT NULL DEFAULT '' COMMENT '渠道编码 bark/pushplus/webhook',
`name` VARCHAR(100) NOT NULL DEFAULT '' COMMENT '渠道名称',
`enabled` TINYINT NOT NULL DEFAULT 1 COMMENT '是否启用 0 1',
`config` VARCHAR(1000) NOT NULL DEFAULT '' COMMENT '渠道配置JSON( bark baseUrl)',
`remark` VARCHAR(500) NOT NULL DEFAULT '' COMMENT '备注',
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
`updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
UNIQUE KEY `uk_code` (`code`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='通知渠道配置';
-- ============ 3) 通知规则表 ============
CREATE TABLE IF NOT EXISTS `notice_rule` (
`id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
`name` VARCHAR(100) NOT NULL DEFAULT '' COMMENT '规则名称',
`event_type` VARCHAR(50) NOT NULL DEFAULT '' COMMENT '事件类型 job_done/job_fail/security_alert/recruit_daily',
`channel_codes` VARCHAR(500) NOT NULL DEFAULT '' COMMENT '渠道编码 JSON 数组 ["bark","pushplus"]',
`user_ids` VARCHAR(500) NOT NULL DEFAULT '' COMMENT '接收用户ID JSON 数组 [1,2]',
`title_template` VARCHAR(200) NOT NULL DEFAULT '' COMMENT '标题模板(支持 {var} 占位符)',
`body_template` VARCHAR(1000) NOT NULL DEFAULT '' COMMENT '内容模板',
`enabled` TINYINT NOT NULL DEFAULT 1 COMMENT '是否启用 0 1',
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
`updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
KEY `idx_event` (`event_type`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='通知规则(事件渠道人员启用)';
-- ============ 4) 通知发送记录 ============
CREATE TABLE IF NOT EXISTS `notice_log` (
`id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
`rule_id` BIGINT UNSIGNED NOT NULL DEFAULT 0 COMMENT '规则ID',
`event_type` VARCHAR(50) NOT NULL DEFAULT '' COMMENT '事件类型',
`channel_code` VARCHAR(50) NOT NULL DEFAULT '' COMMENT '渠道编码',
`user_id` BIGINT UNSIGNED NOT NULL DEFAULT 0 COMMENT '接收用户ID',
`target` VARCHAR(500) NOT NULL DEFAULT '' COMMENT '发送目标(设备key/token)',
`title` VARCHAR(500) NOT NULL DEFAULT '' COMMENT '标题',
`body` VARCHAR(2000) NOT NULL DEFAULT '' COMMENT '内容',
`result` TINYINT NOT NULL DEFAULT 0 COMMENT '1成功 0失败',
`error` VARCHAR(1000) NOT NULL DEFAULT '' COMMENT '错误信息',
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
KEY `idx_event` (`event_type`),
KEY `idx_created` (`created_at`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='通知发送记录';
-- ============ 5) 自动任务定义 ============
CREATE TABLE IF NOT EXISTS `auto_job` (
`id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
`name` VARCHAR(100) NOT NULL DEFAULT '' COMMENT '任务名称',
`code` VARCHAR(100) NOT NULL DEFAULT '' COMMENT '任务编码(唯一,映射业务函数)',
`job_type` VARCHAR(32) NOT NULL DEFAULT 'gcron' COMMENT '任务类型',
`cron_expr` VARCHAR(64) NOT NULL DEFAULT '' COMMENT 'cron 表达式(6: )',
`enabled` TINYINT NOT NULL DEFAULT 1 COMMENT '是否启用 0 1',
`remark` VARCHAR(500) NOT NULL DEFAULT '' COMMENT '备注',
`last_run_at` DATETIME NULL DEFAULT NULL COMMENT '上次运行时间',
`last_result` TINYINT NOT NULL DEFAULT 0 COMMENT '0未运行 1成功 2失败',
`last_error` VARCHAR(1000) NOT NULL DEFAULT '' COMMENT '上次错误',
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
`updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
UNIQUE KEY `uk_code` (`code`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='自动任务定义';
-- ============ 6) 自动任务运行日志 ============
CREATE TABLE IF NOT EXISTS `auto_job_log` (
`id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
`job_id` BIGINT UNSIGNED NOT NULL DEFAULT 0 COMMENT '任务ID',
`run_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '运行时间',
`result` TINYINT NOT NULL DEFAULT 0 COMMENT '1成功 2失败',
`error` VARCHAR(1000) NOT NULL DEFAULT '' COMMENT '错误信息',
`summary` VARCHAR(1000) NOT NULL DEFAULT '' COMMENT '运行摘要',
`duration_ms` INT NOT NULL DEFAULT 0 COMMENT '耗时(毫秒)',
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
KEY `idx_job` (`job_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='自动任务运行日志';
-- ============ 7) 种子通知渠道 ============
INSERT INTO notice_channel (id, code, name, enabled, config, remark) VALUES
(1, 'bark', 'Bark(iOS)', 1, '{"baseUrl":"http://bark:8080"}', 'Bark 自建服务容器网络内访问 bark:8080'),
(2, 'pushplus', 'pushplus', 1, '{}', '微信推送token 在用户资料中维护')
ON DUPLICATE KEY UPDATE name=VALUES(name), enabled=VALUES(enabled), config=VALUES(config), remark=VALUES(remark);
-- ============ 8) 种子通知规则 ============
INSERT INTO notice_rule (id, name, event_type, channel_codes, user_ids, title_template, body_template, enabled) VALUES
(1, '安全告警', 'security_alert', '["bark"]', '[1]', '服务器安全告警', '{{summary}}', 1),
(2, '任务完成', 'job_done', '["bark"]', '[1]', '任务完成: {{jobName}}', '{{summary}}', 1),
(3, '任务失败', 'job_fail', '["bark","pushplus"]', '[1]', ' 任务失败: {{jobName}}', '{{summary}}', 1)
ON DUPLICATE KEY UPDATE name=VALUES(name), event_type=VALUES(event_type), channel_codes=VALUES(channel_codes),
user_ids=VALUES(user_ids), title_template=VALUES(title_template), body_template=VALUES(body_template), enabled=VALUES(enabled);
-- ============ 9) 种子自动任务现有 gcron 任务纳管 ============
INSERT INTO auto_job (id, name, code, job_type, cron_expr, enabled, remark) VALUES
(1, '招聘公告每日抓取', 'recruit-crawl-daily', 'gcron', '0 0 3 * * *', 1, '每日03:00 增量抓取招聘公告'),
(2, '招聘公告每日推送', 'recruit-push-daily', 'gcron', '0 0 8 * * *', 1, '每日08:00 推送订阅公告( push_subscription 配置)')
ON DUPLICATE KEY UPDATE name=VALUES(name), cron_expr=VALUES(cron_expr), enabled=VALUES(enabled), remark=VALUES(remark);
-- ============ 10) 菜单人员管理改名 用户管理 ============
UPDATE admin_menu SET name='用户管理' WHERE name='人员管理' AND type=1;
-- 补充兜底若没有名为人员管理的菜单如叫管理员管理 component='system/admin/index' 的改名为用户管理
UPDATE admin_menu SET name='用户管理' WHERE component='system/admin/index' AND type=1 AND name != '用户管理';
-- ============ 11) 菜单通知中心 + 自动任务 ============
INSERT INTO admin_menu (id, parent_id, name, icon, type, path, component, permission, sort, status, hidden, created_at, updated_at) VALUES
(98, 0, '通知中心', 'mdi:bell-ring-outline', 1, '/notice', '', 'notice:center', 8, 1, 0, NOW(), NOW()),
(980, 98, '通知规则', 'mdi:bell-cog-outline', 1, 'rule', 'system/notice/rule/index', 'notice:rule', 1, 1, 0, NOW(), NOW()),
(981, 98, '通知渠道', 'mdi:router-wireless', 1, 'channel', 'system/notice/channel/index', 'notice:channel', 2, 1, 0, NOW(), NOW()),
(982, 98, '通知日志', 'mdi:history', 1, 'log', 'system/notice/log/index', 'notice:log', 3, 1, 0, NOW(), NOW()),
(99, 0, '自动任务', 'mdi:clock-outline', 1, '/auto-job','', 'job:center', 9, 1, 0, NOW(), NOW()),
(990, 99, '任务管理', 'mdi:calendar-clock', 1, 'list', 'system/auto-job/list/index', 'job:list', 1, 1, 0, NOW(), NOW()),
(991, 99, '任务日志', 'mdi:file-clock-outline', 1, 'log', 'system/auto-job/log/index', 'job:log', 2, 1, 0, NOW(), NOW())
ON DUPLICATE KEY UPDATE parent_id=VALUES(parent_id), name=VALUES(name), icon=VALUES(icon), type=VALUES(type),
path=VALUES(path), component=VALUES(component), permission=VALUES(permission), sort=VALUES(sort),
status=VALUES(status), hidden=VALUES(hidden), deleted_at=NULL;
-- ============ 12) type=2 API 权限 ============
INSERT INTO admin_menu (id, parent_id, name, icon, type, path, component, permission, sort, status, hidden, created_at, updated_at) VALUES
(9801, 980, '查询', '', 2, 'POST /api/service/admin/notice/rule/list', '', 'notice:rule:list', 1, 1, 0, NOW(), NOW()),
(9802, 980, '保存', '', 2, 'POST /api/service/admin/notice/rule/save', '', 'notice:rule:save', 2, 1, 0, NOW(), NOW()),
(9803, 980, '删除', '', 2, 'POST /api/service/admin/notice/rule/delete', '', 'notice:rule:delete', 3, 1, 0, NOW(), NOW()),
(9804, 980, '测试', '', 2, 'POST /api/service/admin/notice/test', '', 'notice:test', 4, 1, 0, NOW(), NOW()),
(9811, 981, '查询', '', 2, 'POST /api/service/admin/notice/channel/list', '', 'notice:channel:list', 1, 1, 0, NOW(), NOW()),
(9812, 981, '保存', '', 2, 'POST /api/service/admin/notice/channel/save', '', 'notice:channel:save', 2, 1, 0, NOW(), NOW()),
(9821, 982, '查询', '', 2, 'POST /api/service/admin/notice/log/list', '', 'notice:log:list', 1, 1, 0, NOW(), NOW()),
(9901, 990, '查询', '', 2, 'POST /api/service/admin/auto-job/list', '', 'job:list:query', 1, 1, 0, NOW(), NOW()),
(9902, 990, '保存', '', 2, 'POST /api/service/admin/auto-job/save', '', 'job:list:save', 2, 1, 0, NOW(), NOW()),
(9903, 990, '触发', '', 2, 'POST /api/service/admin/auto-job/trigger', '', 'job:list:trigger', 3, 1, 0, NOW(), NOW()),
(9911, 991, '查询', '', 2, 'POST /api/service/admin/auto-job/log/list', '', 'job:log:list', 1, 1, 0, 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;
-- ============ 13) 超管角色绑定 ============
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 (98,980,981,982,99,990,991,9801,9802,9803,9804,9811,9812,9821,9901,9902,9903,9911);