验收3-设备保护告警同步本地

This commit is contained in:
2025-11-13 00:02:47 +08:00
parent f1e819ba2b
commit 38ade0c2ed
13 changed files with 960 additions and 62 deletions

View File

@ -0,0 +1,262 @@
package com.xzzn.framework.aspectj;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.xzzn.common.utils.StringUtils;
import com.xzzn.ems.domain.EmsFaultProtectionPlan;
import com.xzzn.ems.domain.MqttSyncLog;
import com.xzzn.ems.mapper.EmsFaultProtectionPlanMapper;
import com.xzzn.ems.mapper.EmsMqttTopicConfigMapper;
import com.xzzn.ems.mapper.MqttSyncLogMapper;
import com.xzzn.framework.web.service.MqttPublisher;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cglib.beans.BeanMap;
import org.springframework.stereotype.Component;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
/**
* 设备保护告警同步
*/
@Aspect
@Component
public class FaultProtPlanAspect {
@Autowired
private MqttPublisher mqttPublisher;
private static final ObjectMapper objectMapper = new ObjectMapper();
private static final String STRATEGY_TOPIC = "FAULT_PROTECTION_PLAN_UP";
private static final String TABLE_NAME = "ems_fault_protection_plan";
@Autowired
private EmsMqttTopicConfigMapper emsMqttTopicConfigMapper;
@Autowired
private MqttSyncLogMapper mqttSyncLogMapper;
@Autowired
private EmsFaultProtectionPlanMapper emsFaultProtectionPlanMapper;
// 用ThreadLocal暂存删除前的对象
private ThreadLocal<EmsFaultProtectionPlan> beforeDeleteThreadLocal = new ThreadLocal<>();
@Before("execution(* com.xzzn.ems.mapper.EmsFaultProtectionPlanMapper.deleteEmsFaultProtectionPlanByIds(..)) && args(ids)")
public void beforeDelete(JoinPoint joinPoint, Long[] ids) {
// 获取删除的id
Object[] args = joinPoint.getArgs();
if (args == null || args.length == 0) {
return;
}
Long[] id = (Long[]) args[0];
// 查询删除前的数据
EmsFaultProtectionPlan faultInfo = emsFaultProtectionPlanMapper.selectEmsFaultProtectionPlanById(id[0]);
beforeDeleteThreadLocal.set(faultInfo); // 暂存
}
// 定义切点拦截策略相关表的Mapper方法
@Pointcut("(execution(* com.xzzn.ems.mapper.EmsFaultProtectionPlanMapper.insertEmsFaultProtectionPlan(..)) && args(insertEntity)) ")
public void insertPointCut(EmsFaultProtectionPlan insertEntity) {
System.out.println("【新增设备保护告警】FaultProtPlanAspect 实例化");
}
@Pointcut("(execution(* com.xzzn.ems.mapper.EmsFaultProtectionPlanMapper.updateEmsFaultProtectionPlan(..)) && args(updateEntity)) ")
public void updatePointCut(EmsFaultProtectionPlan updateEntity) {
System.out.println("【更新设备保护告警】FaultProtPlanAspect 实例化");
}
@Pointcut("(execution(* com.xzzn.ems.mapper.EmsFaultProtectionPlanMapper.deleteEmsFaultProtectionPlanByIds(..)) && args(ids)) ")
public void deletePointCut(Long[] ids) {
System.out.println("【删除设备保护告警】FaultProtPlanAspect 实例化");
}
// 方法执行成功后发布同步消息
@AfterReturning(pointcut = "insertPointCut(insertEntity)", returning = "result")
public void afterInsert(JoinPoint joinPoint, EmsFaultProtectionPlan insertEntity, Integer result) {
System.out.println("【新增设备保护告警切面进入成功】");
if (result == 0) {
return;
}
// 解析方法名获取操作类型INSERT/UPDATE/DELETE和表名
String methodName = joinPoint.getSignature().getName();
String operateType = getOperateType(methodName);
String siteId = insertEntity.getSiteId();
// 构建日志同步消息
MqttSyncLog message = createMessageObject(operateType,siteId);
try {
// 数据转换
String content = convertEntityToJson(insertEntity);
message.setContent(content);
// 发布到MQTT主题
String topic = emsMqttTopicConfigMapper.checkTopicIsExist(STRATEGY_TOPIC);
if (StringUtils.isEmpty(topic)) {
mqttPublisher.publish(STRATEGY_TOPIC, objectMapper.writeValueAsString(message), 1);
}
} catch (Exception e) {
message.setStatus("FAIL");
message.setErrorMsg(e.getMessage());
}
// 存储同步信息
mqttSyncLogMapper.insertMqttSyncLog(message);
}
@AfterReturning(pointcut = "updatePointCut(updateEntity)", returning = "result")
public void afterUpdate(JoinPoint joinPoint, EmsFaultProtectionPlan updateEntity, Integer result) {
System.out.println("【更新设备保护告警切面进入成功】");
if (result == 0) {
return;
}
// 解析方法名获取操作类型INSERT/UPDATE/DELETE和表名
String methodName = joinPoint.getSignature().getName();
String operateType = getOperateType(methodName);
String siteId = updateEntity.getSiteId();
// 构建日志同步消息
MqttSyncLog message = createMessageObject(operateType,siteId);
try {
// 数据转换
String content = convertEntityToJson(updateEntity);
message.setContent(content);
// 发布到MQTT主题 - 判断区分本地还是云上
String topic = emsMqttTopicConfigMapper.checkTopicIsExist(STRATEGY_TOPIC);
if (StringUtils.isEmpty(topic)) {
mqttPublisher.publish(STRATEGY_TOPIC, objectMapper.writeValueAsString(message), 1);
}
} catch (Exception e) {
message.setStatus("FAIL");
message.setErrorMsg(e.getMessage());
}
// 存储同步信息
mqttSyncLogMapper.insertMqttSyncLog(message);
}
@AfterReturning(pointcut = "deletePointCut(id)", returning = "result")
public void afterDelete(JoinPoint joinPoint, Long[] id, Integer result) {
System.out.println("【删除设备保护告警切面进入成功】");
if (result == 0) {
return;
}
// 解析方法名获取操作类型INSERT/UPDATE/DELETE和表名
String methodName = joinPoint.getSignature().getName();
String operateType = getOperateType(methodName);
// 从ThreadLocal中获取删除前的对象
EmsFaultProtectionPlan faultInfo = beforeDeleteThreadLocal.get();
if (faultInfo == null) {
return;
}
// 构建日志同步消息
MqttSyncLog message = createMessageObject(operateType,faultInfo.getSiteId());
try {
// 数据转换
String content = convertEntityToJson(faultInfo);
message.setContent(content);
// 发布到MQTT主题
String topic = emsMqttTopicConfigMapper.checkTopicIsExist(STRATEGY_TOPIC);
if (StringUtils.isEmpty(topic)) {
mqttPublisher.publish(STRATEGY_TOPIC, objectMapper.writeValueAsString(message), 1);
}
} catch (Exception e) {
message.setStatus("FAIL");
message.setErrorMsg(e.getMessage());
}
// 存储同步信息
mqttSyncLogMapper.insertMqttSyncLog(message);
}
// 构建同步信息
private MqttSyncLog createMessageObject(String operateType, String siteId) {
MqttSyncLog message = new MqttSyncLog();
message.setSyncId(UUID.randomUUID().toString());
message.setOperateType(operateType);
message.setTableName(TABLE_NAME);
message.setCreateTime(new Date());
message.setTopic(STRATEGY_TOPIC);
message.setStatus("SUCCESS");
message.setTarget(siteId);
return message;
}
// 从方法名判断操作类型示例insert→INSERTupdate→UPDATEdelete→DELETE
private String getOperateType(String methodName) {
if (methodName.startsWith("insert")) return "INSERT";
if (methodName.startsWith("stop")) return "STOP";
if (methodName.startsWith("update") || methodName.startsWith("stop")) return "UPDATE";
if (methodName.startsWith("delete")) return "DELETE";
return "UNKNOWN";
}
// 从方法参数提取数据示例若参数是实体类转成Map
private Map<String, Object> extractDataFromParams(Object[] args) {
// 实际需反射获取实体类的字段和值如id、name等
Map<String, Object> data = new HashMap<>();
if (args == null || args.length == 0) {
return data;
}
for (int i = 0; i < args.length; i++) {
Object arg = args[i];
if (arg == null) {
continue; // 跳过null参数
}
// 处理基本类型/包装类/字符串直接作为值存入key为"param0"、"param1"等)
if (isBasicType(arg.getClass())) {
String key = "param" + i; // 基本类型参数用"param0"、"param1"作为key
data.put(key, arg);
} else {
Map<String, Object> beanMap = beanToMap(arg);
data.putAll(beanMap); // 合并实体类的字段到结果Map
}
}
return data;
}
/**
* 判断是否为基本类型或包装类或字符串
*/
private boolean isBasicType(Class<?> clazz) {
return clazz.isPrimitive() // 基本类型int、long、boolean等
|| clazz == String.class // 字符串
|| Number.class.isAssignableFrom(clazz) // 数字包装类Integer、Long等
|| clazz == Boolean.class; // 布尔包装类
}
/**
* 将实体类转换为Map字段名为key字段值为value
*/
private Map<String, Object> beanToMap(Object bean) {
Map<String, Object> map = new HashMap<>();
if (bean == null) {
return map;
}
// 方式1使用BeanMap简洁高效
BeanMap beanMap = BeanMap.create(bean);
for (Object key : beanMap.keySet()) {
map.put(key.toString(), beanMap.get(key));
}
return map;
}
// 在方法中转换
public String convertEntityToJson(EmsFaultProtectionPlan insertEntity) throws Exception {
if (insertEntity == null) {
return null; // 空对象返回空JSON
}
// 将实体类转换为JSON字符串
return objectMapper.writeValueAsString(insertEntity);
}
}

View File

@ -4,9 +4,10 @@ import com.alibaba.fastjson2.JSON;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.xzzn.common.utils.StringUtils;
import com.xzzn.ems.domain.EmsStrategyRunning;
import com.xzzn.ems.domain.MqttSyncStrategyLog;
import com.xzzn.ems.domain.MqttSyncLog;
import com.xzzn.ems.mapper.EmsMqttTopicConfigMapper;
import com.xzzn.ems.mapper.MqttSyncStrategyLogMapper;
import com.xzzn.ems.mapper.EmsStrategyRunningMapper;
import com.xzzn.ems.mapper.MqttSyncLogMapper;
import com.xzzn.framework.web.service.MqttPublisher;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
@ -21,18 +22,24 @@ import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
/**
* 策略运行切面同步
*/
@Aspect
@Component
public class StrategySyncAspect {
@Autowired
private MqttPublisher mqttPublisher;
@Autowired
private MqttSyncStrategyLogMapper mqttSyncStrategyLogMapper;
private static final ObjectMapper objectMapper = new ObjectMapper();
private static final String STRATEGY_TOPIC = "EMS_STRATEGY_UP";
private static final String TABLE_NAME = "ems_strategy_running";
@Autowired
private EmsMqttTopicConfigMapper emsMqttTopicConfigMapper;
@Autowired
private MqttSyncLogMapper mqttSyncLogMapper;
@Autowired
private EmsStrategyRunningMapper emsStrategyRunningMapper;
// 定义切点拦截策略相关表的Mapper方法
@Pointcut("(execution(* com.xzzn.ems.mapper.EmsStrategyRunningMapper.stopEmsStrategyRunning(..)) && args(id)) ")
@ -49,8 +56,8 @@ public class StrategySyncAspect {
}
// 方法执行成功后发布同步消息
@AfterReturning(pointcut = "updatePointCut(insertEntity)", returning = "result")
public void afterUpdate(JoinPoint joinPoint, EmsStrategyRunning insertEntity, Integer result) {
@AfterReturning(pointcut = "updatePointCut(updateEntity)", returning = "result")
public void afterUpdate(JoinPoint joinPoint, EmsStrategyRunning updateEntity, Integer result) {
System.out.println("【更新策略切面进入成功】");
if (result == 0) {
return;
@ -58,33 +65,27 @@ public class StrategySyncAspect {
// 解析方法名获取操作类型INSERT/UPDATE/DELETE和表名
String methodName = joinPoint.getSignature().getName();
String operateType = getOperateType(methodName);
String tableName = getTableNameFromMethod(methodName); // 从Mapper类名提取表名
String siteId = updateEntity.getSiteId();
// 构建日志同步消息
MqttSyncStrategyLog message = new MqttSyncStrategyLog();
message.setSyncId(UUID.randomUUID().toString());
message.setOperateType(operateType);
message.setTableName(tableName);
message.setCreateTime(new Date());
message.setTopic(STRATEGY_TOPIC);
message.setStatus("SUCCESS");
MqttSyncLog message = createMessageObject(operateType,siteId);
try {
// 数据转换
String content = convertEntityToJson(insertEntity);
String content = convertEntityToJson(updateEntity);
message.setContent(content);
// 发布到MQTT主题
// 发布到MQTT主题 - 判断区分本地还是云上
String topic = emsMqttTopicConfigMapper.checkTopicIsExist(STRATEGY_TOPIC);
if (!StringUtils.isEmpty(topic)) {
mqttPublisher.publish(topic, objectMapper.writeValueAsString(message), 1);
if (StringUtils.isEmpty(topic)) {
mqttPublisher.publish(STRATEGY_TOPIC, objectMapper.writeValueAsString(message), 1);
}
} catch (Exception e) {
message.setStatus("FAIL");
message.setErrorMsg(e.getMessage());
}
// 存储同步信息
mqttSyncStrategyLogMapper.insertMqttSyncStrategyLog(message);
mqttSyncLogMapper.insertMqttSyncLog(message);
}
@AfterReturning(pointcut = "insertPointCut(insertEntity)", returning = "result")
@ -96,16 +97,10 @@ public class StrategySyncAspect {
// 解析方法名获取操作类型INSERT/UPDATE/DELETE和表名
String methodName = joinPoint.getSignature().getName();
String operateType = getOperateType(methodName);
String tableName = getTableNameFromMethod(methodName); // 从Mapper类名提取表名
String siteId = insertEntity.getSiteId();
// 构建日志同步消息
MqttSyncStrategyLog message = new MqttSyncStrategyLog();
message.setSyncId(UUID.randomUUID().toString());
message.setOperateType(operateType);
message.setTableName(tableName);
message.setCreateTime(new Date());
message.setTopic(STRATEGY_TOPIC);
message.setStatus("SUCCESS");
MqttSyncLog message = createMessageObject(operateType, siteId);
try {
// 数据转换
@ -113,13 +108,16 @@ public class StrategySyncAspect {
message.setContent(content);
// 发布到MQTT主题
mqttPublisher.publish(STRATEGY_TOPIC, objectMapper.writeValueAsString(message), 1);
String topic = emsMqttTopicConfigMapper.checkTopicIsExist(STRATEGY_TOPIC);
if (StringUtils.isEmpty(topic)) {
mqttPublisher.publish(STRATEGY_TOPIC, objectMapper.writeValueAsString(message), 1);
}
} catch (Exception e) {
message.setStatus("FAIL");
message.setErrorMsg(e.getMessage());
}
// 存储同步信息
mqttSyncStrategyLogMapper.insertMqttSyncStrategyLog(message);
mqttSyncLogMapper.insertMqttSyncLog(message);
}
@AfterReturning(pointcut = "stopPointCut(id)", returning = "result")
@ -131,17 +129,11 @@ public class StrategySyncAspect {
// 解析方法名获取操作类型INSERT/UPDATE/DELETE和表名
String methodName = joinPoint.getSignature().getName();
String operateType = getOperateType(methodName);
String tableName = getTableNameFromMethod(methodName); // 从Mapper类名提取表名
EmsStrategyRunning emsStrategyRunning = emsStrategyRunningMapper.selectEmsStrategyRunningById(id);
String siteId = emsStrategyRunning==null ? null : emsStrategyRunning.getSiteId();
// 构建日志同步消息
MqttSyncStrategyLog message = new MqttSyncStrategyLog();
message.setSyncId(UUID.randomUUID().toString());
message.setOperateType(operateType);
message.setTableName(tableName);
message.setCreateTime(new Date());
message.setTopic(STRATEGY_TOPIC);
message.setStatus("SUCCESS");
MqttSyncLog message = createMessageObject(operateType, siteId);
try {
// 数据转换
@ -151,15 +143,30 @@ public class StrategySyncAspect {
message.setContent(content);
// 发布到MQTT主题
mqttPublisher.publish(STRATEGY_TOPIC, objectMapper.writeValueAsString(message), 1);
String topic = emsMqttTopicConfigMapper.checkTopicIsExist(STRATEGY_TOPIC);
if (StringUtils.isEmpty(topic)) {
mqttPublisher.publish(STRATEGY_TOPIC, objectMapper.writeValueAsString(message), 1);
}
} catch (Exception e) {
message.setStatus("FAIL");
message.setErrorMsg(e.getMessage());
}
// 存储同步信息
mqttSyncStrategyLogMapper.insertMqttSyncStrategyLog(message);
mqttSyncLogMapper.insertMqttSyncLog(message);
}
// 构建同步信息
private MqttSyncLog createMessageObject(String operateType, String siteId) {
MqttSyncLog message = new MqttSyncLog();
message.setSyncId(UUID.randomUUID().toString());
message.setOperateType(operateType);
message.setTableName(TABLE_NAME);
message.setCreateTime(new Date());
message.setTopic(STRATEGY_TOPIC);
message.setStatus("SUCCESS");
message.setTarget(siteId);
return message;
}
// 从方法名判断操作类型示例insert→INSERTupdate→UPDATEdelete→DELETE
private String getOperateType(String methodName) {
if (methodName.startsWith("insert")) return "INSERT";
@ -169,12 +176,6 @@ public class StrategySyncAspect {
return "UNKNOWN";
}
// 从Mapper类名提取表名示例StrategyMapper→strategy
private String getTableNameFromMethod(String methodName) {
// 实际需通过JoinPoint获取Mapper类名再转换为表名如StrategyTemplateMapper→strategy_template
return "strategy"; // 简化示例
}
// 从方法参数提取数据示例若参数是实体类转成Map
private Map<String, Object> extractDataFromParams(Object[] args) {
// 实际需反射获取实体类的字段和值如id、name等
@ -240,4 +241,5 @@ public class StrategySyncAspect {
return objectMapper.writeValueAsString(insertEntity);
}
}