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
@@ -0,0 +1,15 @@
|
||||
# Checklist
|
||||
|
||||
- [x] 数据库迁移 20261024_icc_event_alarm.sql 可执行,device_alarm/alarm_dispatch 结构与 spec 一致(字段、索引、唯一键),db_init.sql 同步
|
||||
- [x] 设计文档(表结构新增及变更.md / db_design.html)中 device_alarm、alarm_dispatch 字段已更新
|
||||
- [x] device_alarm.entity.ts / alarm_dispatch.entity.ts 与迁移字段一一对应,后端 tsc 通过
|
||||
- [x] 回调接口 POST /api/icc-event/callback:token 校验失败返回 401;合法 alarm 事件按 alarmCode 幂等 upsert;匹配 electric_line 填充 line_id/line_name/customer_id;未匹配记录 line_id 为空;返回 {"success":true,"code":"0"}
|
||||
- [x] ICC 订阅注册(POST subscribe/mqinfo)可手动触发,配置了 monitor URL 与 name/magic;保活定时任务 icc_event_alarm_keepalive 已注册(cron */30 * * * *,sys_job 种子)
|
||||
- [x] RBAC PERMISSION_MAP 与菜单/角色种子就位:设备报警监控(alarm:list)、报警派单台账与创建(alarm-dispatch:list / create)
|
||||
- [x] GET /api/device-alarms 列表+统计+筛选只返回匹配线路的报警;POST /api/device-alarms/:id/dispatch 生成唯一派单号、同报警未完成派单拒绝重复创建、校验电工在岗审核通过
|
||||
- [x] 报警派单创建后向电工发送 sys_notice 站内通知(receiver_type=worker)
|
||||
- [x] GET /api/alarm-dispatches 台账分页列表正常(联出电工姓名/客户名称)
|
||||
- [x] 前端设备报警监控页面:统计卡、筛选、报警表格、行内「发起报警派单」按钮与电工选择弹窗齐全,样式对齐项目勘察页
|
||||
- [x] 前端 30 秒轮询刷新;新出现 grade=1 报警时报警灯闪烁 + Web Audio 提示音,且去重不重复响
|
||||
- [x] 前端报警派单台账页面与路由就位,vue-tsc 通过
|
||||
- [x] 后端 tsc + 前端 vue-tsc 全绿;模拟回调端到端验证通过(入库→页面展示→报警灯/声音→发起派单→站内通知→台账可见)
|
||||
@@ -0,0 +1,20 @@
|
||||
# Checklist
|
||||
|
||||
* [x] 生产库 electricity\_data 现状已核对(有无表/字段/分区/数据),迁移方案据此确定
|
||||
|
||||
* [x] 迁移 `20261024_icc_analog_data.sql` 已执行到生产库:字段集(id/line\_id/line\_code/imei/line\_name/customer\_id/analog\_type/analog\_name/analog\_unit/analog\_value/collect\_time,**无 equip\_id**)正确,唯一键 (line\_code, analog\_type, collect\_time)、按月分区(2026\_10\~2027\_03)、索引(customer/line/time)就绪
|
||||
|
||||
* [x] db\_init.sql 中 electricity\_data 基线定义与迁移一致
|
||||
|
||||
* [x] 后端实体 `electricity_data.entity.ts` 字段与迁移一致,映射 `icc_analog_mapper.ts` 按实际返回字段正确映射(line\_code/imei/analog\_type/analog\_name/analog\_unit/analog\_value)
|
||||
|
||||
* [x] 同步服务 `icc_analog_sync.service.ts` 复用 OAuth2 鉴权,先读已同步线路 line\_code,分批 deviceCodes(≤50)POST 模拟量接口 pageSize=500 短页停止,collect\_time 用同步时间,按 (line\_code, analog\_type, collect\_time) 幂等 upsert,写 icc\_sync\_log(sync\_type=electricity\_data),失败仅记日志不抛
|
||||
|
||||
* [x] `POST /api/electricity-data/sync` 接口可调用并返回 {pulled, inserted, updated, skipped, synced},RBAC 路由 `/api/electricity-data` → device:list 生效
|
||||
|
||||
* [x] 定时任务 `icc_analog_sync`(每 5 分钟 `*/5 * * * *`)已注册:job\_registry BUILTIN\_JOBS + JobRuntime.syncIccAnalogs + db\_seed.sql sys\_job 种子幂等
|
||||
|
||||
* [x] 设计文档「表结构新增及变更.md」已补充 electricity\_data 新表结构及同步服务/定时任务说明
|
||||
|
||||
* [x] 验证通过:tsc 编译无错误;真实同步拉取到模拟量数据入库(74 行/快照,analog\_name/analog\_unit 填充正确);幂等重跑正常(二次快照 148 行);无前端改动
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
# Tasks
|
||||
|
||||
- [x] Task 1: 数据库迁移与设计文档同步
|
||||
- [x] 1.1 新建 database/migrations/20261024_icc_event_alarm.sql:DROP 重建 device_alarm(按 ICC 事件结构:alarm_code UNIQUE、uuid、line_id/line_code/line_name/customer_id、node_code/device_code/device_name、org_code/org_name、alarm_type/alarm_grade/alarm_stat/is_event、alarm_time TIMESTAMPTZ、alarm_value NUMERIC(14,4) 可空、synced_at;索引 idx_alarm_time/idx_alarm_line/idx_alarm_customer/idx_alarm_grade)与 alarm_dispatch(dispatch_no UNIQUE、alarm_id→device_alarm、line_id/line_code/line_name、customer_id→customer、alarm_time/alarm_grade 快照、dispatcher、worker_id、status 0已派发 1已处理、fault_desc、created_at/completed_at;索引 idx_alarm_disp_status/idx_alarm_disp_worker/idx_alarm_disp_alarm)
|
||||
- [x] 1.2 同步 database/db_init.sql 中对应两表 DDL(与迁移保持一致)
|
||||
- [x] 1.3 更新 系统设计/表结构新增及变更.md(device_alarm/alarm_dispatch 小节)与 db_design.html 中相关表结构(字段级)
|
||||
- [x] 1.4 执行迁移到生产库验证(表为空,安全重建;用 server/node_modules/pg 脚本)
|
||||
|
||||
- [x] Task 2: 后端实体
|
||||
- [x] 2.1 server/src/entity/device_alarm.entity.ts(字段与迁移一致,line_id/customer_id 建 FK/BelongsTo 可选)
|
||||
- [x] 2.2 server/src/entity/alarm_dispatch.entity.ts(含 BelongsTo device_alarm、Customer;worker_id 仅存 ID)
|
||||
- [x] 2.3 `npx tsc --noEmit` 通过
|
||||
|
||||
- [x] Task 3: ICC 事件订阅服务与回调接收
|
||||
- [x] 3.1 server/src/service/icc_event_subscribe.service.ts:复用 getIccAccessToken/iccFetch(icc_customer_auth.ts),实现 registerSubscribe()(POST subscribe/mqinfo,category=alarm、订阅全部类型/权限、monitor=配置的回调 URL 带 token、subsystem name/magic=配置默认 `222.243.55.42_7001_alarm`)与 ensureSubscribe()
|
||||
- [x] 3.2 server/src/controller/icc_event.controller.ts:POST /api/icc-event/callback(无鉴权,校验 URL token 与配置一致,解析通用事件格式,仅处理 category=alarm;按 alarmCode upsert 到 device_alarm,匹配 electric_line.line_code 填充 line_id/line_name/customer_id;返回 {"success":true,"code":"0"});另提供受 RBAC 保护的 POST /api/icc-event/subscribe(手动触发注册)与 GET /api/icc-event/subscribe-status
|
||||
- [x] 3.3 幂等处理:同 uuid/alarmCode 重复推送不重复计数;alarm_stat 变化更新原记录
|
||||
- [x] 3.4 回调 token 与 monitor URL 从配置读取(config.default.ts 加 ICC_EVENT 配置项)
|
||||
|
||||
- [x] Task 4: 保活定时任务、RBAC 与种子
|
||||
- [x] 4.1 server/src/task/icc_event_keepalive.task.ts(defaultCron `*/30 * * * *`,调用 ensureSubscribe),注册到 job_registry.ts 与 job_scheduler.service.ts(syncIccEvents)
|
||||
- [x] 4.2 rbac.middleware.ts PERMISSION_MAP 新增:`/api/icc-event/subscribe: device:list`、`/api/device-alarms: alarm:list`、`/api/alarm-dispatches: alarm-dispatch:list`(create 权限 `alarm-dispatch:create`)
|
||||
- [x] 4.3 database/db_seed.sql:新增 sys_job(icc_event_alarm_keepalive,cron `*/30 * * * *`)、sys_menu(设备监控→设备报警监控 /api/device/alarm;运营派单→报警派单台账 /api/dispatch/alarm)与 sys_role_menu(ADMIN 角色)、sys_permission 相关种子(若权限为表驱动则同步)
|
||||
|
||||
- [x] Task 5: 报警查询与报警派单后端接口
|
||||
- [x] 5.1 server/src/controller/device_alarm.controller.ts:GET /api/device-alarms(分页列表+统计:今日/严重/未派单;筛选客户/等级/关键词;只展示 line_id 非空的记录)+ POST /api/device-alarms/:id/dispatch(创建 alarm_dispatch:生成唯一 dispatch_no、快照报警/线路/客户、dispatcher=当前用户 realName、worker_id 校验在岗+审核通过;同一报警已有未完成派单则拒绝)
|
||||
- [x] 5.2 派单后通过 NoticeService.deliverToReceivers(参照 survey_order.service 的派单通知埋点)向 worker 发站内通知(notice_type=alarm_dispatch,receiver_type=worker)
|
||||
- [x] 5.3 server/src/controller/alarm_dispatch.controller.ts:GET /api/alarm-dispatches(台账分页列表,筛选状态/关键词,联出电工姓名/客户名称)
|
||||
- [x] 5.4 `npx tsc --noEmit` 通过
|
||||
|
||||
- [x] Task 6: 前端-设备报警监控页面
|
||||
- [x] 6.1 client/src/api/device.ts 或新增 api/alarm.ts:deviceAlarmApi.getList/dispatch、alarmDispatchApi.getList、iccEventApi.subscribe/status 类型与封装
|
||||
- [x] 6.2 client/src/views/device/alarm/index.vue(样式对齐 views/dispatch/survey/index.vue):统计卡(今日/严重/未派单)+ 筛选区(客户/等级/关键词)+ 报警表格(报警时间/线路名称/线路编码/客户/类型/等级 tag/状态)+ 行内「发起报警派单」按钮 + 派单弹窗(共享电工下拉,取 worker 在岗审核通过列表)
|
||||
- [x] 6.3 严重报警提示:页面挂载轮询(30s 刷新列表);轮询发现新 grade=1 报警时右上角报警灯闪烁(全局按钮/角标)并播放提示音(Web Audio 蜂鸣 3 次);按「已提示的报警 id 集合」去重
|
||||
- [x] 6.4 路由注册(client/src/router)+ 菜单由后端 sys_menu 动态渲染(自动生效)
|
||||
|
||||
- [x] Task 7: 前端-报警派单台账页面
|
||||
- [x] 7.1 client/src/views/dispatch/alarm/index.vue:台账列表(派单号/报警时间/线路/客户/指派电工/状态 tag/创建时间)+ 筛选(状态/关键词)
|
||||
- [x] 7.2 路由注册(运营派单分组下)
|
||||
- [x] 7.3 `npm run check`(vue-tsc)通过
|
||||
|
||||
- [x] Task 8: 验证
|
||||
- [x] 8.1 后端 `npx tsc --noEmit`、前端 `npm run check` 全绿
|
||||
- [x] 8.2 接口自测:手工构造 ICC 通用事件 JSON POST 回调接口验证入库/幂等/token 校验/未匹配线路落空记录;subscribe 注册接口调用成功
|
||||
- [x] 8.3 浏览器端到端:登录进入「设备报警监控」,触发一条模拟回调入库后页面可见;严重报警出现报警灯+声音;发起报警派单→选择电工→生成派单→电工收到站内通知;「报警派单台账」显示该派单
|
||||
- [x] 8.4 若生产订阅真实生效受限(ICC 无法访问回调地址),以模拟回调验证全链路并在交付说明中注明
|
||||
|
||||
# Task Dependencies
|
||||
- Task 2 依赖 Task 1(表结构确定)
|
||||
- Task 3 依赖 Task 2(实体)
|
||||
- Task 4 依赖 Task 3(订阅服务)
|
||||
- Task 5 依赖 Task 2(实体)与 Task 3(回调入库可测)
|
||||
- Task 6 依赖 Task 5(接口)
|
||||
- Task 7 依赖 Task 5.3(台账接口)
|
||||
- Task 8 依赖全部
|
||||
Reference in new issue
Block a user