Files
water-management-system/db/postgresql/V2__alert_engine.sql
T

123 lines
6.3 KiB
SQL
Raw Normal View History

-- =============================================
-- 智慧水务管理系统 - 报警规则引擎 + 报警管理中心 DDL
-- 版本: V2
-- =============================================
-- ==================== 报警规则定义 ====================
CREATE TABLE IF NOT EXISTS prod_alert_rule (
id BIGSERIAL PRIMARY KEY,
rule_name VARCHAR(100) NOT NULL,
rule_code VARCHAR(50) UNIQUE,
description TEXT,
device_type VARCHAR(30),
metric_key VARCHAR(50) NOT NULL,
alert_level VARCHAR(10) NOT NULL DEFAULT 'general', -- general/important/urgent
condition_expr TEXT NOT NULL, -- JSON: {"op":"AND","conditions":[{"metric":"pressure","operator":">","threshold":0.8},...]}
threshold_value DECIMAL(12,4), -- 简单阈值(向后兼容)
debounce_sec INT DEFAULT 300,
notify_channels VARCHAR(200), -- 逗号分隔: sms,wechat,app,email
notify_template VARCHAR(500), -- 通知模板
enabled SMALLINT DEFAULT 1,
priority INT DEFAULT 0, -- 规则优先级
effective_start TIME, -- 生效开始时间
effective_end TIME, -- 生效结束时间
created_by BIGINT,
updated_by BIGINT,
deleted SMALLINT DEFAULT 0,
created_time TIMESTAMP DEFAULT NOW(),
updated_time TIMESTAMP DEFAULT NOW()
);
COMMENT ON TABLE prod_alert_rule IS '报警规则定义表';
COMMENT ON COLUMN prod_alert_rule.alert_level IS '报警等级: general(一般)/important(重要)/urgent(紧急)';
COMMENT ON COLUMN prod_alert_rule.condition_expr IS '条件表达式JSON: 支持AND/OR组合条件';
-- ==================== 报警记录(全生命周期) ====================
CREATE TABLE IF NOT EXISTS prod_alert_record (
id BIGSERIAL PRIMARY KEY,
rule_id BIGINT REFERENCES prod_alert_rule(id),
rule_name VARCHAR(100),
device_id BIGINT,
device_sn VARCHAR(100),
device_name VARCHAR(200),
area VARCHAR(50),
metric_key VARCHAR(50) NOT NULL,
metric_value DECIMAL(12,4),
threshold_value VARCHAR(50),
alert_level VARCHAR(10) NOT NULL DEFAULT 'general',
title VARCHAR(200),
message TEXT,
-- 生命周期状态: 0=活跃 1=已确认 2=已派单 3=处理中 4=已处理 5=已归档
status INT DEFAULT 0,
confirmed_by BIGINT,
confirmed_time TIMESTAMP,
dispatch_time TIMESTAMP,
assignee_id BIGINT,
assignee_name VARCHAR(50),
handler_id BIGINT,
handler_name VARCHAR(50),
handle_result TEXT,
handle_time TIMESTAMP,
archive_time TIMESTAMP,
archive_reason VARCHAR(500),
resolved_at TIMESTAMP,
created_time TIMESTAMP DEFAULT NOW(),
updated_time TIMESTAMP DEFAULT NOW(),
deleted SMALLINT DEFAULT 0
);
COMMENT ON TABLE prod_alert_record IS '报警记录表(全生命周期)';
CREATE INDEX IF NOT EXISTS idx_alert_record_time ON prod_alert_record(created_time DESC);
CREATE INDEX IF NOT EXISTS idx_alert_record_device ON prod_alert_record(device_sn, created_time DESC);
CREATE INDEX IF NOT EXISTS idx_alert_record_status ON prod_alert_record(status);
CREATE INDEX IF NOT EXISTS idx_alert_record_level ON prod_alert_record(alert_level);
CREATE INDEX IF NOT EXISTS idx_alert_record_area ON prod_alert_record(area);
-- ==================== 报警通知记录 ====================
CREATE TABLE IF NOT EXISTS prod_alert_notification (
id BIGSERIAL PRIMARY KEY,
alert_record_id BIGINT REFERENCES prod_alert_record(id),
rule_id BIGINT,
channel VARCHAR(30) NOT NULL, -- sms/wechat/app/email
recipient VARCHAR(100) NOT NULL, -- 接收人标识
recipient_name VARCHAR(50),
title VARCHAR(200),
content TEXT,
status INT DEFAULT 0, -- 0=待发送 1=已发送 2=发送失败 3=已读
send_time TIMESTAMP,
read_time TIMESTAMP,
retry_count INT DEFAULT 0,
error_msg VARCHAR(500),
created_time TIMESTAMP DEFAULT NOW()
);
COMMENT ON TABLE prod_alert_notification IS '报警通知记录表';
CREATE INDEX IF NOT EXISTS idx_alert_notif_record ON prod_alert_notification(alert_record_id);
CREATE INDEX IF NOT EXISTS idx_alert_notif_status ON prod_alert_notification(status);
-- ==================== 报警规则-设备关联(可选) ====================
CREATE TABLE IF NOT EXISTS prod_alert_rule_device (
id BIGSERIAL PRIMARY KEY,
rule_id BIGINT REFERENCES prod_alert_rule(id),
device_id BIGINT,
device_sn VARCHAR(100),
area VARCHAR(50),
created_time TIMESTAMP DEFAULT NOW()
);
COMMENT ON TABLE prod_alert_rule_device IS '报警规则-设备/区域关联表';
-- ==================== 初始规则数据 ====================
INSERT INTO prod_alert_rule (rule_name, rule_code, metric_key, alert_level, condition_expr, threshold_value, debounce_sec, description, enabled) VALUES
('管网压力过高报警', 'RULE_PRESSURE_HIGH', 'pressure', 'urgent',
'{"op":"AND","conditions":[{"metric":"pressure","operator":">","threshold":0.8}]}',
0.8000, 300, '管网压力超过0.8MPa时触发紧急报警', 1),
('管网压力过低报警', 'RULE_PRESSURE_LOW', 'pressure', 'important',
'{"op":"OR","conditions":[{"metric":"pressure","operator":"<","threshold":0.2}]}',
0.2000, 300, '管网压力低于0.2MPa时触发重要报警', 1),
('水质浊度超标', 'RULE_TURBIDITY_HIGH', 'turbidity', 'urgent',
'{"op":"AND","conditions":[{"metric":"turbidity","operator":">","threshold":1.0}]}',
1.0000, 600, '水质浊度超过1.0NTU触发紧急报警', 1),
('余氯偏低报警', 'RULE_CHLORINE_LOW', 'residual_chlorine', 'general',
'{"op":"AND","conditions":[{"metric":"residual_chlorine","operator":"<","threshold":0.1}]}',
0.1000, 600, '余氯低于0.1mg/L触发一般报警', 1),
('流量异常波动', 'RULE_FLOW_ANOMALY', 'flow', 'important',
'{"op":"OR","conditions":[{"metric":"flow","operator":">","threshold":100},{"metric":"flow","operator":"<","threshold":5}]}',
NULL, 120, '流量异常偏高或偏低时触发报警', 1);