AbstractDataAlarmJobService.java 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269
  1. package com.huaxu.quartz.service;
  2. import com.alibaba.fastjson.JSONObject;
  3. import com.huaxu.client.UserCenterClient;
  4. import com.huaxu.common.CalcUtil;
  5. import com.huaxu.dao.alarm.DataAlarmAnalysisMapper;
  6. import com.huaxu.dao.alarm.DataAlarmDetailMapper;
  7. import com.huaxu.dao.alarm.DataAlarmManageMapper;
  8. import com.huaxu.dto.DeviceCheckAlarmDto;
  9. import com.huaxu.entity.Message;
  10. import com.huaxu.entity.alarm.DataAlarmAnalysisEntity;
  11. import com.huaxu.entity.alarm.DataAlarmDetailEntity;
  12. import com.huaxu.entity.alarm.DataAlarmManageEntity;
  13. import com.huaxu.util.DatesUtil;
  14. import com.huaxu.vo.DataAlarmManageVo;
  15. import lombok.extern.slf4j.Slf4j;
  16. import org.springframework.amqp.core.AmqpTemplate;
  17. import org.springframework.beans.BeanUtils;
  18. import org.springframework.beans.factory.annotation.Autowired;
  19. import org.springframework.beans.factory.annotation.Value;
  20. import org.springframework.util.CollectionUtils;
  21. import javax.annotation.Resource;
  22. import java.math.BigDecimal;
  23. import java.time.LocalDate;
  24. import java.util.*;
  25. import java.util.stream.Collectors;
  26. /**
  27. * 数据报警处理
  28. * @author lihui
  29. * @date 2020-3-26
  30. */
  31. @Slf4j
  32. public abstract class AbstractDataAlarmJobService {
  33. @Resource
  34. protected DataAlarmDetailMapper dataAlarmDetailMapper;
  35. @Resource
  36. protected DataAlarmAnalysisMapper dataAlarmAnalysisMapper;
  37. @Resource
  38. protected DataAlarmManageMapper dataAlarmManageMapper;
  39. @Autowired
  40. protected UserCenterClient userCenterClient;
  41. @Resource(name = "messageRabbitTemplate")
  42. private AmqpTemplate messageRabbitTemplate;
  43. @Value("${receive.exchange.name}")
  44. private String receiveExchangeName;
  45. @Value("${dispath.routing.key}")
  46. private String dispathRoutingKey;
  47. /**
  48. * 挂起
  49. */
  50. protected static final int HANG_UP = 1;
  51. /***
  52. * 执行入口
  53. * @author lihui
  54. * @date 18:48 2021/6/1
  55. * @return void
  56. **/
  57. public void execute(){
  58. List<DataAlarmManageVo> manageVoList = this.listDataAlarmManage();
  59. if (CollectionUtils.isEmpty(manageVoList)) {
  60. log.info("获取数据报警管理参数数据为空");
  61. return;
  62. }
  63. DataAlarmManageEntity manageEntity = null;
  64. Map<Long, DataAlarmDetailEntity> alarmDetailsDtoMap = getMapDataAlarmDetail(manageVoList);
  65. for (DataAlarmManageVo manageVo : manageVoList) {
  66. manageEntity = new DataAlarmManageEntity();
  67. BeanUtils.copyProperties(manageVo, manageEntity);
  68. DataAlarmDetailEntity nowDetailEntity = this.getAlarmValue(manageEntity);
  69. if (nowDetailEntity == null) {
  70. continue;
  71. }
  72. nowDetailEntity.setManageId(manageEntity.getId());
  73. boolean isAlarm = isAlarm(nowDetailEntity, manageEntity);
  74. // 必须先计算报警数据,才能执行保存数据报警分析操作,不然会丢失数据
  75. this.saveDataAlarmAnalysis(nowDetailEntity);
  76. // 计算出来属于报警,处理报警数据
  77. if (isAlarm) {
  78. handAlarm(alarmDetailsDtoMap, manageVo, nowDetailEntity);
  79. continue;
  80. }
  81. // 存在报警信息,但已不报警,则更新为历史数据
  82. if (alarmDetailsDtoMap.containsKey(manageEntity.getId())){
  83. dataAlarmDetailMapper.updateHistoryData(alarmDetailsDtoMap.get(manageEntity.getId()).getId());
  84. }
  85. }
  86. }
  87. /***
  88. * double转换BigDecimal
  89. * @author lihui
  90. * @date 11:48 2021/6/2
  91. * @param receivedValue :
  92. * @return java.math.BigDecimal
  93. **/
  94. protected BigDecimal toBigDecimal(Double receivedValue){
  95. return receivedValue == null ? null : new BigDecimal(receivedValue.toString());
  96. }
  97. /***
  98. * 保存报警数据
  99. * @author lihui
  100. * @date 11:09 2021/6/2
  101. * @param detailEntity :
  102. * @return void
  103. **/
  104. protected void saveDataAlarmDetail(DataAlarmDetailEntity detailEntity){
  105. detailEntity.setAlarmStartTime(new Date());
  106. detailEntity.setDateCreate(new Date());
  107. detailEntity.setStatus(1);
  108. dataAlarmDetailMapper.saveDataAlarmDetail(detailEntity);
  109. }
  110. /***
  111. * 保存分析数据详情
  112. * @author lihui
  113. * @date 9:43 2021/6/2
  114. * @param detailEntity :
  115. * @return void
  116. **/
  117. protected void saveDataAlarmAnalysis(DataAlarmDetailEntity detailEntity){
  118. DataAlarmAnalysisEntity analysisEntity = new DataAlarmAnalysisEntity();
  119. BeanUtils.copyProperties(detailEntity, analysisEntity);
  120. analysisEntity.setDateCreate(new Date());
  121. analysisEntity.setStatus(1);
  122. dataAlarmAnalysisMapper.saveDataAlarmAnalysis(analysisEntity);
  123. }
  124. /***
  125. * 数据存在,需要根据当前设置的计算规则和正在报警的计算规则是否一样
  126. * 一样:更新数据
  127. * 不一样:更新该条正在报警的数据为历史数据,并新增一条新计算规则的报警数据
  128. * this.sendMessage(manageEntity);
  129. * @author lihui
  130. * @date 11:06 2021/6/2
  131. * @param alarmDetailsDtoMap : 现有报警数据
  132. * @param manageVo : 报警设置数据
  133. * @param nowDetailEntity : 当前报警数据
  134. * @return void
  135. **/
  136. private void handAlarm(Map<Long, DataAlarmDetailEntity> alarmDetailsDtoMap, DataAlarmManageVo manageVo, DataAlarmDetailEntity nowDetailEntity){
  137. if (!alarmDetailsDtoMap.containsKey(manageVo.getId())){
  138. this.saveDataAlarmDetail(nowDetailEntity);
  139. this.sendMessage(manageVo);
  140. return;
  141. }
  142. DataAlarmDetailEntity dataAlarmDetailEntity = alarmDetailsDtoMap.get(manageVo.getId());
  143. // 如果没有被挂起,就要发送消息提示
  144. if (dataAlarmDetailEntity.getIsHangup() != HANG_UP){
  145. this.sendMessage(manageVo);
  146. }
  147. // 检查计算规则是否有变更
  148. if (manageVo.getMd5Query().equals(dataAlarmDetailEntity.getMd5Query())) {
  149. dataAlarmDetailMapper.updateAlrarmData(dataAlarmDetailEntity);
  150. return;
  151. }
  152. // 规则有变革,数据更新为历史数据,再添加一条新的历史报警记录
  153. dataAlarmDetailMapper.updateHistoryData(dataAlarmDetailEntity.getId());
  154. this.saveDataAlarmDetail(nowDetailEntity);
  155. }
  156. /***
  157. * 获取报警数据
  158. * @author lihui
  159. * @date 10:58 2021/6/2
  160. * @param manageVoList :
  161. * @return java.util.Map<java.lang.Long,com.huaxu.entity.alarm.DataAlarmDetailEntity>
  162. **/
  163. private Map<Long, DataAlarmDetailEntity> getMapDataAlarmDetail(List<DataAlarmManageVo> manageVoList){
  164. List<Long> manageIds = manageVoList.stream().map(DataAlarmManageVo::getId).collect(Collectors.toList());
  165. List<DataAlarmDetailEntity> list = dataAlarmDetailMapper.listByManageId(manageIds);
  166. if (CollectionUtils.isEmpty(list)){
  167. return new HashMap<>();
  168. }
  169. return list.stream().collect(Collectors.toMap(DataAlarmDetailEntity::getManageId, a -> a,(k1, k2)->k1));
  170. }
  171. /***
  172. * 判断是否触发报警
  173. * @author lihui
  174. * @date 18:22 2021/6/1
  175. * @param dataAlarmDetailEntity :
  176. * @param dataAlarmManageEntity :
  177. * @return boolean
  178. **/
  179. private boolean isAlarm(DataAlarmDetailEntity dataAlarmDetailEntity, DataAlarmManageEntity dataAlarmManageEntity){
  180. BigDecimal resultValue = CalcUtil.operation(dataAlarmDetailEntity.getBeAlarmValue(), dataAlarmManageEntity.getComputeRules(),
  181. dataAlarmDetailEntity.getToAlarmValue());
  182. dataAlarmDetailEntity.setResultAlarmValue(resultValue);
  183. return CalcUtil.compareBySign(resultValue, dataAlarmManageEntity.getAlarmValue(), dataAlarmManageEntity.getAlarmRules());
  184. }
  185. /***
  186. * 消息发送
  187. * @author lihui
  188. * @date 18:46 2021/6/1
  189. * @param dataAlarmManageEntity :
  190. * @return void
  191. **/
  192. private void sendMessage(DataAlarmManageVo dataAlarmManageEntity){
  193. Message message = new Message();
  194. message.setStatus(1);
  195. message.setTenantId(dataAlarmManageEntity.getTenantId());
  196. message.setMessageId(UUID.randomUUID().toString());
  197. JSONObject jsonContent = new JSONObject();
  198. // ${场景名称}${设备名称}【${报警字段}】异常报警
  199. jsonContent.put("场景名称",dataAlarmManageEntity.getAlarmSettingRules());
  200. jsonContent.put("设备名称","");
  201. jsonContent.put("报警字段","");
  202. // 消息内容,如果需要动态使用,配合模板使用{key:value}
  203. message.setMessageContent(jsonContent.toJSONString());
  204. // 消息类型、模板id、渠道
  205. message.setMessageType(1);
  206. message.setMessageTemplateId(1);
  207. message.setChannel(0);
  208. Integer companyOrgId = dataAlarmManageEntity.getCompanyOrgId();
  209. Integer departmentOrgId = dataAlarmManageEntity.getDeptOrgId();
  210. try{
  211. List<Integer> taskUsers = userCenterClient.findUserIdsByPermissonOrg(dataAlarmManageEntity.getTenantId(),companyOrgId,departmentOrgId);
  212. if (taskUsers == null) {
  213. return;
  214. }
  215. taskUsers.forEach(id -> {
  216. message.setUserId(id);
  217. this.send(message);
  218. });
  219. } catch (Exception e) {
  220. log.error ("推送报警消息失败:{}",e);
  221. }
  222. }
  223. private void send(Message message){
  224. log.debug("消息发送 exchange={} routingkey={} 用户id={}",receiveExchangeName,dispathRoutingKey,message.getUserId());
  225. messageRabbitTemplate.convertAndSend(receiveExchangeName, dispathRoutingKey, JSONObject.toJSONString(message));
  226. }
  227. /***
  228. * 获取设置的报警参数
  229. * @author lihui
  230. * @date 18:15 2021/6/1
  231. * @return java.util.List<com.huaxu.entity.alarm.DataAlarmManageEntity>
  232. **/
  233. protected abstract List<DataAlarmManageVo> listDataAlarmManage();
  234. /***
  235. * 获取报警值
  236. * @author lihui
  237. * @date 11:47 2021/6/2
  238. * @param dataAlarmManageEntity : 报警设置参数
  239. * @return com.huaxu.entity.alarm.DataAlarmDetailEntity
  240. **/
  241. protected abstract DataAlarmDetailEntity getAlarmValue(DataAlarmManageEntity dataAlarmManageEntity);
  242. }