diff --git a/agri-admin/src/main/resources/application.yml b/agri-admin/src/main/resources/application.yml index dc7946e..3c696e3 100644 --- a/agri-admin/src/main/resources/application.yml +++ b/agri-admin/src/main/resources/application.yml @@ -43,7 +43,7 @@ server: # 日志配置 logging: level: - com.agri: debug + com.agri: info org.springframework: warn # 用户配置 diff --git a/agri-common/src/main/java/com/agri/common/utils/SecurityUtils.java b/agri-common/src/main/java/com/agri/common/utils/SecurityUtils.java index ab8a17f..d439ccb 100644 --- a/agri-common/src/main/java/com/agri/common/utils/SecurityUtils.java +++ b/agri-common/src/main/java/com/agri/common/utils/SecurityUtils.java @@ -5,6 +5,8 @@ import com.agri.common.constant.HttpStatus; import com.agri.common.core.domain.entity.SysRole; import com.agri.common.core.domain.model.LoginUser; import com.agri.common.exception.ServiceException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; @@ -22,6 +24,8 @@ import java.util.stream.Collectors; public class SecurityUtils { + private static final Logger log = LoggerFactory.getLogger(SecurityUtils.class); + /** * 用户ID **/ @@ -72,14 +76,16 @@ public class SecurityUtils **/ public static LoginUser getLoginUser() { + LoginUser loginUser = null; try { - return (LoginUser) getAuthentication().getPrincipal(); + loginUser = (LoginUser) getAuthentication().getPrincipal(); } catch (Exception e) { - throw new ServiceException("获取用户信息异常", HttpStatus.UNAUTHORIZED); + log.error("获取用户信息异常: {}", HttpStatus.UNAUTHORIZED); } + return loginUser; } /** diff --git a/agri-framework/src/main/java/com/agri/framework/config/MybatisPlusHandler.java b/agri-framework/src/main/java/com/agri/framework/config/MybatisPlusHandler.java index 895c2e5..e66c46b 100644 --- a/agri-framework/src/main/java/com/agri/framework/config/MybatisPlusHandler.java +++ b/agri-framework/src/main/java/com/agri/framework/config/MybatisPlusHandler.java @@ -31,7 +31,7 @@ public class MybatisPlusHandler implements MetaObjectHandler { // 填充创建时间(字段名:createTime,值:当前时间) this.strictInsertFill(metaObject, "createTime", Date.class, new Date()); // 示例:填充创建人(假设从上下文获取当前用户ID) - this.strictInsertFill(metaObject, "createBy", String.class, getLoginUser().getUsername()); + this.strictInsertFill(metaObject, "createBy", String.class, getLoginUser()!=null?getLoginUser().getUsername():""); } // 更新操作时自动填充 @@ -40,6 +40,6 @@ public class MybatisPlusHandler implements MetaObjectHandler { // 填充更新时间(字段名:updateTime,值:当前时间) this.strictUpdateFill(metaObject, "updateTime", Date.class, new Date()); // 示例:填充更新人 - this.strictUpdateFill(metaObject, "updateBy", String.class, getLoginUser().getUsername()); + this.strictUpdateFill(metaObject, "updateBy", String.class, getLoginUser()!=null?getLoginUser().getUsername():""); } } \ No newline at end of file diff --git a/agri-framework/src/main/java/com/agri/framework/interceptor/DeviceStatusHandler.java b/agri-framework/src/main/java/com/agri/framework/interceptor/DeviceStatusHandler.java index d3749cd..37bd235 100644 --- a/agri-framework/src/main/java/com/agri/framework/interceptor/DeviceStatusHandler.java +++ b/agri-framework/src/main/java/com/agri/framework/interceptor/DeviceStatusHandler.java @@ -190,6 +190,7 @@ public class DeviceStatusHandler { .set(SysDevOperLog::getAckReceived,1) .set(SysDevOperLog::getIsLockSuc,1) .set(SysDevOperLog::getAckSuc, 1) + .set(SysDevOperLog::getUpdateBy,"自动关") .set(SysDevOperLog::getIsTask,autoOffSeconds > 0?1:0) .set(ObjectUtils.isEmpty(autoOffSeconds), SysDevOperLog::getNoTaskReason,"当前运行时间:【"+autoOffSeconds+"】") .set(SysDevOperLog::getAck, payload) @@ -289,7 +290,7 @@ public class DeviceStatusHandler { } } catch (MqttException e) { WxUtil.pushText( - "【消息转发失败】\n deviceId: "+deviceId+"\n payload: "+payload+"\n msg: "+e.getMessage()+"\n cause: "+e.getCause()); + "【消息转发失败】\n deviceId: "+deviceId+"\n payload: "+payload+"\n cause: "+e); log.error("【消息转发失败】deviceId={}, msg={}", deviceId, e.getMessage(), e); } } diff --git a/agri-framework/src/main/java/com/agri/framework/interceptor/FrontendControlHandler.java b/agri-framework/src/main/java/com/agri/framework/interceptor/FrontendControlHandler.java index 972df3b..75a3fd6 100644 --- a/agri-framework/src/main/java/com/agri/framework/interceptor/FrontendControlHandler.java +++ b/agri-framework/src/main/java/com/agri/framework/interceptor/FrontendControlHandler.java @@ -9,6 +9,7 @@ import com.agri.system.service.ISysAgriInfoService; import com.agri.system.service.ISysAgriLimitService; import com.agri.system.service.ISysDevOperLogService; import com.alibaba.fastjson2.JSON; +import com.alibaba.fastjson2.JSONObject; import com.alibaba.fastjson2.TypeReference; import org.apache.commons.lang3.ObjectUtils; import org.eclipse.paho.client.mqttv3.MqttException; @@ -67,7 +68,7 @@ public class FrontendControlHandler { private ISysDevOperLogService sysDevOperLogService; - @Value("${dtu-ctl-lock-ttl}") + @Value("${spring.mqtt.dtu-ctl-lock-ttl}") private int dtuCtlLockTTL; private static final Map> LIMIT_MAP = new HashMap<>(); static { @@ -94,7 +95,20 @@ public class FrontendControlHandler { log.error("【指令处理】clientId或deviceId为空,topic={}", topic); return; } - + // 4. 转发指令到设备 + String deviceTopic = "dtu/" + deviceId + "/down"; + JSONObject payloadObj; + try { + payloadObj = JSON.parseObject(payload); + } catch (Exception e) { + log.error("【设备处理】JSON解析失败,payload={}", payload, e); + return; + } + if (payloadObj.containsKey("read")) { + mqttMessageSender.publish(deviceTopic, payload); + log.info("【主动读取】设备{}主动读取,payload={}",deviceId, payload); + return; + } // 解析功能码({"功能码":状态码}格式) Map funcCodeMap = null; try { @@ -139,11 +153,9 @@ public class FrontendControlHandler { log.info("【指令处理】前端{}于{}控制设备{}的{}功能,指令:{}", clientId, LocalDateTime.now(), deviceId, funcType, payload); - // 4. 转发指令到设备 - String deviceTopic = "dtu/" + deviceId + "/down"; + //todo mqttMessageSender.publish(deviceTopic, payload); - // testAutoOffTask(deviceId,funcCodeMap); SysAgriInfo agriInfo = sysAgriInfoService.lambdaQuery() .eq(SysAgriInfo::getImei, deviceId) @@ -159,7 +171,11 @@ public class FrontendControlHandler { logDto.setLockAcquired(1); logDto.setLockHolder(clientId); logDto.setExecResult(1); - sysDevOperLogService.save(logDto); + logDto.setCreateBy("手动控制"); + boolean save = sysDevOperLogService.save(logDto); +// if (save) { +// testAutoOffTask(deviceId,funcCodeMap); +// } log.info("【指令转发】前端{} → 设备{}的{}功能", clientId, deviceId, funcType); } @@ -169,7 +185,10 @@ public class FrontendControlHandler { Integer funcValue = funcCodeMap.get(funcType); // 释放对应功能的分布式锁 String lockKey = "lock:" + deviceId + ":" + funcType; - stringRedisTemplate.delete(lockKey); + Boolean delete = stringRedisTemplate.delete(lockKey); + if (delete) { + log.info("【设备控制锁删除成功!】"); + } // 回执成功且值=1时启动自动关闭任务(保留原有逻辑) if (StringUtils.hasText(funcType) && funcValue != null && funcValue == 1) { @@ -184,9 +203,27 @@ public class FrontendControlHandler { if (autoOffSeconds > 0) { mqttAutoOffManager.scheduleAutoOff(deviceId, funcType, autoOffSeconds); log.debug("【自动关任务】标记需要执行,deviceId={}, funcType={}, delay={}s", deviceId, funcType, autoOffSeconds); + } else { log.debug("【自动关任务】标记不符合执行运行时间未配置,deviceId={}, funcType={}, delay={}s", deviceId, funcType, autoOffSeconds); } + + sysDevOperLogService.lambdaUpdate() + .eq(SysDevOperLog::getImei, deviceId) + .eq(SysDevOperLog::getFuncCode, funcType) + .eq(SysDevOperLog::getOpType, funcValue) + .eq(SysDevOperLog::getLockAcquired,1) + .orderByDesc(SysDevOperLog::getCreateTime) + .last("LIMIT 1") + .set(SysDevOperLog::getAckReceived,1) + .set(SysDevOperLog::getIsLockSuc,1) + .set(SysDevOperLog::getAckSuc, 1) + .set(SysDevOperLog::getIsTask, 1) + .set(SysDevOperLog::getUpdateBy,"自动关") + .set(autoOffSeconds <= 0, SysDevOperLog::getNoTaskReason,"当前运行时间:【"+autoOffSeconds+"】") + .set(SysDevOperLog::getUpdateBy, "测试") + .set(SysDevOperLog::getExecResult, 1) + .update(); } if (StringUtils.hasText(funcType) && funcValue != null && funcValue == 0) { diff --git a/agri-framework/src/main/java/com/agri/framework/manager/MqttAutoOffManager.java b/agri-framework/src/main/java/com/agri/framework/manager/MqttAutoOffManager.java index e7c0dd8..a62d016 100644 --- a/agri-framework/src/main/java/com/agri/framework/manager/MqttAutoOffManager.java +++ b/agri-framework/src/main/java/com/agri/framework/manager/MqttAutoOffManager.java @@ -70,7 +70,7 @@ public class MqttAutoOffManager { @Value("${spring.mqtt.auto-off-thread-pool-size:5}") private int autoOffThreadPoolSize; - @Value("${dtu-ctl-lock-ttl}") + @Value("${spring.mqtt.dtu-ctl-lock-ttl}") private int dtuCtlLockTTL; @Autowired @@ -191,7 +191,7 @@ public class MqttAutoOffManager { try { runAutoOff(deviceId, funcType); } catch (Exception e) { - WxUtil.pushText("【自动关任务】提交任务失败! \n deviceId: "+deviceId+"\n funcType: "+funcType+"\n msg: "+e.getMessage()+"\n cause: "+e.getCause()); + WxUtil.pushText("【自动关任务】提交任务失败! \n deviceId: "+deviceId+"\n funcType: "+funcType+"\n cause: "+e); log.error("【自动关任务】执行失败,deviceId={}, funcType={}", deviceId, funcType, e); } finally { // 任务执行完成后移除映射 @@ -226,7 +226,7 @@ public class MqttAutoOffManager { latestObj = JSON.parseObject(latest); } catch (Exception e) { skipReason = "【自动关任务】执行报错-解析异常"; - WxUtil.pushText("自动关任务执行报错-解析异常:\n deviceId: " + deviceId + "\n funcType:" + funcType+"\n 异常:"+e.getMessage()+"\n Cause: "+e.getCause()); + WxUtil.pushText("自动关任务执行报错-解析异常:\n deviceId: " + deviceId + "\n funcType:" + funcType+"\n Cause: "+e); log.warn("【自动关任务】最新状态JSON解析失败,跳过:deviceId={}, funcType={}", deviceId, funcType); return; } @@ -244,7 +244,9 @@ public class MqttAutoOffManager { } catch (Exception ignore) { skipReason = "【自动关任务】最新状态功能码获取失败"; } - + if (current == null || current!=1) { + skipReason = "【自动关任务】检测未运行或状态未知"; + } sysDevOperLogService.lambdaUpdate() .eq(SysDevOperLog::getImei, deviceId) .eq(SysDevOperLog::getFuncCode, funcType) @@ -256,6 +258,7 @@ public class MqttAutoOffManager { .last("LIMIT 1") .set(SysDevOperLog::getExecResult,1) .set(SysDevOperLog::getLatestState, latest) + .set(SysDevOperLog::getUpdateBy,"自动关") .set(!skipReason.isEmpty(), SysDevOperLog::getSkipReason, skipReason) .update(); @@ -289,6 +292,7 @@ public class MqttAutoOffManager { logDto.setLockHolder("autoOff"); logDto.setExecResult(1); logDto.setLatestState(latest); + logDto.setCreateBy("自动关"); logDto.setTaskStatus(getFutureStatus().toString()); sysDevOperLogService.save(logDto); log.info("【自动关任务】检测仍在运行,已下发关闭:deviceId={}, funcType={}, payload={}", deviceId, funcType, down.toJSONString()); diff --git a/agri-framework/src/main/java/com/agri/framework/manager/MqttClientManager.java b/agri-framework/src/main/java/com/agri/framework/manager/MqttClientManager.java index 4abc56f..502492f 100644 --- a/agri-framework/src/main/java/com/agri/framework/manager/MqttClientManager.java +++ b/agri-framework/src/main/java/com/agri/framework/manager/MqttClientManager.java @@ -142,7 +142,7 @@ public class MqttClientManager implements SmartLifecycle { log.error("【MQTT连接异常】连接断开,clientId:{},原因:{}", safeClientId(), (cause == null ? "unknown" : cause.getMessage()), cause); - WxUtil.pushText("【MQTT连接异常】连接断开:\n clientId:"+safeClientId()+"\n 原因:"+(cause == null ? "unknown" : cause.getMessage())+"\n Cause: "+cause.getCause()); + WxUtil.pushText("【MQTT连接异常】连接断开:\n clientId:"+safeClientId()+"\n Cause: "+cause); // 【方案A】不再触发自写重连;Paho自动重连会接管重连过程 // 这里只记录日志即可 if (isRunning.get()) { diff --git a/agri-framework/src/main/java/com/agri/framework/web/dispatcher/MqttMessageDispatcher.java b/agri-framework/src/main/java/com/agri/framework/web/dispatcher/MqttMessageDispatcher.java index b2f1665..734e164 100644 --- a/agri-framework/src/main/java/com/agri/framework/web/dispatcher/MqttMessageDispatcher.java +++ b/agri-framework/src/main/java/com/agri/framework/web/dispatcher/MqttMessageDispatcher.java @@ -1,5 +1,6 @@ package com.agri.framework.web.dispatcher; +import com.agri.common.utils.wechat.WxUtil; import com.agri.framework.interceptor.DeviceStatusHandler; import com.agri.framework.interceptor.FrontendControlHandler; import com.agri.framework.interceptor.FrontendOnlineHandler; @@ -64,6 +65,7 @@ public class MqttMessageDispatcher { } // todo 是否加回复主题?? } catch (Exception e) { + WxUtil.pushText("【MQTT消息处理异常】\n topic: "+ topic+"\n cause: "+e); log.error("【MQTT消息处理异常】topic={}", topic, e); } }