feat(alarm): ICC 报警事件订阅与设备报警监控/报警派单 - 重建 device_alarm 表(迁移20261024_icc_event_alarm.sql:alarm_code 唯一、uuid、line 关联、客户、等级、事件标记、alarm_time 等 19 字段与 4 索引)并新建 alarm_dispatch 派单表(15 字段);订阅服务 IccEventSubscribeService 复用 OAuth2 鉴权向 ICC 注册报警事件回调(POST subscribe/mqinfo,monitor 带 token、同名覆盖保活),每 30 分钟保活任务(sys_job 种子);回调 POST /api/icc-event/callback 无鉴权仅 URL token 校验,兼容单条/数组事件解析、按 alarmCode 幂等 upsert、匹配 electric_line.line_code 回填线路客户;新增 GET /api/device-alarms(列表+今日/严重/未派单统计+客户/等级/关键词筛选)与 POST /api/device-alarms/:id/dispatch(AD 派单号、同报警重复派单拦截、电工在岗审核校验、NoticeService 站内通知);GET /api/alarm-dispatches 台账(联电工/客户名);前端设备报警监控页(统计卡/筛选/表格/发起报警派单弹窗/30 秒轮询+严重报警红灯闪烁与 Web Audio 蜂鸣/订阅状态弹窗)与报警派单台账页+路由;菜单 63/64、role_menu、sys_job 种子;同步 db_init/db_seed 与设计文档;端到端验证通过
Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com
This commit is contained in:
1 parent
c8a4330f3b
commit
44fc9a1d54
24 files changed
+2825
-126
No files matched your search
+44
-87
@@ -921,101 +921,58 @@ COMMENT ON COLUMN fault_type_detail.remark IS '备注';
|
||||
COMMENT ON COLUMN fault_type_detail.created_at IS '创建时间';
|
||||
CREATE INDEX idx_ftd_type ON fault_type_detail (fault_type_id);
|
||||
|
||||
-- 27. 设备报警信息表(ICC 拉取)
|
||||
-- 27. 设备报警信息表(ICC 事件订阅)
|
||||
DROP TABLE IF EXISTS alarm_dispatch CASCADE;
|
||||
DROP TABLE IF EXISTS device_alarm CASCADE;
|
||||
CREATE TABLE device_alarm (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
alarm_code VARCHAR(128) NOT NULL UNIQUE,
|
||||
line_id BIGINT,
|
||||
equip_id BIGINT,
|
||||
icc_device_code VARCHAR(128),
|
||||
line_name VARCHAR(128),
|
||||
customer_id BIGINT,
|
||||
building_id BIGINT,
|
||||
floor_no VARCHAR(16),
|
||||
location VARCHAR(256),
|
||||
alarm_date DATE,
|
||||
fault_type VARCHAR(128),
|
||||
alarm_value NUMERIC(14,2),
|
||||
history_count INT DEFAULT 0,
|
||||
synced_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
alarm_code VARCHAR(128) NOT NULL UNIQUE, -- ICC 报警编码(幂等键)
|
||||
uuid VARCHAR(128), -- ICC 事件 uuid
|
||||
line_id BIGINT, -- 智电线路 ID(→ electric_line,nodeCode/deviceCode 匹配 line_code)
|
||||
line_code VARCHAR(64), -- 线路编码(electric_line.line_code)
|
||||
line_name VARCHAR(128), -- 线路名称
|
||||
customer_id BIGINT, -- 客户 ID(由 line_id 联出)
|
||||
node_code VARCHAR(64), -- 探测器节点编码(info.nodeCode)
|
||||
device_code VARCHAR(64), -- 设备编码(info.deviceCode)
|
||||
device_name VARCHAR(128), -- 设备名称(info.deviceName)
|
||||
org_code VARCHAR(64), -- 组织编码(info.orgCode)
|
||||
org_name VARCHAR(128), -- 组织名称(info.orgName)
|
||||
alarm_type INT, -- 报警类型(info.alarmType)
|
||||
alarm_grade SMALLINT, -- 报警等级 1/2/3(1 最严重)
|
||||
alarm_stat SMALLINT, -- 报警状态(info.alarmStat)
|
||||
is_event BOOLEAN DEFAULT FALSE, -- 是否事件(info.isEvent)
|
||||
alarm_time TIMESTAMPTZ, -- 报警发生时间(info.alarmDate 秒级时间戳)
|
||||
alarm_value NUMERIC(14,4), -- 报警数值(部分事件带值,可空)
|
||||
synced_at TIMESTAMPTZ NOT NULL DEFAULT NOW() -- 入库时间
|
||||
);
|
||||
COMMENT ON TABLE device_alarm IS '设备报警信息表(ICC 拉取)';
|
||||
COMMENT ON COLUMN device_alarm.id IS '自增主键';
|
||||
COMMENT ON COLUMN device_alarm.alarm_code IS '报警编码(唯一)';
|
||||
COMMENT ON COLUMN device_alarm.line_id IS '线路 ID';
|
||||
COMMENT ON COLUMN device_alarm.equip_id IS '客户设备 ID';
|
||||
COMMENT ON COLUMN device_alarm.icc_device_code IS 'ICC 设备编号';
|
||||
COMMENT ON COLUMN device_alarm.line_name IS '线路名称';
|
||||
COMMENT ON COLUMN device_alarm.customer_id IS '客户 ID';
|
||||
COMMENT ON COLUMN device_alarm.building_id IS '所属建筑 ID';
|
||||
COMMENT ON COLUMN device_alarm.floor_no IS '所在楼层';
|
||||
COMMENT ON COLUMN device_alarm.location IS '所在位置';
|
||||
COMMENT ON COLUMN device_alarm.alarm_date IS '报警日期';
|
||||
COMMENT ON COLUMN device_alarm.fault_type IS 'ICC 预警类型';
|
||||
COMMENT ON COLUMN device_alarm.alarm_value IS '报警数值';
|
||||
COMMENT ON COLUMN device_alarm.history_count IS '历史出现次数';
|
||||
COMMENT ON COLUMN device_alarm.synced_at IS 'ICC 同步时间';
|
||||
CREATE INDEX idx_alarm_customer ON device_alarm (customer_id);
|
||||
CREATE INDEX idx_alarm_date ON device_alarm (alarm_date);
|
||||
COMMENT ON TABLE device_alarm IS '设备报警信息表(ICC 事件订阅)';
|
||||
CREATE INDEX idx_alarm_time ON device_alarm (alarm_time DESC);
|
||||
CREATE INDEX idx_alarm_line ON device_alarm (line_id);
|
||||
CREATE INDEX idx_alarm_customer ON device_alarm (customer_id);
|
||||
CREATE INDEX idx_alarm_grade ON device_alarm (alarm_grade);
|
||||
|
||||
-- 28. 报警派单信息表
|
||||
DROP TABLE IF EXISTS alarm_dispatch CASCADE;
|
||||
CREATE TABLE alarm_dispatch (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
dispatch_no VARCHAR(64) NOT NULL UNIQUE,
|
||||
alarm_id BIGINT,
|
||||
line_id BIGINT,
|
||||
equip_id BIGINT,
|
||||
icc_device_code VARCHAR(128),
|
||||
line_name VARCHAR(128),
|
||||
customer_id BIGINT NOT NULL REFERENCES customer(id),
|
||||
contact_person VARCHAR(64),
|
||||
contact_phone VARCHAR(20),
|
||||
building_id BIGINT,
|
||||
floor_no VARCHAR(16),
|
||||
location VARCHAR(256),
|
||||
fault_type_id BIGINT REFERENCES fault_type(id),
|
||||
fault_desc TEXT,
|
||||
dispatcher VARCHAR(64),
|
||||
fault_reason TEXT,
|
||||
process_flow TEXT,
|
||||
worker_id BIGINT,
|
||||
status SMALLINT NOT NULL DEFAULT 0,
|
||||
process_photos JSONB,
|
||||
rating SMALLINT,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
completed_at TIMESTAMPTZ
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
dispatch_no VARCHAR(64) NOT NULL UNIQUE, -- 报警派单号(如 AD20261024001,生成规则由后端实现)
|
||||
alarm_id BIGINT, -- 报警 ID(→ device_alarm)
|
||||
line_id BIGINT, -- 线路 ID
|
||||
line_code VARCHAR(64), -- 线路编码
|
||||
line_name VARCHAR(128), -- 线路名称
|
||||
customer_id BIGINT REFERENCES customer(id), -- 客户 ID
|
||||
alarm_time TIMESTAMPTZ, -- 报警时间(快照)
|
||||
alarm_grade SMALLINT, -- 报警等级(快照)
|
||||
fault_desc TEXT, -- 故障事项(报警类型描述)
|
||||
dispatcher VARCHAR(64), -- 派发人(当前登录用户 realName)
|
||||
worker_id BIGINT, -- 共享电工 ID(→ worker)
|
||||
status SMALLINT NOT NULL DEFAULT 0, -- 状态:0已派发 1已处理
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
completed_at TIMESTAMPTZ
|
||||
);
|
||||
COMMENT ON TABLE alarm_dispatch IS '报警派单信息表';
|
||||
COMMENT ON COLUMN alarm_dispatch.id IS '自增主键';
|
||||
COMMENT ON COLUMN alarm_dispatch.dispatch_no IS '报警派单号(唯一)';
|
||||
COMMENT ON COLUMN alarm_dispatch.alarm_id IS '报警 ID(→ device_alarm)';
|
||||
COMMENT ON COLUMN alarm_dispatch.line_id IS '线路 ID';
|
||||
COMMENT ON COLUMN alarm_dispatch.equip_id IS '客户设备 ID';
|
||||
COMMENT ON COLUMN alarm_dispatch.icc_device_code IS 'ICC 设备编号';
|
||||
COMMENT ON COLUMN alarm_dispatch.line_name IS '线路名称';
|
||||
COMMENT ON COLUMN alarm_dispatch.customer_id IS '客户 ID(→ customer)';
|
||||
COMMENT ON COLUMN alarm_dispatch.contact_person IS '联系人';
|
||||
COMMENT ON COLUMN alarm_dispatch.contact_phone IS '电话';
|
||||
COMMENT ON COLUMN alarm_dispatch.building_id IS '建筑 ID';
|
||||
COMMENT ON COLUMN alarm_dispatch.floor_no IS '所在楼层';
|
||||
COMMENT ON COLUMN alarm_dispatch.location IS '所在位置';
|
||||
COMMENT ON COLUMN alarm_dispatch.fault_type_id IS '故障类型 ID(→ fault_type)';
|
||||
COMMENT ON COLUMN alarm_dispatch.fault_desc IS '故障事项(类型+数值)';
|
||||
COMMENT ON COLUMN alarm_dispatch.dispatcher IS '派发人';
|
||||
COMMENT ON COLUMN alarm_dispatch.fault_reason IS '故障原因(来自明细)';
|
||||
COMMENT ON COLUMN alarm_dispatch.process_flow IS '处理流程(来自明细)';
|
||||
COMMENT ON COLUMN alarm_dispatch.worker_id IS '共享电工 ID';
|
||||
COMMENT ON COLUMN alarm_dispatch.status IS '状态:0已派发 1已处理';
|
||||
COMMENT ON COLUMN alarm_dispatch.process_photos IS '报警处理照片(JSONB 多张)';
|
||||
COMMENT ON COLUMN alarm_dispatch.rating IS '派单处理评分';
|
||||
COMMENT ON COLUMN alarm_dispatch.created_at IS '创建时间';
|
||||
COMMENT ON COLUMN alarm_dispatch.completed_at IS '完成时间';
|
||||
CREATE INDEX idx_alarm_disp_customer ON alarm_dispatch (customer_id);
|
||||
CREATE INDEX idx_alarm_disp_worker ON alarm_dispatch (worker_id);
|
||||
CREATE INDEX idx_alarm_disp_status ON alarm_dispatch (status);
|
||||
COMMENT ON TABLE alarm_dispatch IS '报警派单信息表';
|
||||
CREATE INDEX idx_alarm_disp_status ON alarm_dispatch (status);
|
||||
CREATE INDEX idx_alarm_disp_worker ON alarm_dispatch (worker_id);
|
||||
CREATE INDEX idx_alarm_disp_alarm ON alarm_dispatch (alarm_id);
|
||||
|
||||
-- ============================================================
|
||||
-- 八、报修域(2 张表)
|
||||
|
||||
@@ -538,6 +538,44 @@ ON CONFLICT (job_key) DO UPDATE SET
|
||||
job_name = EXCLUDED.job_name,
|
||||
remark = EXCLUDED.remark;
|
||||
|
||||
-- ------------------------------------------------------------
|
||||
-- 12. ICC 事件订阅保活任务种子(sys_job,按 job_key 幂等;默认每 30 分钟)
|
||||
-- ------------------------------------------------------------
|
||||
INSERT INTO sys_job (job_key, job_name, cron_expression, params, retry_times, retry_interval, status, remark) VALUES
|
||||
('icc_event_alarm_keepalive', 'ICC事件订阅保活', '*/30 * * * *', '{}'::jsonb, 1, 300, 1,
|
||||
'向 ICC 平台重新注册报警事件回调订阅(同名覆盖保活,默认每 30 分钟)')
|
||||
ON CONFLICT (job_key) DO UPDATE SET
|
||||
cron_expression = EXCLUDED.cron_expression,
|
||||
job_name = EXCLUDED.job_name,
|
||||
remark = EXCLUDED.remark;
|
||||
|
||||
-- ------------------------------------------------------------
|
||||
-- 12a. 报警域菜单(设备监控下「设备报警监控」/ 运营派单下「报警派单台账」,id:63-64)
|
||||
-- 63 挂设备监控 parent_id=4(sort 4,排在网关台账之后)
|
||||
-- 64 挂运营派单 parent_id=3(sort 6,排在维保派单之后)
|
||||
-- ------------------------------------------------------------
|
||||
INSERT INTO sys_menu (id, parent_id, menu_name, menu_path, component, icon, sort_order, menu_type, permission, visible) VALUES
|
||||
(63, 4, '设备报警监控', '/device/alarm', 'device/alarm/index', 'AlertOutlined', 4, 2, 'alarm:list', 1),
|
||||
(64, 3, '报警派单台账', '/dispatch/alarm', 'dispatch/alarm/index', 'ScheduleOutlined', 6, 2, 'alarm-dispatch:list', 1)
|
||||
ON CONFLICT (id) DO UPDATE SET
|
||||
parent_id = EXCLUDED.parent_id,
|
||||
menu_name = EXCLUDED.menu_name,
|
||||
menu_path = EXCLUDED.menu_path,
|
||||
component = EXCLUDED.component,
|
||||
icon = EXCLUDED.icon,
|
||||
sort_order = EXCLUDED.sort_order,
|
||||
menu_type = EXCLUDED.menu_type,
|
||||
permission = EXCLUDED.permission,
|
||||
visible = EXCLUDED.visible;
|
||||
|
||||
-- 角色-菜单绑定:ADMIN(role_id=1)拥有 63-64
|
||||
INSERT INTO sys_role_menu (role_id, menu_id) VALUES
|
||||
(1, 63), (1, 64)
|
||||
ON CONFLICT (role_id, menu_id) DO NOTHING;
|
||||
|
||||
-- 重置 sys_menu 自增序列(覆盖到 64)
|
||||
SELECT setval('sys_menu_id_seq', GREATEST((SELECT MAX(id) FROM sys_menu), 64), true);
|
||||
|
||||
COMMIT;
|
||||
|
||||
-- ============================================================
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
-- ICC 报警事件订阅:按 ICC 平台事件订阅推送的通用事件格式重建 device_alarm / alarm_dispatch
|
||||
-- 两表原为旧设计(equip_id/building_id/floor_no/location/history_count/fault_type/alarm_date 等与 ICC 事件结构不符),现为空表,DROP 重建
|
||||
DROP TABLE IF EXISTS alarm_dispatch CASCADE;
|
||||
DROP TABLE IF EXISTS device_alarm CASCADE;
|
||||
CREATE TABLE device_alarm (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
alarm_code VARCHAR(128) NOT NULL UNIQUE, -- ICC 报警编码(幂等键)
|
||||
uuid VARCHAR(128), -- ICC 事件 uuid
|
||||
line_id BIGINT, -- 智电线路 ID(→ electric_line,nodeCode/deviceCode 匹配 line_code)
|
||||
line_code VARCHAR(64), -- 线路编码(electric_line.line_code)
|
||||
line_name VARCHAR(128), -- 线路名称
|
||||
customer_id BIGINT, -- 客户 ID(由 line_id 联出)
|
||||
node_code VARCHAR(64), -- 探测器节点编码(info.nodeCode)
|
||||
device_code VARCHAR(64), -- 设备编码(info.deviceCode)
|
||||
device_name VARCHAR(128), -- 设备名称(info.deviceName)
|
||||
org_code VARCHAR(64), -- 组织编码(info.orgCode)
|
||||
org_name VARCHAR(128), -- 组织名称(info.orgName)
|
||||
alarm_type INT, -- 报警类型(info.alarmType)
|
||||
alarm_grade SMALLINT, -- 报警等级 1/2/3(1 最严重)
|
||||
alarm_stat SMALLINT, -- 报警状态(info.alarmStat)
|
||||
is_event BOOLEAN DEFAULT FALSE, -- 是否事件(info.isEvent)
|
||||
alarm_time TIMESTAMPTZ, -- 报警发生时间(info.alarmDate 秒级时间戳)
|
||||
alarm_value NUMERIC(14,4), -- 报警数值(部分事件带值,可空)
|
||||
synced_at TIMESTAMPTZ NOT NULL DEFAULT NOW() -- 入库时间
|
||||
);
|
||||
COMMENT ON TABLE device_alarm IS '设备报警信息表(ICC 事件订阅)';
|
||||
CREATE INDEX idx_alarm_time ON device_alarm (alarm_time DESC);
|
||||
CREATE INDEX idx_alarm_line ON device_alarm (line_id);
|
||||
CREATE INDEX idx_alarm_customer ON device_alarm (customer_id);
|
||||
CREATE INDEX idx_alarm_grade ON device_alarm (alarm_grade);
|
||||
|
||||
CREATE TABLE alarm_dispatch (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
dispatch_no VARCHAR(64) NOT NULL UNIQUE, -- 报警派单号(如 AD20261024001,生成规则由后端实现)
|
||||
alarm_id BIGINT, -- 报警 ID(→ device_alarm)
|
||||
line_id BIGINT, -- 线路 ID
|
||||
line_code VARCHAR(64), -- 线路编码
|
||||
line_name VARCHAR(128), -- 线路名称
|
||||
customer_id BIGINT REFERENCES customer(id), -- 客户 ID
|
||||
alarm_time TIMESTAMPTZ, -- 报警时间(快照)
|
||||
alarm_grade SMALLINT, -- 报警等级(快照)
|
||||
fault_desc TEXT, -- 故障事项(报警类型描述)
|
||||
dispatcher VARCHAR(64), -- 派发人(当前登录用户 realName)
|
||||
worker_id BIGINT, -- 共享电工 ID(→ worker)
|
||||
status SMALLINT NOT NULL DEFAULT 0, -- 状态:0已派发 1已处理
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
completed_at TIMESTAMPTZ
|
||||
);
|
||||
COMMENT ON TABLE alarm_dispatch IS '报警派单信息表';
|
||||
CREATE INDEX idx_alarm_disp_status ON alarm_dispatch (status);
|
||||
CREATE INDEX idx_alarm_disp_worker ON alarm_dispatch (worker_id);
|
||||
CREATE INDEX idx_alarm_disp_alarm ON alarm_dispatch (alarm_id);
|
||||
Reference in new issue
Block a user