refactor(alarm): 重构报警处理逻辑并优化状态管理

main
zhaokai 2026-05-27 10:35:22 +08:00
parent 3db3063206
commit beeaa44527
20 changed files with 225 additions and 77 deletions

View File

@ -1,4 +1,4 @@
<!doctype html><html lang="zh"><head data-built-info="@cqsjjb/scripts@2.0.0-alpha-1 Env/production (2026/5/26 08:44:59) App/iotalarm"><meta charset="UTF-8"/><meta name="renderer" content="webkit"/><meta http-equiv="X-UA-Compatible" content="IE=edge,Chrome=1"/><meta name="viewport" content="width=device-width,minimum-scale=1,maximum-scale=1,user-scalable=no,viewport-fit=cover"><title>--</title><script>(function () { <!doctype html><html lang="zh"><head data-built-info="@cqsjjb/scripts@2.0.0-alpha-1 Env/production (2026/5/27 09:58:05) App/iotalarm"><meta charset="UTF-8"/><meta name="renderer" content="webkit"/><meta http-equiv="X-UA-Compatible" content="IE=edge,Chrome=1"/><meta name="viewport" content="width=device-width,minimum-scale=1,maximum-scale=1,user-scalable=no,viewport-fit=cover"><title>--</title><script>(function () {
const APP_ENV = { const APP_ENV = {
antd: { antd: {
'ant-prefix': 'micro-temp', 'ant-prefix': 'micro-temp',
@ -20,4 +20,4 @@
redirect: '', redirect: '',
FRAMEWORK: APP_ENV.antd FRAMEWORK: APP_ENV.antd
}; };
})();</script><script defer="defer" src="/iotalarm/static/js/692.af6ab5c0031679cbddc3.js"></script><script defer="defer" src="/iotalarm/static/js/267.5d17f26c6b6d0853e68b.js"></script><script defer="defer" src="/iotalarm/static/js/867.e56a598fea96a2b1b4fa.js"></script><script defer="defer" src="/iotalarm/static/js/main.d970f084b493888c2de7.js"></script><link href="/iotalarm/static/css/main.64b082dca17390b0b36f.css" rel="stylesheet"></head><body><noscript>此网页需要开启JavaScript功能。</noscript><div id="root" style="width: 100%; height: 100%; position: relative;overflow-y: auto"></div><script type="text/javascript">/* @cqsjjb/script 输出当前应用基本信息、构建时间 */console.log("%c@cqsjjb/scripts@2.0.0-alpha-1 Env/production (2026/5/26 08:44:59) App/iotalarm Version/main Java/<branch-name>", "color: #1890ff; border-radius: 2px; padding: 0 4px; border: 1px solid #1890ff; background: #f9fcff")</script></body></html> })();</script><script defer="defer" src="/iotalarm/static/js/692.af6ab5c0031679cbddc3.js"></script><script defer="defer" src="/iotalarm/static/js/267.5d17f26c6b6d0853e68b.js"></script><script defer="defer" src="/iotalarm/static/js/867.e56a598fea96a2b1b4fa.js"></script><script defer="defer" src="/iotalarm/static/js/main.efb0f4abab73ee923073.js"></script><link href="/iotalarm/static/css/main.64b082dca17390b0b36f.css" rel="stylesheet"></head><body><noscript>此网页需要开启JavaScript功能。</noscript><div id="root" style="width: 100%; height: 100%; position: relative;overflow-y: auto"></div><script type="text/javascript">/* @cqsjjb/script 输出当前应用基本信息、构建时间 */console.log("%c@cqsjjb/scripts@2.0.0-alpha-1 Env/production (2026/5/27 09:58:05) App/iotalarm Version/main Java/<branch-name>", "color: #1890ff; border-radius: 2px; padding: 0 4px; border: 1px solid #1890ff; background: #f9fcff")</script></body></html>

View File

@ -5,11 +5,12 @@ import cn.hutool.json.JSONUtil;
import com.alibaba.cola.dto.SingleResponse; import com.alibaba.cola.dto.SingleResponse;
import com.alibaba.cola.exception.BizException; import com.alibaba.cola.exception.BizException;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
import com.jjb.saas.framework.auth.utils.AuthContext;
import com.jjb.saas.message.client.message.facede.MessageFacade; import com.jjb.saas.message.client.message.facede.MessageFacade;
import com.jjb.saas.message.client.message.request.MessageSendCmd; import com.jjb.saas.message.client.message.request.MessageSendCmd;
import com.jjb.saas.message.client.message.request.MessageTargetCmd; import com.jjb.saas.message.client.message.request.MessageTargetCmd;
import com.zcloud.domain.config.MessageTemplateConfig; import com.zcloud.domain.config.MessageTemplateConfig;
import com.zcloud.domain.gateway.AlarmDisposeLogGateway; import com.zcloud.domain.enums.AlarmRecordStatusEnum;
import com.zcloud.domain.gateway.AlarmRecordGateway; import com.zcloud.domain.gateway.AlarmRecordGateway;
import com.zcloud.domain.model.AlarmRecordE; import com.zcloud.domain.model.AlarmRecordE;
import com.zcloud.dto.AlarmDisposeAssignCmd; import com.zcloud.dto.AlarmDisposeAssignCmd;
@ -18,8 +19,6 @@ import com.zcloud.gbscommon.todolistmq.event.TodoListAddBatchEvent;
import com.zcloud.gbscommon.todolistmq.event.TodoListAddEvent; import com.zcloud.gbscommon.todolistmq.event.TodoListAddEvent;
import com.zcloud.gbscommon.utils.Tools; import com.zcloud.gbscommon.utils.Tools;
import com.zcloud.gbscommon.utils.UuidUtil; import com.zcloud.gbscommon.utils.UuidUtil;
import com.zcloud.service.AlarmMessageService;
import com.zcloud.service.AlarmTodoService;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference; import org.apache.dubbo.config.annotation.DubboReference;
@ -43,18 +42,22 @@ import java.util.List;
public class AlarmDisposeAssignExe { public class AlarmDisposeAssignExe {
private final AlarmRecordGateway alarmRecordGateway; private final AlarmRecordGateway alarmRecordGateway;
private final AlarmDisposeLogGateway alarmDisposeLogGateway;
private final AlarmMessageService alarmMessageService;
private final AlarmTodoService alarmTodoService;
private final MessageTemplateConfig messageTemplateConfig; private final MessageTemplateConfig messageTemplateConfig;
private final TodoListEventPusherUtil todoListEventPusherUtil; private final TodoListEventPusherUtil todoListEventPusherUtil;
/**
*
*
* @param cmd
* @return
*/
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public SingleResponse execute(AlarmDisposeAssignCmd cmd) { public SingleResponse execute(AlarmDisposeAssignCmd cmd) {
List<Long> ids = cmd.getIds(); List<Long> ids = cmd.getIds();
if (Tools.isEmpty(ids)) { if (Tools.isEmpty(ids)) {
throw new BizException("请选择要处置的报警记录"); throw new BizException("请选择要处置的报警记录");
} }
checkAssignStatus(cmd.getStatus());
// 获取当前时间的LocalDateTime "yyyy-MM-dd HH:mm:ss" // 获取当前时间的LocalDateTime "yyyy-MM-dd HH:mm:ss"
LocalDateTime assignTime = LocalDateTime.now(); LocalDateTime assignTime = LocalDateTime.now();
@ -67,8 +70,8 @@ public class AlarmDisposeAssignExe {
} }
// 检查状态:只有待研判(10)状态可以分配 // 检查状态:只有待研判(10)状态可以分配
if (alarmRecord.getStatus() != 10) { if (!AlarmRecordStatusEnum.PENDING_REVIEW.sameStatus(alarmRecord.getStatus())) {
return SingleResponse.buildFailure("报警编码为"+alarmRecord.getAlarmNo()+"报警记录状态不是待处置;"); return SingleResponse.buildFailure("报警编码为" + alarmRecord.getAlarmNo() + "报警记录状态不是待研判;");
} }
// 更新报警记录状态和处置人 // 更新报警记录状态和处置人
@ -76,18 +79,18 @@ public class AlarmDisposeAssignExe {
BeanUtil.copyProperties(cmd, updateEntity); BeanUtil.copyProperties(cmd, updateEntity);
updateEntity.setId(id); updateEntity.setId(id);
updateEntity.setAssignTime(assignTime); updateEntity.setAssignTime(assignTime);
updateEntity.setAssignTime(LocalDateTime.now()); updateEntity.setAssignUserId(AuthContext.getUserId());
alarmRecordGateway.update(updateEntity); alarmRecordGateway.update(updateEntity);
if (cmd.getStatus() == 20){ if (AlarmRecordStatusEnum.PENDING_DISPOSE.sameStatus(cmd.getStatus())) {
// 发送站内信 // 发送站内信
sendMessage(messageTemplateConfig.getDispose(), alarmRecord.getDisposeUserId()); sendMessage(messageTemplateConfig.getDispose(), cmd.getDisposeUserId());
//待排查 待办 //待排查 待办
TodoListAddEvent event = new TodoListAddEvent(); TodoListAddEvent event = new TodoListAddEvent();
event.setTitle("您有一条【物联网报警】待处置"); event.setTitle("您有一条【物联网报警】待处置");
event.setContent("您有一条报警信息,请及时进行处置。"); event.setContent("您有一条报警信息,请及时进行处置。");
event.setForeignKey(alarmRecord.getId()); // 业务表ID -申请 event.setForeignKey(alarmRecord.getId()); // 业务表ID -申请
event.setForeignSubsidiaryKey(alarmRecord.getId()); // 业务附表ID 没有附表时为foreignKey的值 event.setForeignSubsidiaryKey(alarmRecord.getId()); // 业务附表ID 没有附表时为foreignKey的值
event.setReceiveUser(alarmRecord.getDisposeUserId());// user表ID event.setReceiveUser(cmd.getDisposeUserId());// user表ID
event.setPcFlag(0); // 是否PC端待办 1是 0否 event.setPcFlag(0); // 是否PC端待办 1是 0否
event.setAppFlag(1); // 是否APP端待办 1是 0否 event.setAppFlag(1); // 是否APP端待办 1是 0否
event.setOtherParams(new JSONObject()); event.setOtherParams(new JSONObject());
@ -95,12 +98,8 @@ public class AlarmDisposeAssignExe {
} }
} }
if (cmd.getStatus() == 20){ if (AlarmRecordStatusEnum.PENDING_DISPOSE.sameStatus(cmd.getStatus()) && !todoListAddEventList.isEmpty()) {
TodoListAddBatchEvent event3 = new TodoListAddBatchEvent(); sendTodoBatch(todoListAddEventList);
event3.setTodoListAddEventList(todoListAddEventList);
log.info("【物联网报警】待处置,请求:{}", JSONUtil.toJsonStr(event3));
boolean b = todoListEventPusherUtil.sendMessageAddBatchEvent(event3);
log.info("【物联网报警】待处置,结果:{}",b);
} }
return SingleResponse.buildSuccess(); return SingleResponse.buildSuccess();
} }
@ -108,6 +107,26 @@ public class AlarmDisposeAssignExe {
@DubboReference @DubboReference
private MessageFacade messageFacade; private MessageFacade messageFacade;
private void checkAssignStatus(Integer status) {
if (!AlarmRecordStatusEnum.PENDING_DISPOSE.sameStatus(status)
&& !AlarmRecordStatusEnum.FALSE_ALARM.sameStatus(status)) {
throw new BizException("报警确认状态不合法");
}
}
private void sendTodoBatch(List<TodoListAddEvent> todoListAddEventList) {
try {
TodoListAddBatchEvent event = new TodoListAddBatchEvent();
event.setTodoListAddEventList(todoListAddEventList);
log.info("【物联网报警】待处置,请求:{}", JSONUtil.toJsonStr(event));
boolean sendResult = todoListEventPusherUtil.sendMessageAddBatchEvent(event);
log.info("【物联网报警】待处置,结果:{}", sendResult);
} catch (Exception e) {
log.error("处置分配待办发送失败,不影响分配主流程,错误:{}", e.getMessage(), e);
}
}
private void sendMessage(String template, Long userId) { private void sendMessage(String template, Long userId) {
try { try {
MessageSendCmd messageSendCmd = new MessageSendCmd(); MessageSendCmd messageSendCmd = new MessageSendCmd();
@ -122,7 +141,7 @@ public class AlarmDisposeAssignExe {
SingleResponse<Boolean> result = messageFacade.send(messageSendCmd); SingleResponse<Boolean> result = messageFacade.send(messageSendCmd);
log.info("发送站内信结果:{}", result.toString()); log.info("发送站内信结果:{}", result.toString());
} catch (Exception e){ } catch (Exception e){
e.printStackTrace(); log.error("处置分配站内信发送失败不影响分配主流程接收人ID{},错误:{}", userId, e.getMessage(), e);
} }
} }

View File

@ -1,6 +1,8 @@
package com.zcloud.command; package com.zcloud.command;
import com.alibaba.cola.exception.BizException; import com.alibaba.cola.exception.BizException;
import com.jjb.saas.framework.auth.utils.AuthContext;
import com.zcloud.domain.enums.AlarmRecordStatusEnum;
import com.zcloud.domain.gateway.AlarmRecordGateway; import com.zcloud.domain.gateway.AlarmRecordGateway;
import com.zcloud.domain.gateway.AlarmDisposeLogGateway; import com.zcloud.domain.gateway.AlarmDisposeLogGateway;
import com.zcloud.domain.model.AlarmRecordE; import com.zcloud.domain.model.AlarmRecordE;
@ -51,18 +53,20 @@ public class AlarmDisposeBatchAssignExe {
} }
// 检查状态:只有待研判(10)状态可以分配 // 检查状态:只有待研判(10)状态可以分配
if (alarmRecord.getStatus() != 10) { if (!AlarmRecordStatusEnum.PENDING_REVIEW.sameStatus(alarmRecord.getStatus())) {
continue; // 跳过非待研判状态的记录 continue; // 跳过非待研判状态的记录
} }
// 更新报警记录状态和处置人 // 更新报警记录状态和处置人
AlarmRecordE updateEntity = new AlarmRecordE(); AlarmRecordE updateEntity = new AlarmRecordE();
updateEntity.setId(id); updateEntity.setId(id);
updateEntity.setStatus(20); // 待处置 updateEntity.setStatus(AlarmRecordStatusEnum.PENDING_DISPOSE.getStatus()); // 待处置
updateEntity.setManagerId(cmd.getDisposeUserId()); updateEntity.setManagerId(cmd.getDisposeUserId());
updateEntity.setDisposeUserId(cmd.getDisposeUserId()); updateEntity.setDisposeUserId(cmd.getDisposeUserId());
// updateEntity.setAssignTime(assignTime); // updateEntity.setAssignTime(assignTime);
updateEntity.setTenantId(cmd.getTenantId()); updateEntity.setTenantId(cmd.getTenantId());
updateEntity.setAssignTime(LocalDateTime.now());
updateEntity.setAssignUserId(AuthContext.getUserId());
updateEntity.setOrgId(cmd.getOrgId()); updateEntity.setOrgId(cmd.getOrgId());
alarmRecordGateway.update(updateEntity); alarmRecordGateway.update(updateEntity);
@ -73,8 +77,8 @@ public class AlarmDisposeBatchAssignExe {
log.setAlarmId(id); log.setAlarmId(id);
log.setAlarmNo(alarmRecord.getAlarmNo()); log.setAlarmNo(alarmRecord.getAlarmNo());
log.setActionType("MANUAL_ASSIGN"); log.setActionType("MANUAL_ASSIGN");
log.setBeforeStatus(10); log.setBeforeStatus(AlarmRecordStatusEnum.PENDING_REVIEW.getStatus());
log.setAfterStatus(20); log.setAfterStatus(AlarmRecordStatusEnum.PENDING_DISPOSE.getStatus());
log.setOperatorId(cmd.getDisposeUserId()); log.setOperatorId(cmd.getDisposeUserId());
log.setActionDesc("批量分配处置"); log.setActionDesc("批量分配处置");
// log.setActionTime(assignTime); // log.setActionTime(assignTime);

View File

@ -2,6 +2,7 @@ package com.zcloud.command;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import com.alibaba.cola.exception.BizException; import com.alibaba.cola.exception.BizException;
import com.zcloud.domain.enums.AlarmRecordStatusEnum;
import com.zcloud.domain.gateway.AlarmRecordGateway; import com.zcloud.domain.gateway.AlarmRecordGateway;
import com.zcloud.domain.gateway.AlarmDisposeLogGateway; import com.zcloud.domain.gateway.AlarmDisposeLogGateway;
import com.zcloud.domain.model.AlarmRecordE; import com.zcloud.domain.model.AlarmRecordE;
@ -41,7 +42,8 @@ public class AlarmDisposeInvalidExe {
} }
// 检查状态:只有待研判(10)或待处置(20)状态可以标记为无效 // 检查状态:只有待研判(10)或待处置(20)状态可以标记为无效
if (alarmRecord.getStatus() != 10 && alarmRecord.getStatus() != 20) { if (!AlarmRecordStatusEnum.PENDING_REVIEW.sameStatus(alarmRecord.getStatus())
&& !AlarmRecordStatusEnum.PENDING_DISPOSE.sameStatus(alarmRecord.getStatus())) {
throw new BizException("该报警已处置或已消警,无法标记为无效"); throw new BizException("该报警已处置或已消警,无法标记为无效");
} }
@ -50,9 +52,9 @@ public class AlarmDisposeInvalidExe {
// 更新报警记录状态 // 更新报警记录状态
AlarmRecordE updateEntity = new AlarmRecordE(); AlarmRecordE updateEntity = new AlarmRecordE();
updateEntity.setId(cmd.getId()); updateEntity.setId(cmd.getId());
updateEntity.setStatus(40); // 误报 updateEntity.setStatus(AlarmRecordStatusEnum.FALSE_ALARM.getStatus()); // 误报
updateEntity.setDisposeTime(LocalDateTime.now()); updateEntity.setDisposeTime(LocalDateTime.now());
updateEntity.setDisposeResult("误报"); updateEntity.setDisposeResult(AlarmRecordStatusEnum.FALSE_ALARM.getDesc());
if (StrUtil.isNotBlank(cmd.getInvalidReason())) { if (StrUtil.isNotBlank(cmd.getInvalidReason())) {
updateEntity.setDisposeRemark(cmd.getInvalidReason()); updateEntity.setDisposeRemark(cmd.getInvalidReason());
} }
@ -71,7 +73,7 @@ public class AlarmDisposeInvalidExe {
log.setAlarmNo(alarmRecord.getAlarmNo()); log.setAlarmNo(alarmRecord.getAlarmNo());
log.setActionType("INVALID"); log.setActionType("INVALID");
log.setBeforeStatus(beforeStatus); log.setBeforeStatus(beforeStatus);
log.setAfterStatus(40); log.setAfterStatus(AlarmRecordStatusEnum.FALSE_ALARM.getStatus());
log.setActionDesc("标记为无效报警"); log.setActionDesc("标记为无效报警");
if (StrUtil.isNotBlank(cmd.getInvalidReason())) { if (StrUtil.isNotBlank(cmd.getInvalidReason())) {
log.setResultText(cmd.getInvalidReason()); log.setResultText(cmd.getInvalidReason());

View File

@ -3,21 +3,19 @@ package com.zcloud.command;
import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import com.alibaba.cola.exception.BizException; import com.alibaba.cola.exception.BizException;
import com.zcloud.domain.enums.AlarmRecordStatusEnum;
import com.zcloud.domain.gateway.AlarmRecordGateway; import com.zcloud.domain.gateway.AlarmRecordGateway;
import com.zcloud.domain.gateway.AlarmDisposeLogGateway;
import com.zcloud.domain.model.AlarmRecordE; import com.zcloud.domain.model.AlarmRecordE;
import com.zcloud.domain.model.AlarmDisposeLogE;
import com.zcloud.dto.AppAlarmDisposeSubmitCmd; import com.zcloud.dto.AppAlarmDisposeSubmitCmd;
import com.zcloud.gbscommon.utils.Tools; import com.zcloud.gbscommon.utils.Tools;
import com.zcloud.gbscommon.utils.UuidUtil;
import com.zcloud.service.AlarmTodoService; import com.zcloud.service.AlarmTodoService;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.context.config.annotation.RefreshScope; import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
/** /**
* AppAlarmDisposeSubmitExe - APP * AppAlarmDisposeSubmitExe - APP
@ -27,12 +25,20 @@ import java.time.format.DateTimeFormatter;
@Component @Component
@RequiredArgsConstructor @RequiredArgsConstructor
@RefreshScope @RefreshScope
@Slf4j
public class AppAlarmDisposeSubmitExe { public class AppAlarmDisposeSubmitExe {
private final AlarmRecordGateway alarmRecordGateway; private final AlarmRecordGateway alarmRecordGateway;
private final AlarmTodoService alarmTodoService;
/**
* APP
*
* @param cmd APP
*/
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void execute(AppAlarmDisposeSubmitCmd cmd) { public void execute(AppAlarmDisposeSubmitCmd cmd) {
checkSubmitStatus(cmd.getStatus());
// 查询报警记录 // 查询报警记录
AlarmRecordE alarmRecord = alarmRecordGateway.getById(cmd.getId()); AlarmRecordE alarmRecord = alarmRecordGateway.getById(cmd.getId());
if (Tools.isEmpty(alarmRecord)) { if (Tools.isEmpty(alarmRecord)) {
@ -40,7 +46,7 @@ public class AppAlarmDisposeSubmitExe {
} }
// 检查状态:只有待处置(20)状态可以提交处置 // 检查状态:只有待处置(20)状态可以提交处置
if (alarmRecord.getStatus() != 20) { if (!AlarmRecordStatusEnum.PENDING_DISPOSE.sameStatus(alarmRecord.getStatus())) {
throw new BizException("该报警已处置或状态异常,无法提交处置结果"); throw new BizException("该报警已处置或状态异常,无法提交处置结果");
} }
@ -48,11 +54,39 @@ public class AppAlarmDisposeSubmitExe {
// 更新报警记录 // 更新报警记录
AlarmRecordE updateEntity = new AlarmRecordE(); AlarmRecordE updateEntity = new AlarmRecordE();
BeanUtil.copyProperties(cmd, updateEntity); BeanUtil.copyProperties(cmd, updateEntity);
updateEntity.init(); updateEntity.setStatus(cmd.getStatus());
updateEntity.setDisposeResult(buildDisposeResult(cmd));
updateEntity.setDisposeTime(LocalDateTime.now());
Boolean res = alarmRecordGateway.update(updateEntity); Boolean res = alarmRecordGateway.update(updateEntity);
if (!res) { if (!res) {
throw new BizException("处置提交失败"); throw new BizException("处置提交失败");
} }
completeTodo(cmd.getId());
}
private void checkSubmitStatus(Integer status) {
if (!AlarmRecordStatusEnum.RESOLVED.sameStatus(status)
&& !AlarmRecordStatusEnum.FALSE_ALARM.sameStatus(status)) {
throw new BizException("处置状态不合法");
}
}
private String buildDisposeResult(AppAlarmDisposeSubmitCmd cmd) {
if (StrUtil.isNotBlank(cmd.getDisposeResult())) {
return StrUtil.trim(cmd.getDisposeResult());
}
if (AlarmRecordStatusEnum.FALSE_ALARM.sameStatus(cmd.getStatus())) {
return AlarmRecordStatusEnum.FALSE_ALARM.getDesc();
}
return AlarmRecordStatusEnum.RESOLVED.getDesc();
}
private void completeTodo(Long alarmId) {
try {
alarmTodoService.completeTodo(alarmId);
} catch (Exception e) {
log.error("APP处置提交后发送待办完成失败不影响处置主流程报警ID{},错误:{}", alarmId, e.getMessage(), e);
}
} }
} }

View File

@ -3,6 +3,7 @@ package com.zcloud.command;
import com.alibaba.cola.exception.BizException; import com.alibaba.cola.exception.BizException;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.zcloud.domain.gateway.SensorDeviceGateway; import com.zcloud.domain.gateway.SensorDeviceGateway;
import com.zcloud.domain.model.SensorDeviceE;
import com.zcloud.persistence.dataobject.AlarmRecordDO; import com.zcloud.persistence.dataobject.AlarmRecordDO;
import com.zcloud.persistence.dataobject.RegionSensorRelDO; import com.zcloud.persistence.dataobject.RegionSensorRelDO;
import com.zcloud.persistence.repository.AlarmRecordRepository; import com.zcloud.persistence.repository.AlarmRecordRepository;
@ -29,19 +30,23 @@ public class SensorDeviceRemoveExe {
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public boolean execute(Long id) { public boolean execute(Long id) {
// LambdaQueryWrapper<RegionSensorRelDO> relWrapper = new LambdaQueryWrapper<>(); SensorDeviceE sensorDeviceE = sensorDeviceGateway.getById(id);
// relWrapper.eq(RegionSensorRelDO::getSensorId, id) if (sensorDeviceE==null) {
// .eq(RegionSensorRelDO::getDeleteEnum, "FALSE"); throw new BizException("该传感器不存在");
// if (regionSensorRelRepository.count(relWrapper) > 0) { }
// throw new BizException("该传感器已被使用,不可删除"); LambdaQueryWrapper<RegionSensorRelDO> relWrapper = new LambdaQueryWrapper<>();
// } relWrapper.eq(RegionSensorRelDO::getSensorDeviceId, sensorDeviceE.getSensorDeviceId())
// .eq(RegionSensorRelDO::getDeleteEnum, "FALSE");
// LambdaQueryWrapper<AlarmRecordDO> alarmWrapper = new LambdaQueryWrapper<>(); if (regionSensorRelRepository.count(relWrapper) > 0) {
// alarmWrapper.eq(AlarmRecordDO::getSensorId, id) throw new BizException("该传感器已被使用,不可删除");
// .eq(AlarmRecordDO::getDeleteEnum, "FALSE"); }
// if (alarmRecordRepository.count(alarmWrapper) > 0) {
// throw new BizException("该传感器已被使用,不可删除"); /* LambdaQueryWrapper<AlarmRecordDO> alarmWrapper = new LambdaQueryWrapper<>();
// } alarmWrapper.eq(AlarmRecordDO::getId, id)
.eq(AlarmRecordDO::getDeleteEnum, "FALSE");
if (alarmRecordRepository.count(alarmWrapper) > 0) {
throw new BizException("该传感器已被使用,不可删除");
}*/
boolean res = sensorDeviceGateway.deleteById(id); boolean res = sensorDeviceGateway.deleteById(id);
if (!res) { if (!res) {

View File

@ -25,6 +25,10 @@ public class SensorDeviceUpdateExe {
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public boolean execute(SensorDeviceUpdateCmd cmd) { public boolean execute(SensorDeviceUpdateCmd cmd) {
SensorDeviceE bySensorCode = sensorDeviceGateway.getBySensorCode(cmd.getSensorCode());
if (bySensorCode != null && !bySensorCode.getId().equals(cmd.getId())) {
throw new BizException("传感器编码已存在");
}
SensorDeviceE entity = new SensorDeviceE(); SensorDeviceE entity = new SensorDeviceE();
BeanUtils.copyProperties(cmd, entity); BeanUtils.copyProperties(cmd, entity);

View File

@ -1,6 +1,7 @@
package com.zcloud.service; package com.zcloud.service;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
import com.zcloud.domain.enums.AlarmRecordStatusEnum;
import com.zcloud.domain.model.AlarmRecordE; import com.zcloud.domain.model.AlarmRecordE;
import com.zcloud.gbscommon.todolistmq.TodoListEventPusherUtil; import com.zcloud.gbscommon.todolistmq.TodoListEventPusherUtil;
import com.zcloud.gbscommon.todolistmq.event.TodoListAddEvent; import com.zcloud.gbscommon.todolistmq.event.TodoListAddEvent;
@ -45,6 +46,10 @@ public class AlarmTodoService {
log.warn("新增负责人待办参数不完整,跳过发送"); log.warn("新增负责人待办参数不完整,跳过发送");
return; return;
} }
if (isFalseAlarm(alarmRecord)) {
log.info("报警为误报状态跳过负责人待办发送报警ID: {}", alarmRecord.getId());
return;
}
if (todoPusherUnavailable()) { if (todoPusherUnavailable()) {
return; return;
} }
@ -78,6 +83,10 @@ public class AlarmTodoService {
log.warn("新增处置人待办参数不完整,跳过发送"); log.warn("新增处置人待办参数不完整,跳过发送");
return; return;
} }
if (isFalseAlarm(alarmRecord)) {
log.info("报警为误报状态跳过处置人待办发送报警ID: {}", alarmRecord.getId());
return;
}
if (todoPusherUnavailable()) { if (todoPusherUnavailable()) {
return; return;
} }
@ -101,6 +110,10 @@ public class AlarmTodoService {
} }
} }
private boolean isFalseAlarm(AlarmRecordE alarmRecord) {
return AlarmRecordStatusEnum.FALSE_ALARM.sameStatus(alarmRecord.getStatus());
}
/** /**
* *
* @param alarmId ID * @param alarmId ID

View File

@ -4,6 +4,8 @@ import com.alibaba.cola.dto.PageQuery;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
import lombok.Data; import lombok.Data;
import java.util.List;
/** /**
* AlarmRecordPageQry - * AlarmRecordPageQry -
* @Author wangyan * @Author wangyan
@ -21,8 +23,10 @@ public class AlarmRecordPageQry extends PageQuery {
@ApiModelProperty(value = "处置人姓名") @ApiModelProperty(value = "处置人姓名")
private String disposeUserName; private String disposeUserName;
@ApiModelProperty(value = "当前状态 10待研判/20待处置/30已消警/40误报") @ApiModelProperty(value = "当前状态 10报警中/20未处置/30已消警/40误报")
private Integer status; private Integer status;
@ApiModelProperty(value = "当前状态 10报警中/20未处置/30已消警/40误报")
private List<Integer> statusList;
@ApiModelProperty(value = "报警时间开始") @ApiModelProperty(value = "报警时间开始")
private String alarmTimeStart; private String alarmTimeStart;

View File

@ -7,7 +7,7 @@ import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import javax.validation.constraints.NotEmpty; import javax.validation.constraints.NotNull;
/** /**
* AppAlarmDisposeSubmitCmd - APP * AppAlarmDisposeSubmitCmd - APP
@ -23,8 +23,11 @@ public class AppAlarmDisposeSubmitCmd extends Command {
@ApiModelProperty(value = "报警ID", name = "id", required = true) @ApiModelProperty(value = "报警ID", name = "id", required = true)
private Long id; private Long id;
@ApiModelProperty(value = "处置结果(已消警/误报)", name = "disposeResult", required = true) @ApiModelProperty(value = "处置状态 30已消警/40误报", name = "status", required = true)
@NotEmpty(message = "处置结果不能为空") @NotNull(message = "处置状态不能为空")
private Integer status;
@ApiModelProperty(value = "处置结果快照", name = "disposeResult")
private String disposeResult; private String disposeResult;
@ApiModelProperty(value = "处置视频地址", name = "videoUrl") @ApiModelProperty(value = "处置视频地址", name = "videoUrl")

View File

@ -100,7 +100,7 @@ public class AlarmRecordCO extends ClientObject {
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime alarmTime; private LocalDateTime alarmTime;
@ApiModelProperty(value = "当前状态 10待研判/20待处置/30已消警/40误报") @ApiModelProperty(value = "当前状态 10报警中/20未处置/30已消警/40误报")
private Integer status; private Integer status;
@ApiModelProperty(value = "分配时间") @ApiModelProperty(value = "分配时间")
@ -109,6 +109,9 @@ public class AlarmRecordCO extends ClientObject {
@ApiModelProperty(value = "分配人ID") @ApiModelProperty(value = "分配人ID")
private Long assignUserId; private Long assignUserId;
@ApiModelProperty(value = "分配人姓名")
private String assignUserName;
@ApiModelProperty(value = "处置时间") @ApiModelProperty(value = "处置时间")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime disposeTime; private LocalDateTime disposeTime;

View File

@ -32,6 +32,9 @@ public class DeviceRegionCO extends ClientObject {
@ApiModelProperty(value = "外部消防区域编码") @ApiModelProperty(value = "外部消防区域编码")
private String fireRegionCode; private String fireRegionCode;
@ApiModelProperty(value = "负责企业ID")
private Long corpinfoId;
@ApiModelProperty(value = "负责部门ID") @ApiModelProperty(value = "负责部门ID")
private Long departmentId; private Long departmentId;

View File

@ -0,0 +1,35 @@
package com.zcloud.domain.enums;
import lombok.Getter;
import java.util.Arrays;
/**
*
*/
@Getter
public enum AlarmRecordStatusEnum {
PENDING_REVIEW(10, "报警中"),
PENDING_DISPOSE(20, "待处置"),
RESOLVED(30, "已消警"),
FALSE_ALARM(40, "误报");
private final Integer status;
private final String desc;
AlarmRecordStatusEnum(Integer status, String desc) {
this.status = status;
this.desc = desc;
}
public boolean sameStatus(Integer status) {
return this.status.equals(status);
}
public static AlarmRecordStatusEnum getByStatus(Integer status) {
return Arrays.stream(values())
.filter(item -> item.sameStatus(status))
.findFirst()
.orElse(null);
}
}

View File

@ -1,5 +1,6 @@
package com.zcloud.domain.model; package com.zcloud.domain.model;
import com.zcloud.domain.enums.AlarmRecordStatusEnum;
import com.jjb.saas.framework.domain.model.BaseE; import com.jjb.saas.framework.domain.model.BaseE;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
import lombok.Data; import lombok.Data;
@ -123,6 +124,7 @@ public class AlarmRecordE extends BaseE {
* *
*/ */
private LocalDateTime assignTime; private LocalDateTime assignTime;
private Long assignUserId;
/** /**
* *
@ -180,7 +182,7 @@ public class AlarmRecordE extends BaseE {
private Long orgId; private Long orgId;
public void init(){ public void init(){
this.setStatus(30); this.setStatus(AlarmRecordStatusEnum.RESOLVED.getStatus());
this.setDisposeTime(LocalDateTime.now()); this.setDisposeTime(LocalDateTime.now());
} }
} }

View File

@ -98,13 +98,16 @@ public class AlarmRecordDO extends BaseDO {
@ApiModelProperty(value = "报警时间") @ApiModelProperty(value = "报警时间")
private LocalDateTime alarmTime; private LocalDateTime alarmTime;
@ApiModelProperty(value = "当前状态 10待研判/20待处置/30已消警/40误报") @ApiModelProperty(value = "当前状态 10报警中/20未处置/30已消警/40误报")
private Integer status; private Integer status;
@ApiModelProperty(value = "分配时间") @ApiModelProperty(value = "分配时间")
private LocalDateTime assignTime; private LocalDateTime assignTime;
@ApiModelProperty(value = "分配人ID") @ApiModelProperty(value = "分配人ID")
private Long assignUserId; private Long assignUserId;
@TableField(exist = false)
@ApiModelProperty(value = "分配人姓名")
private String assignUserName;
@ApiModelProperty(value = "处置时间") @ApiModelProperty(value = "处置时间")
private LocalDateTime disposeTime; private LocalDateTime disposeTime;

View File

@ -30,6 +30,9 @@ public class DeviceRegionDO extends BaseDO {
@ApiModelProperty(value = "外部消防区域编码") @ApiModelProperty(value = "外部消防区域编码")
private String fireRegionCode; private String fireRegionCode;
@ApiModelProperty(value = "负责企业ID")
private Long corpinfoId;
@ApiModelProperty(value = "负责部门ID") @ApiModelProperty(value = "负责部门ID")
private Long departmentId; private Long departmentId;

View File

@ -10,6 +10,8 @@
dep.name AS departmentName, dep.name AS departmentName,
mgr.name AS managerName, mgr.name AS managerName,
sd.sensor_name AS sensorName, sd.sensor_name AS sensorName,
assign.name AS assignUserName,
u.name AS disposeUserName u.name AS disposeUserName
</sql> </sql>
@ -21,6 +23,7 @@
LEFT JOIN iot_alarm_sensor_device sd ON ar.sensor_device_id = sd.sensor_device_id AND sd.delete_enum = 'FALSE' LEFT JOIN iot_alarm_sensor_device sd ON ar.sensor_device_id = sd.sensor_device_id AND sd.delete_enum = 'FALSE'
LEFT JOIN user u ON ar.dispose_user_id = u.id LEFT JOIN user u ON ar.dispose_user_id = u.id
LEFT JOIN user assign ON ar.assign_user_id = assign.id
</sql> </sql>
<select id="listPage" resultType="com.zcloud.persistence.dataobject.AlarmRecordDO"> <select id="listPage" resultType="com.zcloud.persistence.dataobject.AlarmRecordDO">
@ -57,21 +60,27 @@
</if> </if>
<if test="params.status != null"> <if test="params.status != null">
AND ar.status = #{params.status} AND ar.status = #{params.status}
</if>
<if test="params.statusList != null and params.statusList.size() > 0">
AND ar.status IN
<foreach collection="params.statusList" item="status" open="(" separator="," close=")">
#{status}
</foreach>
</if> </if>
<if test="params.alarmTimeStart != null and params.alarmTimeStart != ''"> <if test="params.alarmTimeStart != null and params.alarmTimeStart != ''">
AND ar.alarm_time <![CDATA[>=]]> #{params.alarmTimeStart} AND ar.alarm_time <![CDATA[>=]]> CONCAT(#{params.alarmTimeStart}, ' 00:00:00')
</if> </if>
<if test="params.alarmTimeEnd != null and params.alarmTimeEnd != ''"> <if test="params.alarmTimeEnd != null and params.alarmTimeEnd != ''">
AND ar.alarm_time <![CDATA[<=]]> #{params.alarmTimeEnd} AND ar.alarm_time <![CDATA[<=]]> CONCAT(#{params.alarmTimeEnd}, ' 23:59:59')
</if> </if>
<if test="params.disposeTimeStart != null and params.disposeTimeStart != ''"> <if test="params.disposeTimeStart != null and params.disposeTimeStart != ''">
AND ar.dispose_time <![CDATA[>=]]> #{params.disposeTimeStart} AND ar.dispose_time <![CDATA[>=]]> CONCAT(#{params.disposeTimeStart}, ' 00:00:00')
</if> </if>
<if test="params.disposeTimeEnd != null and params.disposeTimeEnd != ''"> <if test="params.disposeTimeEnd != null and params.disposeTimeEnd != ''">
AND ar.dispose_time <![CDATA[<=]]> #{params.disposeTimeEnd} AND ar.dispose_time <![CDATA[<=]]> CONCAT(#{params.disposeTimeEnd}, ' 23:59:59')
</if> </if>
</where> </where>
ORDER BY CASE WHEN ar.status IN (10, 20) THEN 0 ELSE 1 END, ar.alarm_time DESC ORDER BY ar.alarm_time DESC
</select> </select>
<select id="listBySensorDevice" resultType="com.zcloud.persistence.dataobject.AlarmRecordDO"> <select id="listBySensorDevice" resultType="com.zcloud.persistence.dataobject.AlarmRecordDO">
@ -95,10 +104,10 @@
AND ar.sensor_device_id = #{params.sensorDeviceId} AND ar.sensor_device_id = #{params.sensorDeviceId}
</if> </if>
<if test="params.alarmTimeStart != null and params.alarmTimeStart != ''"> <if test="params.alarmTimeStart != null and params.alarmTimeStart != ''">
AND ar.alarm_time <![CDATA[>=]]> #{params.alarmTimeStart} AND ar.alarm_time <![CDATA[>=]]> CONCAT(#{params.alarmTimeStart}, ' 00:00:00')
</if> </if>
<if test="params.alarmTimeEnd != null and params.alarmTimeEnd != ''"> <if test="params.alarmTimeEnd != null and params.alarmTimeEnd != ''">
AND ar.alarm_time <![CDATA[<=]]> #{params.alarmTimeEnd} AND ar.alarm_time <![CDATA[<=]]> CONCAT(#{params.alarmTimeEnd}, ' 23:59:59')
</if> </if>
</where> </where>
ORDER BY ar.alarm_time DESC ORDER BY ar.alarm_time DESC
@ -146,10 +155,10 @@
AND ar.alarm_type = #{params.alarmType} AND ar.alarm_type = #{params.alarmType}
</if> </if>
<if test="params.alarmTimeStart != null and params.alarmTimeStart != ''"> <if test="params.alarmTimeStart != null and params.alarmTimeStart != ''">
AND ar.alarm_time <![CDATA[>=]]> #{params.alarmTimeStart} AND ar.alarm_time <![CDATA[>=]]> CONCAT(#{params.alarmTimeStart}, ' 00:00:00')
</if> </if>
<if test="params.alarmTimeEnd != null and params.alarmTimeEnd != ''"> <if test="params.alarmTimeEnd != null and params.alarmTimeEnd != ''">
AND ar.alarm_time <![CDATA[<=]]> #{params.alarmTimeEnd} AND ar.alarm_time <![CDATA[<=]]> CONCAT(#{params.alarmTimeEnd}, ' 23:59:59')
</if> </if>
</where> </where>
ORDER BY ar.alarm_time DESC ORDER BY ar.alarm_time DESC
@ -173,10 +182,10 @@
</otherwise> </otherwise>
</choose> </choose>
<if test="params.alarmTimeStart != null and params.alarmTimeStart != ''"> <if test="params.alarmTimeStart != null and params.alarmTimeStart != ''">
AND ar.alarm_time <![CDATA[>=]]> #{params.alarmTimeStart} AND ar.alarm_time <![CDATA[>=]]> CONCAT(#{params.alarmTimeStart}, ' 00:00:00')
</if> </if>
<if test="params.alarmTimeEnd != null and params.alarmTimeEnd != ''"> <if test="params.alarmTimeEnd != null and params.alarmTimeEnd != ''">
AND ar.alarm_time <![CDATA[<=]]> #{params.alarmTimeEnd} AND ar.alarm_time <![CDATA[<=]]> CONCAT(#{params.alarmTimeEnd}, ' 23:59:59')
</if> </if>
</where> </where>
ORDER BY ar.alarm_time DESC ORDER BY ar.alarm_time DESC
@ -226,10 +235,10 @@
AND ar.dispose_user_id = #{params.currentUserId} AND ar.dispose_user_id = #{params.currentUserId}
</if> </if>
<if test="params.alarmTimeStart != null and params.alarmTimeStart != ''"> <if test="params.alarmTimeStart != null and params.alarmTimeStart != ''">
AND ar.alarm_time <![CDATA[>=]]> #{params.alarmTimeStart} AND ar.alarm_time <![CDATA[>=]]> CONCAT(#{params.alarmTimeStart}, ' 00:00:00')
</if> </if>
<if test="params.alarmTimeEnd != null and params.alarmTimeEnd != ''"> <if test="params.alarmTimeEnd != null and params.alarmTimeEnd != ''">
AND ar.alarm_time <![CDATA[<=]]> #{params.alarmTimeEnd} AND ar.alarm_time <![CDATA[<=]]> CONCAT(#{params.alarmTimeEnd}, ' 23:59:59')
</if> </if>
</where> </where>
ORDER BY ar.alarm_time DESC ORDER BY ar.alarm_time DESC

View File

@ -11,6 +11,7 @@
fr.fire_region_id AS fireRegionId, fr.fire_region_id AS fireRegionId,
fr.fire_region_name AS fireRegionName, fr.fire_region_name AS fireRegionName,
fr.fire_region_code AS fireRegionCode, fr.fire_region_code AS fireRegionCode,
d.corpinfo_id as corpInfoId,
fr.department_id AS departmentId, fr.department_id AS departmentId,
d.name AS departmentName, d.name AS departmentName,
rc.manager_id AS managerId, rc.manager_id AS managerId,

View File

@ -20,7 +20,7 @@
asd.sensor_type_id asd.sensor_type_id
from iot_alarm_region_sensor_rel arsr from iot_alarm_region_sensor_rel arsr
left join iot_alarm_sensor_device asd on asd.sensor_device_id = arsr.sensor_device_id left join iot_alarm_sensor_device asd on asd.sensor_device_id = arsr.sensor_device_id
left join iot_alarm_sensor_type ast on ast.sensor_type_id = asd.sensor_type_id left join iot_alarm_sensor_type ast on ast.id = asd.sensor_type_id
where arsr.delete_enum = 'FALSE' where arsr.delete_enum = 'FALSE'
and arsr.fire_region_id = #{regionId} and arsr.fire_region_id = #{regionId}
</select> </select>

View File

@ -7,7 +7,8 @@
<select id="listPage" resultType="com.zcloud.persistence.dataobject.SensorDeviceDO"> <select id="listPage" resultType="com.zcloud.persistence.dataobject.SensorDeviceDO">
SELECT SELECT
sd.*, sd.*,
st.type_name AS sensorTypeName st.type_name AS sensorTypeName,
rel.fire_region_id as fireRegionId
FROM iot_alarm_sensor_device sd FROM iot_alarm_sensor_device sd
LEFT JOIN iot_alarm_region_sensor_rel rel ON rel.sensor_device_id = sd.sensor_device_id AND rel.delete_enum = 'FALSE' LEFT JOIN iot_alarm_region_sensor_rel rel ON rel.sensor_device_id = sd.sensor_device_id AND rel.delete_enum = 'FALSE'
LEFT JOIN iot_alarm_sensor_type st ON sd.sensor_type_id = st.id AND st.delete_enum = 'FALSE' LEFT JOIN iot_alarm_sensor_type st ON sd.sensor_type_id = st.id AND st.delete_enum = 'FALSE'