feat(notification): 新增通知渠道及绑定管理功能

- 新增数据库表 notification_channels, recruiter_channel_bindings 支持多渠道通知绑定
- 在 notifications 表中新增 channel_id 关联通知渠道
- 增加默认通知渠道示例数据插入脚本(企业微信、钉钉、飞书)
- 实现 NotificationChannel 和 RecruiterChannelBinding 两个ORM模型及关联关系
- 增加通知渠道管理API,支持增删改查及启用停用操作
- 实现通知渠道类型枚举及配置验证
- 新增招聘者与通知渠道绑定管理路由,支持绑定关系创建、更新和删除
- 在招聘者模块中集成通知渠道绑定管理相关接口
- 增加对应的请求参数、响应模型及数据校验模型
- 更新数据库配置和依赖注入,支持通知渠道服务
- 完善接口响应的错误处理和成功提示信息
- 保证所有新增代码符合项目代码风格和结构规范
This commit is contained in:
2026-03-25 10:39:33 +08:00
parent 91b6808d45
commit eedaac69b0
22 changed files with 3499 additions and 911 deletions

View File

@@ -163,13 +163,50 @@ CREATE TABLE IF NOT EXISTS evaluations (
);
-- ============================================
-- 7. 通知记录
-- 7. 通知渠道
-- ============================================
CREATE TABLE IF NOT EXISTS notification_channels (
id VARCHAR(64) PRIMARY KEY,
name VARCHAR(128) NOT NULL, -- 渠道名称
channel_type VARCHAR(32) NOT NULL, -- 渠道类型: wechat_work, dingtalk, email, feishu, webhook
config JSON NOT NULL, -- 渠道配置JSON
status VARCHAR(32) DEFAULT 'active', -- active, inactive
description TEXT, -- 描述
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
INDEX idx_channel_type (channel_type),
INDEX idx_status (status)
);
-- ============================================
-- 8. 招聘者与通知渠道绑定关系表(多对多)
-- ============================================
CREATE TABLE IF NOT EXISTS recruiter_channel_bindings (
id VARCHAR(64) PRIMARY KEY,
recruiter_id VARCHAR(64) NOT NULL,
channel_id VARCHAR(64) NOT NULL,
is_enabled TINYINT(1) DEFAULT 1, -- 是否启用该渠道
notify_on_new_candidate TINYINT(1) DEFAULT 1, -- 新候选人时通知
notify_on_evaluation TINYINT(1) DEFAULT 1, -- 完成评价时通知
notify_on_high_score TINYINT(1) DEFAULT 0, -- 高分候选人时通知
high_score_threshold INT DEFAULT 85, -- 高分阈值
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (recruiter_id) REFERENCES recruiters(id) ON DELETE CASCADE,
FOREIGN KEY (channel_id) REFERENCES notification_channels(id) ON DELETE CASCADE,
UNIQUE KEY uk_recruiter_channel (recruiter_id, channel_id),
INDEX idx_recruiter_id (recruiter_id),
INDEX idx_channel_id (channel_id)
);
-- ============================================
-- 9. 通知记录表
-- ============================================
CREATE TABLE IF NOT EXISTS notifications (
id VARCHAR(64) PRIMARY KEY,
candidate_id VARCHAR(64) NOT NULL,
evaluation_id VARCHAR(64),
channel VARCHAR(32) NOT NULL, -- WECHAT_WORK, DINGTALK, EMAIL, WEBHOOK
channel_id VARCHAR(64), -- 关联的通知渠道ID
channel VARCHAR(32) NOT NULL, -- 渠道类型: WECHAT_WORK, DINGTALK, EMAIL, FEISHU, WEBHOOK
content TEXT,
status VARCHAR(32) DEFAULT 'PENDING', -- PENDING, SENT, FAILED
error_message TEXT,
@@ -177,13 +214,36 @@ CREATE TABLE IF NOT EXISTS notifications (
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (candidate_id) REFERENCES candidates(id) ON DELETE CASCADE,
FOREIGN KEY (evaluation_id) REFERENCES evaluations(id) ON DELETE SET NULL,
FOREIGN KEY (channel_id) REFERENCES notification_channels(id) ON DELETE SET NULL,
INDEX idx_candidate_id (candidate_id),
INDEX idx_channel_id (channel_id),
INDEX idx_status (status),
INDEX idx_created_at (created_at)
);
-- ============================================
-- 8. 插入默认评价方案
-- 10. 插入默认通知渠道(可选)
-- ============================================
INSERT INTO notification_channels (id, name, channel_type, config, description) VALUES
('demo_wechat', '企业微信通知', 'wechat_work',
'{"webhook_url": "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=YOUR_KEY", "secret": ""}',
'企业微信机器人通知渠道(示例配置)')
ON DUPLICATE KEY UPDATE name = VALUES(name);
INSERT INTO notification_channels (id, name, channel_type, config, description) VALUES
('demo_dingtalk', '钉钉通知', 'dingtalk',
'{"access_token": "YOUR_ACCESS_TOKEN", "sign_secret": ""}',
'钉钉机器人通知渠道(示例配置)')
ON DUPLICATE KEY UPDATE name = VALUES(name);
INSERT INTO notification_channels (id, name, channel_type, config, description) VALUES
('demo_feishu', '飞书通知', 'feishu',
'{"feishu_webhook": "https://open.feishu.cn/open-apis/bot/v2/hook/YOUR_TOKEN", "feishu_secret": ""}',
'飞书机器人通知渠道(示例配置)')
ON DUPLICATE KEY UPDATE name = VALUES(name);
-- ============================================
-- 11. 插入默认评价方案
-- ============================================
INSERT INTO evaluation_schemas (id, name, description, dimensions, weights, is_default) VALUES
('general', '通用评价方案', '适用于各类岗位的通用评价方案',