【验收】8 本地设备切换记录日志

This commit is contained in:
2025-11-16 21:00:29 +08:00
parent 38ade0c2ed
commit 25e03ab028
7 changed files with 643 additions and 5 deletions

View File

@ -0,0 +1,97 @@
package com.xzzn.framework.aspectj;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.xzzn.common.utils.StringUtils;
import com.xzzn.ems.domain.EmsDeviceChangeLog;
import com.xzzn.ems.domain.MqttSyncLog;
import com.xzzn.ems.mapper.EmsMqttTopicConfigMapper;
import com.xzzn.ems.mapper.MqttSyncLogMapper;
import com.xzzn.framework.web.service.MqttPublisher;
import org.apache.juli.logging.Log;
import org.apache.juli.logging.LogFactory;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.Date;
import java.util.UUID;
/**
* 设备运行状态变更日志同步
* 本地 - 云端
*/
@Aspect
@Component
public class DeviceChangeLogAspect {
private static final Log logger = LogFactory.getLog(DeviceChangeLogAspect.class);
@Autowired
private MqttPublisher mqttPublisher;
private static final ObjectMapper objectMapper = new ObjectMapper();
private static final String MQTT_TOPIC = "DEVICE_CHANGE_LOG_UP";
private static final String TABLE_NAME = "ems_device_change_log";
@Autowired
private MqttSyncLogMapper mqttSyncLogMapper;
@Autowired
private EmsMqttTopicConfigMapper emsMqttTopicConfigMapper;
// 定义切点拦截策略相关表的Mapper方法
@Pointcut("(execution(* com.xzzn.ems.mapper.EmsDeviceChangeLogMapper.insertEmsDeviceChangeLog(..)) && args(insertEntity)) ")
public void insertPointCut(EmsDeviceChangeLog insertEntity) {
logger.info("【新增设备运行状态变更日志】DeviceChangeLogAspect 实例化");
}
// 方法执行成功后发布同步消息
@AfterReturning(pointcut = "insertPointCut(insertEntity)", returning = "result")
public void afterInsert(JoinPoint joinPoint, EmsDeviceChangeLog insertEntity, Integer result) {
logger.info("【新增设备运行状态变更日志下发数据切面进入成功】");
if (result == 0 || insertEntity == null) {
return;
}
// 校验是否配置监听topic-监听则不发布
String topic = emsMqttTopicConfigMapper.checkTopicIsExist(MQTT_TOPIC);
if (!StringUtils.isEmpty(topic)) {
return;
}
// 解析方法名获取操作类型INSERT/UPDATE/DELETE和表名
String operateType = "INSERT";
String siteId = insertEntity.getSiteId();
// 构建日志同步消息
MqttSyncLog message = createMessageObject(operateType,siteId);
try {
// 数据转换
String content = objectMapper.writeValueAsString(insertEntity);
message.setContent(content);
// mqtt同步到云端
mqttPublisher.publish(MQTT_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(MQTT_TOPIC);
message.setStatus("SUCCESS");
message.setSyncObject(siteId);
message.setTarget("CLOUD");
return message;
}
}

View File

@ -1,9 +1,12 @@
package com.xzzn.quartz.task;
import com.xzzn.common.enums.DeviceRunningStatus;
import com.xzzn.ems.domain.EmsDeviceChangeLog;
import com.xzzn.ems.domain.EmsDevicesSetting;
import com.xzzn.ems.mapper.EmsDeviceChangeLogMapper;
import com.xzzn.ems.mapper.EmsDevicesSettingMapper;
import com.xzzn.ems.mapper.EmsMqttMessageMapper;
import com.xzzn.ems.service.impl.EmsDeviceSettingServiceImpl;
import com.xzzn.framework.manager.ModbusConnectionManager;
import com.xzzn.framework.manager.ModbusConnectionWrapper;
import com.xzzn.framework.manager.MqttLifecycleManager;
@ -14,7 +17,9 @@ import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.Date;
import java.util.List;
import java.util.UUID;
/**
* 轮询设备-通过modbus协议读取数据
@ -33,6 +38,10 @@ public class ModbusPoller {
private EmsDevicesSettingMapper deviceRepo;
@Autowired
private EmsMqttMessageMapper emsMqttMessageMapper;
@Autowired
private EmsDeviceSettingServiceImpl emsDeviceSettingServiceImpl;
@Autowired
private EmsDeviceChangeLogMapper emsDeviceChangeLogMapper;
@Autowired
public ModbusPoller(MqttLifecycleManager mqttLifecycleManager) {
@ -41,8 +50,9 @@ public class ModbusPoller {
public void pollAllDevices() {
logger.info("开始执行Modbus设备轮询...");
List<EmsDevicesSetting> activeDevices = deviceRepo.selectEmsDevicesSettingList(null);
EmsDevicesSetting selectEntity = new EmsDevicesSetting();
selectEntity.setRunningStatus(DeviceRunningStatus.RUNNING.getCode());
List<EmsDevicesSetting> activeDevices = deviceRepo.selectEmsDevicesSettingList(selectEntity);
EmsDevicesSetting device = activeDevices.get(0);
try {
@ -91,16 +101,39 @@ public class ModbusPoller {
wrapper.close();
connectionManager.removeConnection(Integer.parseInt(device.getDeviceId()));
}
throw new RuntimeException("轮询设备失败", e);
// 设备轮询不到修改运行状态
String beforeStatus = device.getRunningStatus();
device.setRunningStatus(DeviceRunningStatus.SHUTDOWN.getCode());
emsDeviceSettingServiceImpl.updateDevice(device);
// 轮询设备,设备状态变更日志
EmsDeviceChangeLog log = createLogEntity(beforeStatus,device);
emsDeviceChangeLogMapper.insertEmsDeviceChangeLog(log);
throw new RuntimeException("轮询设备失败", e);
}
}
// 处理获取到的数据
private void processData(EmsDevicesSetting device, int[] data) throws MqttException {
String beforeStatus = device.getRunningStatus();
Boolean error = true;
if (data == null || data.length == 0) {
logger.warn("设备{}返回空数据", device.getId());
// 设备读取不到-设置设备故障
device.setRunningStatus(DeviceRunningStatus.FAULT.getCode());
error = false;
} else {
// 恢复设备状态 - 运行
device.setRunningStatus(DeviceRunningStatus.RUNNING.getCode());
}
emsDeviceSettingServiceImpl.updateDevice(device);
// 轮询设备,设备状态变更日志
EmsDeviceChangeLog log = createLogEntity(beforeStatus,device);
emsDeviceChangeLogMapper.insertEmsDeviceChangeLog(log);
// 错误数据-不处理直接返回
if (!error) {
return;
}
@ -116,8 +149,6 @@ public class ModbusPoller {
/*
String siteId = device.getSiteId();
if (siteId.startsWith("021_DDS")) {
ems_devices_setting
dDSDataProcessService.handleDdsData(message);
} else if (siteId.startsWith("021_FXX")) {
fXXDataProcessService.handleFxData(message);
@ -132,4 +163,17 @@ public class ModbusPoller {
// 将设备数据下发到mqtt服务器上
mqttLifecycleManager.publish(topic, dataJson, 0);*/
}
private EmsDeviceChangeLog createLogEntity(String beforeStatus, EmsDevicesSetting device) {
EmsDeviceChangeLog log = new EmsDeviceChangeLog();
log.setLogId(UUID.randomUUID().toString());
log.setLogTime(new Date());
log.setSiteId(device.getSiteId());
log.setDeviceId(device.getDeviceId());
log.setBeforeStatus(beforeStatus);
log.setAfterStatus(device.getRunningStatus());
log.setCreateBy("sys");
log.setCreateTime(new Date());
return log;
}
}

View File

@ -0,0 +1,134 @@
package com.xzzn.ems.domain;
import java.util.Date;
import com.xzzn.common.core.domain.BaseEntity;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import com.xzzn.common.annotation.Excel;
/**
* 设备状态变更记录对象 ems_device_change_log
*
* @author xzzn
* @date 2025-11-15
*/
public class EmsDeviceChangeLog extends BaseEntity
{
private static final long serialVersionUID = 1L;
/** $column.columnComment */
private Long id;
/** 日志IDUUID */
@Excel(name = "日志ID", readConverterExp = "U=UID")
private String logId;
/** 日志时间(精确到秒) */
@Excel(name = "日志时间", readConverterExp = "精=确到秒")
private Date logTime;
/** 站点id */
@Excel(name = "站点id")
private String siteId;
/** 设备id */
@Excel(name = "设备id")
private String deviceId;
/** 变更前状态0-离线、1-待机、2-运行、3-故障、4-停机 */
@Excel(name = "变更前状态0-离线、1-待机、2-运行、3-故障、4-停机")
private String beforeStatus;
/** 变更后状态0-离线、1-待机、2-运行、3-故障、4-停机 */
@Excel(name = "变更后状态0-离线、1-待机、2-运行、3-故障、4-停机")
private String afterStatus;
public void setId(Long id)
{
this.id = id;
}
public Long getId()
{
return id;
}
public void setLogId(String logId)
{
this.logId = logId;
}
public String getLogId()
{
return logId;
}
public void setLogTime(Date logTime)
{
this.logTime = logTime;
}
public Date getLogTime()
{
return logTime;
}
public void setSiteId(String siteId)
{
this.siteId = siteId;
}
public String getSiteId()
{
return siteId;
}
public void setDeviceId(String deviceId)
{
this.deviceId = deviceId;
}
public String getDeviceId()
{
return deviceId;
}
public void setBeforeStatus(String beforeStatus)
{
this.beforeStatus = beforeStatus;
}
public String getBeforeStatus()
{
return beforeStatus;
}
public void setAfterStatus(String afterStatus)
{
this.afterStatus = afterStatus;
}
public String getAfterStatus()
{
return afterStatus;
}
@Override
public String toString() {
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
.append("id", getId())
.append("logId", getLogId())
.append("logTime", getLogTime())
.append("siteId", getSiteId())
.append("deviceId", getDeviceId())
.append("beforeStatus", getBeforeStatus())
.append("afterStatus", getAfterStatus())
.append("createBy", getCreateBy())
.append("createTime", getCreateTime())
.append("updateBy", getUpdateBy())
.append("updateTime", getUpdateTime())
.append("remark", getRemark())
.toString();
}
}

View File

@ -0,0 +1,65 @@
package com.xzzn.ems.mapper;
import java.util.List;
import com.xzzn.ems.domain.EmsDeviceChangeLog;
import com.xzzn.ems.domain.EmsFaultIssueLog;
/**
* 设备状态变更记录Mapper接口
*
* @author xzzn
* @date 2025-11-15
*/
public interface EmsDeviceChangeLogMapper
{
/**
* 查询设备状态变更记录
*
* @param id 设备状态变更记录主键
* @return 设备状态变更记录
*/
public EmsDeviceChangeLog selectEmsDeviceChangeLogById(Long id);
/**
* 查询设备状态变更记录列表
*
* @param emsDeviceChangeLog 设备状态变更记录
* @return 设备状态变更记录集合
*/
public List<EmsDeviceChangeLog> selectEmsDeviceChangeLogList(EmsDeviceChangeLog emsDeviceChangeLog);
/**
* 新增设备状态变更记录
*
* @param emsDeviceChangeLog 设备状态变更记录
* @return 结果
*/
public int insertEmsDeviceChangeLog(EmsDeviceChangeLog emsDeviceChangeLog);
/**
* 修改设备状态变更记录
*
* @param emsDeviceChangeLog 设备状态变更记录
* @return 结果
*/
public int updateEmsDeviceChangeLog(EmsDeviceChangeLog emsDeviceChangeLog);
/**
* 删除设备状态变更记录
*
* @param id 设备状态变更记录主键
* @return 结果
*/
public int deleteEmsDeviceChangeLogById(Long id);
/**
* 批量删除设备状态变更记录
*
* @param ids 需要删除的数据主键集合
* @return 结果
*/
public int deleteEmsDeviceChangeLogByIds(Long[] ids);
// 根据logId获取日志
public EmsDeviceChangeLog selectDeviceChangeLogByLogId(String logId);
}

View File

@ -0,0 +1,64 @@
package com.xzzn.ems.service;
import java.util.List;
import com.xzzn.ems.domain.EmsDeviceChangeLog;
/**
* 设备状态变更记录Service接口
*
* @author xzzn
* @date 2025-11-15
*/
public interface IEmsDeviceChangeLogService
{
/**
* 查询设备状态变更记录
*
* @param id 设备状态变更记录主键
* @return 设备状态变更记录
*/
public EmsDeviceChangeLog selectEmsDeviceChangeLogById(Long id);
/**
* 查询设备状态变更记录列表
*
* @param emsDeviceChangeLog 设备状态变更记录
* @return 设备状态变更记录集合
*/
public List<EmsDeviceChangeLog> selectEmsDeviceChangeLogList(EmsDeviceChangeLog emsDeviceChangeLog);
/**
* 新增设备状态变更记录
*
* @param emsDeviceChangeLog 设备状态变更记录
* @return 结果
*/
public int insertEmsDeviceChangeLog(EmsDeviceChangeLog emsDeviceChangeLog);
/**
* 修改设备状态变更记录
*
* @param emsDeviceChangeLog 设备状态变更记录
* @return 结果
*/
public int updateEmsDeviceChangeLog(EmsDeviceChangeLog emsDeviceChangeLog);
/**
* 批量删除设备状态变更记录
*
* @param ids 需要删除的设备状态变更记录主键集合
* @return 结果
*/
public int deleteEmsDeviceChangeLogByIds(Long[] ids);
/**
* 删除设备状态变更记录信息
*
* @param id 设备状态变更记录主键
* @return 结果
*/
public int deleteEmsDeviceChangeLogById(Long id);
// 处理本地端同步设备状态变更数据
public void dealSyncData(String content, String operateType);
}

View File

@ -0,0 +1,128 @@
package com.xzzn.ems.service.impl;
import java.util.List;
import com.alibaba.fastjson2.JSON;
import com.xzzn.common.utils.DateUtils;
import com.xzzn.common.utils.StringUtils;
import com.xzzn.ems.domain.EmsFaultIssueLog;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.xzzn.ems.mapper.EmsDeviceChangeLogMapper;
import com.xzzn.ems.domain.EmsDeviceChangeLog;
import com.xzzn.ems.service.IEmsDeviceChangeLogService;
/**
* 设备状态变更记录Service业务层处理
*
* @author xzzn
* @date 2025-11-15
*/
@Service
public class EmsDeviceChangeLogServiceImpl implements IEmsDeviceChangeLogService
{
@Autowired
private EmsDeviceChangeLogMapper emsDeviceChangeLogMapper;
/**
* 查询设备状态变更记录
*
* @param id 设备状态变更记录主键
* @return 设备状态变更记录
*/
@Override
public EmsDeviceChangeLog selectEmsDeviceChangeLogById(Long id)
{
return emsDeviceChangeLogMapper.selectEmsDeviceChangeLogById(id);
}
/**
* 查询设备状态变更记录列表
*
* @param emsDeviceChangeLog 设备状态变更记录
* @return 设备状态变更记录
*/
@Override
public List<EmsDeviceChangeLog> selectEmsDeviceChangeLogList(EmsDeviceChangeLog emsDeviceChangeLog)
{
return emsDeviceChangeLogMapper.selectEmsDeviceChangeLogList(emsDeviceChangeLog);
}
/**
* 新增设备状态变更记录
*
* @param emsDeviceChangeLog 设备状态变更记录
* @return 结果
*/
@Override
public int insertEmsDeviceChangeLog(EmsDeviceChangeLog emsDeviceChangeLog)
{
emsDeviceChangeLog.setCreateTime(DateUtils.getNowDate());
return emsDeviceChangeLogMapper.insertEmsDeviceChangeLog(emsDeviceChangeLog);
}
/**
* 修改设备状态变更记录
*
* @param emsDeviceChangeLog 设备状态变更记录
* @return 结果
*/
@Override
public int updateEmsDeviceChangeLog(EmsDeviceChangeLog emsDeviceChangeLog)
{
emsDeviceChangeLog.setUpdateTime(DateUtils.getNowDate());
return emsDeviceChangeLogMapper.updateEmsDeviceChangeLog(emsDeviceChangeLog);
}
/**
* 批量删除设备状态变更记录
*
* @param ids 需要删除的设备状态变更记录主键
* @return 结果
*/
@Override
public int deleteEmsDeviceChangeLogByIds(Long[] ids)
{
return emsDeviceChangeLogMapper.deleteEmsDeviceChangeLogByIds(ids);
}
/**
* 删除设备状态变更记录信息
*
* @param id 设备状态变更记录主键
* @return 结果
*/
@Override
public int deleteEmsDeviceChangeLogById(Long id)
{
return emsDeviceChangeLogMapper.deleteEmsDeviceChangeLogById(id);
}
@Override
public void dealSyncData(String content, String operateType) {
if (StringUtils.isEmpty(content)) {
return;
}
EmsDeviceChangeLog changeLog = JSON.parseObject(content, EmsDeviceChangeLog.class);
String logId = changeLog.getLogId();
if (checkLogIsExist(logId)) {
return;
}
switch(operateType) {
case "INSERT":
insertEmsDeviceChangeLog(changeLog);
break;
default:
break;
}
}
private boolean checkLogIsExist(String logId) {
EmsDeviceChangeLog changeLog = emsDeviceChangeLogMapper.selectDeviceChangeLogByLogId(logId);
if (changeLog != null) {
return true;
}
return false;
}
}

View File

@ -0,0 +1,106 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.xzzn.ems.mapper.EmsDeviceChangeLogMapper">
<resultMap type="EmsDeviceChangeLog" id="EmsDeviceChangeLogResult">
<result property="id" column="id" />
<result property="logId" column="log_id" />
<result property="logTime" column="log_time" />
<result property="siteId" column="siteId" />
<result property="deviceId" column="deviceId" />
<result property="beforeStatus" column="before_status" />
<result property="afterStatus" column="after_status" />
<result property="createBy" column="create_by" />
<result property="createTime" column="create_time" />
<result property="updateBy" column="update_by" />
<result property="updateTime" column="update_time" />
<result property="remark" column="remark" />
</resultMap>
<sql id="selectEmsDeviceChangeLogVo">
select id, log_id, log_time, siteId, deviceId, before_status, after_status, create_by, create_time, update_by, update_time, remark from ems_device_change_log
</sql>
<select id="selectEmsDeviceChangeLogList" parameterType="EmsDeviceChangeLog" resultMap="EmsDeviceChangeLogResult">
<include refid="selectEmsDeviceChangeLogVo"/>
<where>
<if test="logId != null and logId != ''"> and log_id = #{logId}</if>
<if test="logTime != null "> and log_time = #{logTime}</if>
<if test="siteId != null and siteId != ''"> and siteId = #{siteId}</if>
<if test="deviceId != null and deviceId != ''"> and deviceId = #{deviceId}</if>
<if test="beforeStatus != null and beforeStatus != ''"> and before_status = #{beforeStatus}</if>
<if test="afterStatus != null and afterStatus != ''"> and after_status = #{afterStatus}</if>
</where>
</select>
<select id="selectEmsDeviceChangeLogById" parameterType="Long" resultMap="EmsDeviceChangeLogResult">
<include refid="selectEmsDeviceChangeLogVo"/>
where id = #{id}
</select>
<insert id="insertEmsDeviceChangeLog" parameterType="EmsDeviceChangeLog" useGeneratedKeys="true" keyProperty="id">
insert into ems_device_change_log
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="logId != null and logId != ''">log_id,</if>
<if test="logTime != null">log_time,</if>
<if test="siteId != null">siteId,</if>
<if test="deviceId != null">deviceId,</if>
<if test="beforeStatus != null">before_status,</if>
<if test="afterStatus != null">after_status,</if>
<if test="createBy != null">create_by,</if>
<if test="createTime != null">create_time,</if>
<if test="updateBy != null">update_by,</if>
<if test="updateTime != null">update_time,</if>
<if test="remark != null">remark,</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="logId != null and logId != ''">#{logId},</if>
<if test="logTime != null">#{logTime},</if>
<if test="siteId != null">#{siteId},</if>
<if test="deviceId != null">#{deviceId},</if>
<if test="beforeStatus != null">#{beforeStatus},</if>
<if test="afterStatus != null">#{afterStatus},</if>
<if test="createBy != null">#{createBy},</if>
<if test="createTime != null">#{createTime},</if>
<if test="updateBy != null">#{updateBy},</if>
<if test="updateTime != null">#{updateTime},</if>
<if test="remark != null">#{remark},</if>
</trim>
</insert>
<update id="updateEmsDeviceChangeLog" parameterType="EmsDeviceChangeLog">
update ems_device_change_log
<trim prefix="SET" suffixOverrides=",">
<if test="logId != null and logId != ''">log_id = #{logId},</if>
<if test="logTime != null">log_time = #{logTime},</if>
<if test="siteId != null">siteId = #{siteId},</if>
<if test="deviceId != null">deviceId = #{deviceId},</if>
<if test="beforeStatus != null">before_status = #{beforeStatus},</if>
<if test="afterStatus != null">after_status = #{afterStatus},</if>
<if test="createBy != null">create_by = #{createBy},</if>
<if test="createTime != null">create_time = #{createTime},</if>
<if test="updateBy != null">update_by = #{updateBy},</if>
<if test="updateTime != null">update_time = #{updateTime},</if>
<if test="remark != null">remark = #{remark},</if>
</trim>
where id = #{id}
</update>
<delete id="deleteEmsDeviceChangeLogById" parameterType="Long">
delete from ems_device_change_log where id = #{id}
</delete>
<delete id="deleteEmsDeviceChangeLogByIds" parameterType="String">
delete from ems_device_change_log where id in
<foreach item="id" collection="array" open="(" separator="," close=")">
#{id}
</foreach>
</delete>
<select id="selectDeviceChangeLogByLogId" parameterType="String" resultMap="EmsDeviceChangeLogResult">
<include refid="selectEmsDeviceChangeLogVo"/>
where log_id = #{logId}
</select>
</mapper>