在线状态优化

This commit is contained in:
磷叶 2025-01-04 13:43:34 +08:00
parent 6bcda98673
commit 2d4f601816
17 changed files with 338 additions and 81 deletions

View File

@ -65,4 +65,19 @@ public class CacheConstants
* 微信access_token
*/
public static final String WX_ACCESS_TOKEN = "wx_access_token";
/**
* 设备在线状态
*/
public static final String DEVICE_ONLINE_STATUS = "device_online_status:";
/**
* 设备离线计数
*/
public static final String DEVICE_OFFLINE_INCREMENT = "device_offline_increment:";
/**
* 待插入的命令日志
*/
public static final String INSERT_COMMAND_LOG = "insert_command_log";
}

View File

@ -1,18 +1,17 @@
package com.ruoyi.common.core.redis;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.BoundSetOperations;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.data.redis.core.script.RedisScript;
import org.springframework.stereotype.Component;
import java.util.*;
import java.util.concurrent.TimeUnit;
/**
* spring redis 工具类
*
@ -265,4 +264,76 @@ public class RedisCache
{
return redisTemplate.keys(pattern);
}
/**
* 累计缓存的值并设置过期时间每次累计时刷新过期时间
*
* @param key 缓存的键值
* @param timeout 过期时间
* @param timeUnit 时间单位
* @return 累计后的值
*/
public long incrementCacheValue(final String key, final long timeout, final TimeUnit timeUnit) {
// 使用 SET 命令的 NX EX 选项确保初始值设置和过期时间设置是原子性的
Boolean isNewKey = redisTemplate.opsForValue().setIfAbsent(key, 0, timeout, timeUnit);
if (isNewKey != null && isNewKey) {
// 如果 key 是新设置的初始值为 0
return 1L;
}
// 使用 INCR 命令累计值
long newValue = redisTemplate.opsForValue().increment(key);
// 刷新过期时间
redisTemplate.expire(key, timeout, timeUnit);
return newValue;
}
/**
* 向缓存列表的右侧尾部添加数据
*
* @param key 缓存的键值
* @param value 要添加的数据
* @return 添加后的列表长度
*/
public long rightPush(final String key, final Object value) {
return redisTemplate.opsForList().rightPush(key, value);
}
/**
* 向缓存列表的左侧头部添加数据
*
* @param key 缓存的键值
* @param value 要添加的数据
* @return 添加后的列表长度
*/
public long leftPush(final String key, final Object value) {
return redisTemplate.opsForList().leftPush(key, value);
}
/**
* 清空缓存列表的数据
*
* @param key 缓存的键值
* @return 是否成功清空
*/
public boolean clearCacheList(final String key) {
return redisTemplate.delete(key);
}
/**
* 获取并清空缓存列表的数据原子性操作
*
* @param key 缓存的键值
* @return 缓存键值对应的数据列表
*/
public <T> List<T> getAndClearCacheList(final String key) {
// 定义 Lua 脚本
String scriptText = "local list = redis.call('LRANGE', KEYS[1], 0, -1) " +
"redis.call('DEL', KEYS[1]) " +
"return list";
RedisScript<List<T>> redisScript = new DefaultRedisScript<>(scriptText, (Class<List<T>>) (Class<?>) List.class);
// 执行 Lua 脚本
return (List<T>) redisTemplate.<T>execute(redisScript, Collections.singletonList(key));
}
}

View File

@ -27,7 +27,8 @@ public enum RedisLockKey {
RECOVER_DEVICE_BALANCE("recover_device_balance", "恢复设备余额"),
ADD_USER_WX_OPEN_ID("add_user_wx_open_id", "微信注册用户"),
ADD_USER_MOBILE("add_user_mobile", "手机号注册用户"),
SUBMIT_RISK_INFO("submit_risk_info", "提交风控材料");
SUBMIT_RISK_INFO("submit_risk_info", "提交风控材料"),
DEVICE_ONLINE_COMMAND("device_online_command", "设备在线发送命令");
private final String key;

View File

@ -1,10 +1,14 @@
package com.ruoyi.common.utils.http;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.net.ssl.*;
import javax.servlet.http.HttpServletRequest;
import java.io.*;
import java.net.ConnectException;
import java.net.SocketTimeoutException;
import java.net.URL;
@ -14,19 +18,6 @@ import java.security.cert.X509Certificate;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import javax.servlet.http.HttpServletRequest;
import com.ruoyi.common.exception.ServiceException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.utils.StringUtils;
/**
* 通用http发送方法
@ -311,8 +302,8 @@ public class HttpUtils
StringBuilder result = new StringBuilder();
try
{
log.info("sendPost - {}", url);
log.info("发送命令 - {}", param);
// log.info("sendPost - {}", url);
// log.info("发送命令 - {}", param);
URL realUrl = new URL(url);
URLConnection conn = realUrl.openConnection();
conn.setRequestProperty("accept", "*/*");

View File

@ -57,6 +57,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
#end
#end
#end
${query.params.dataScope}
</sql>
<select id="select${ClassName}List" parameterType="${ClassName}Query" resultMap="${ClassName}Result">

View File

@ -137,8 +137,8 @@ public class IotDeviceDetail {
private final Integer status;
// 转换为设备在线状态
public static DeviceOnlineStatus toDeviceOnlineStatus(Integer iotStatus) {
return ONLINE.getStatus().equals(iotStatus) ? DeviceOnlineStatus.ONLINE : DeviceOnlineStatus.OFFLINE;
public static String toDeviceOnlineStatus(Integer iotStatus) {
return ONLINE.getStatus().equals(iotStatus) ? DeviceOnlineStatus.ONLINE.getStatus(): DeviceOnlineStatus.OFFLINE.getStatus();
}
}
}

View File

@ -1,6 +1,5 @@
package com.ruoyi.iot.domain.response;
import com.ruoyi.common.constant.HttpStatus;
import com.ruoyi.iot.enums.IotHttpStatus;
import lombok.Data;
@ -21,4 +20,14 @@ public class CommandResponse extends BaseResponse {
return Objects.equals(IotHttpStatus.SUCCESS.getCode(), this.getCode());
}
// 设备不在线
public boolean isNotOnline() {
return Objects.equals(IotHttpStatus.DEVICE_NOT_ONLINE.getCode(), this.getCode());
}
// 命令超时
public boolean isCmdTimeout() {
return Objects.equals(IotHttpStatus.TIME_OUT.getCode(), this.getCode());
}
}

View File

@ -6,11 +6,9 @@ import com.ruoyi.iot.domain.HistoryDeviceData;
import com.ruoyi.iot.domain.IotDeviceInfo;
import com.ruoyi.iot.domain.response.CommandResponse;
import com.ruoyi.iot.interfaces.IotDevice;
import com.ruoyi.ss.device.domain.enums.DeviceOnlineStatus;
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
/**
* @author wjh
@ -24,7 +22,7 @@ public interface IotService {
* @param deviceName OneNet设备名称即设备表的MAC号
* @param productId
*/
default DeviceOnlineStatus getOnlineStatus(String deviceName, String productId) {
default String getOnlineStatus(String deviceName, String productId) {
return getOnlineStatus(deviceName, productId, IotConstants.ONLINE_TYPE_GET);
}
@ -33,14 +31,14 @@ public interface IotService {
*
* @param deviceName OneNet设备名称即设备表的MAC号
* @param productId
* @param type 获取方式1-从OneNet直接获取2-发送命令获取
* @param type 获取方式1-从OneNet直接获取2-发送命令获取
*/
DeviceOnlineStatus getOnlineStatus(String deviceName, String productId, String type);
String getOnlineStatus(String deviceName, String productId, String type);
/**
* 获取设备在线状态
*/
DeviceOnlineStatus getOnlineStatus(IotDevice device);
String getOnlineStatus(IotDevice device);
/**
* 通电

View File

@ -2,9 +2,13 @@ package com.ruoyi.iot.service.impl;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.ruoyi.common.constant.CacheConstants;
import com.ruoyi.common.constant.HttpStatus;
import com.ruoyi.common.constant.IotConstants;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.core.redis.RedisLock;
import com.ruoyi.common.core.redis.enums.RedisLockKey;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.ServiceUtil;
@ -28,9 +32,7 @@ import org.springframework.stereotype.Service;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
@ -73,28 +75,77 @@ public class IotServiceImpl implements IotService {
@Autowired
private ICommandLogService commandLogService;
@Autowired
private RedisCache redisCache;
@Autowired
private RedisLock redisLock;
// 查询OneNet设备在线状态
@Override
public DeviceOnlineStatus getOnlineStatus(String deviceName, String productId, String type) {
public String getOnlineStatus(String deviceName, String productId, String type) {
if (StringUtils.isAnyBlank(deviceName, productId)) {
return DeviceOnlineStatus.OFFLINE;
return DeviceOnlineStatus.OFFLINE.getStatus();
}
if ( IotConstants.ONLINE_TYPE_COMMAND.equals(type)) {
CommandResponse res = uploadData(deviceName, productId, "获取在线状态");
return res != null && res.isSuccess() ? DeviceOnlineStatus.ONLINE : DeviceOnlineStatus.OFFLINE;
// 加锁防止第一次会有多个请求进入
boolean lock = redisLock.lock(RedisLockKey.DEVICE_ONLINE_COMMAND, deviceName);
try {
if (lock) {
// log.info("进入lock");
// 从缓存获取上次的在线状态若不存在则发命令防止短时间发送命令过于频繁
String cacheKey = CacheConstants.DEVICE_ONLINE_STATUS + deviceName;
String incrementCacheKey = CacheConstants.DEVICE_OFFLINE_INCREMENT + deviceName;
String status = redisCache.getCacheObject(cacheKey);
if (StringUtils.isBlank(status)) {
// log.info("进入command");
// 发送命令
CommandResponse res = uploadData(deviceName, productId, "获取在线状态");
// 若是离线则直接返回离线
if (res != null && res.isNotOnline()) {
status = DeviceOnlineStatus.OFFLINE.getStatus();
}
// 若是命令超时则累加redis数据超过3次则判断为离线
else if (res == null || res.isCmdTimeout()) {
long offlineCount = redisCache.incrementCacheValue(incrementCacheKey, 60, TimeUnit.SECONDS);
if (offlineCount >= 3) {
status = DeviceOnlineStatus.OFFLINE.getStatus();
} else {
status = DeviceOnlineStatus.ONLINE.getStatus();
}
}
// 若命令发送成功则清空redis累加数据
else if (res.isSuccess()) {
status = DeviceOnlineStatus.ONLINE.getStatus();
redisCache.deleteObject(incrementCacheKey);
}
// 缓存结果10秒
redisCache.setCacheObject(cacheKey, status, 10, TimeUnit.SECONDS);
}
return status;
} else {
return null;
}
} finally {
if (lock) {
redisLock.unlock(RedisLockKey.DEVICE_ONLINE_COMMAND, deviceName);
}
}
} else {
IotDeviceDetail detail = this.getDeviceDetail(deviceName, productId);
if (detail == null) {
return DeviceOnlineStatus.OFFLINE;
return DeviceOnlineStatus.OFFLINE.getStatus();
}
return IotDeviceDetail.Status.toDeviceOnlineStatus(detail.getStatus());
}
}
@Override
public DeviceOnlineStatus getOnlineStatus(IotDevice device) {
DeviceOnlineStatus status = DeviceOnlineStatus.OFFLINE;
public String getOnlineStatus(IotDevice device) {
String status = DeviceOnlineStatus.OFFLINE.getStatus();
if (device == null || StringUtils.isBlank(device.getProductId())) {
return status;
}
@ -103,7 +154,7 @@ public class IotServiceImpl implements IotService {
status = this.getOnlineStatus(device.iotMac2(), device.getProductId());
}
// 若还是离线则判断mac1是否在线
if (status == DeviceOnlineStatus.OFFLINE && StringUtils.hasText(device.iotMac1())) {
if (!Objects.equals(status, DeviceOnlineStatus.ONLINE.getStatus()) && StringUtils.hasText(device.iotMac1())) {
status = this.getOnlineStatus(device.iotMac1(), device.getProductId());
}
return status;
@ -263,7 +314,7 @@ public class IotServiceImpl implements IotService {
String result = HttpUtils.sendGetWithToken(sendUrl, null, Token.getToken());
log.info("IOT返回的结果【{}】", result);
// log.info("IOT返回的结果【{}】", result);
if (!StringUtils.hasText(result)) {
log.error("与OneNet通信异常");
return Collections.emptyList();
@ -500,7 +551,7 @@ public class IotServiceImpl implements IotService {
CommandResponse res = JSON.parseObject(result, CommandResponse.class);
// 记录日志
this.addCommandLogAsync(deviceName, command, res.getMsg(), reason, res.getCode());
this.addCommandLog(deviceName, command, res.getMsg(), reason, res.getCode());
// 若返回数据为离线或者超时则判断设备是否在线
// if (IotHttpStatus.checkOnlineList().contains(res.getCode())) {
@ -508,23 +559,20 @@ public class IotServiceImpl implements IotService {
// }
return res;
} catch (Exception e) {
this.addCommandLogAsync(deviceName, command, "操作失败:" + e.getMessage(), reason, null);
this.addCommandLog(deviceName, command, "操作失败:" + e.getMessage(), reason, null);
throw e;
}
}
// 异步添加日志
private void addCommandLogAsync(String deviceName, String command, String result, String reason, Integer iotCode) {
private void addCommandLog(String deviceName, String command, String result, String reason, Integer iotCode) {
LoginUser loginUser = null;
try {
loginUser = SecurityUtils.getLoginUser();
} catch (Exception e) {
log.error(e.getMessage());
}
LoginUser finalLoginUser = loginUser;
scheduledExecutorService.schedule(() -> {
commandLogService.addApiLog(deviceName, command, result, reason, finalLoginUser, iotCode);
}, 0, TimeUnit.SECONDS);
commandLogService.addApiLog(deviceName, command, result, reason, loginUser, iotCode);
}
@Override

View File

@ -1,11 +1,12 @@
package com.ruoyi.ss.commandLog.mapper;
import java.util.List;
import com.ruoyi.ss.commandLog.domain.CommandLog;
import com.ruoyi.ss.commandLog.domain.CommandLogVO;
import com.ruoyi.ss.commandLog.domain.CommandLogQuery;
import com.ruoyi.ss.commandLog.domain.CommandLogVO;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* 命令日志Mapper接口
*
@ -61,4 +62,6 @@ public interface CommandLogMapper
* @return 结果
*/
public int deleteCommandLogByIds(Long[] ids);
int batchInsert(@Param("list") List<CommandLog> list);
}

View File

@ -85,6 +85,48 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
</trim>
</insert>
<insert id="batchInsert" parameterType="CommandLog" keyProperty="id" useGeneratedKeys="true">
insert into ss_command_log
<trim prefix="(" suffix=")" suffixOverrides=",">
type,
mac,
reason,
command,
result,
user_id,
user_name,
user_type,
opera_time,
iot_code,
</trim>
values
<foreach collection="list" item="i" separator=",">
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="i.type != null and i.type != ''">#{i.type},</if>
<if test="i.type == null or i.type == ''">default,</if>
<if test="i.mac != null and i.mac != ''">#{i.mac},</if>
<if test="i.mac == null or i.mac == ''">default,</if>
<if test="i.reason != null ">#{i.reason},</if>
<if test="i.reason == null ">default,</if>
<if test="i.command != null ">#{i.command},</if>
<if test="i.command == null ">default,</if>
<if test="i.result != null ">#{i.result},</if>
<if test="i.result == null ">default,</if>
<if test="i.userId != null ">#{i.userId},</if>
<if test="i.userId == null ">default,</if>
<if test="i.userName != null ">#{i.userName},</if>
<if test="i.userName == null ">default,</if>
<if test="i.userType != null ">#{i.userType},</if>
<if test="i.userType == null ">default,</if>
<if test="i.operaTime != null ">#{i.operaTime},</if>
<if test="i.operaTime == null ">default,</if>
<if test="i.iotCode != null ">#{i.iotCode},</if>
<if test="i.iotCode == null ">default,</if>
</trim>
</foreach>
</insert>
<update id="updateCommandLog" parameterType="CommandLog">
update ss_command_log
<trim prefix="SET" suffixOverrides=",">

View File

@ -1,11 +1,11 @@
package com.ruoyi.ss.commandLog.service;
import java.util.List;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.ss.commandLog.domain.CommandLog;
import com.ruoyi.ss.commandLog.domain.CommandLogVO;
import com.ruoyi.ss.commandLog.domain.CommandLogQuery;
import com.ruoyi.ss.commandLog.domain.CommandLogVO;
import java.util.List;
/**
* 命令日志Service接口
@ -79,4 +79,9 @@ public interface ICommandLogService
* 插入一条蓝牙命令日志
*/
int addBluetoothLog(CommandLog po, LoginUser loginUser);
/**
* 批量插入
*/
int batchInsert(List<CommandLog> list);
}

View File

@ -1,19 +1,22 @@
package com.ruoyi.ss.commandLog.service.impl;
import java.time.LocalDateTime;
import java.util.List;
import com.ruoyi.common.constant.CacheConstants;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.collection.CollectionUtils;
import com.ruoyi.ss.commandLog.domain.CommandLog;
import com.ruoyi.ss.commandLog.domain.CommandLogQuery;
import com.ruoyi.ss.commandLog.domain.CommandLogVO;
import com.ruoyi.ss.commandLog.domain.enums.CommandLogType;
import com.ruoyi.ss.commandLog.mapper.CommandLogMapper;
import com.ruoyi.ss.commandLog.service.ICommandLogService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.ss.commandLog.mapper.CommandLogMapper;
import com.ruoyi.ss.commandLog.domain.CommandLog;
import com.ruoyi.ss.commandLog.domain.CommandLogVO;
import com.ruoyi.ss.commandLog.domain.CommandLogQuery;
import com.ruoyi.ss.commandLog.service.ICommandLogService;
import java.time.LocalDateTime;
import java.util.List;
/**
* 命令日志Service业务层处理
@ -28,6 +31,9 @@ public class CommandLogServiceImpl implements ICommandLogService
@Autowired
private CommandLogMapper commandLogMapper;
@Autowired
private RedisCache redisCache;
/**
* 查询命令日志
*
@ -118,6 +124,14 @@ public class CommandLogServiceImpl implements ICommandLogService
return this.addLog(po, loginUser);
}
@Override
public int batchInsert(List<CommandLog> list) {
if (CollectionUtils.isEmptyElement(list)) {
return 0;
}
return commandLogMapper.batchInsert(list);
}
private int addLog(CommandLog po, LoginUser loginUser) {
if (po == null || StringUtils.isBlank(po.getMac())) {
return 0;
@ -131,6 +145,9 @@ public class CommandLogServiceImpl implements ICommandLogService
po.setUserType(loginUser.getLoginType().getType());
}
return this.insertCommandLog(po);
// 添加到缓存中
redisCache.rightPush(CacheConstants.INSERT_COMMAND_LOG, po);
return 1;
}
}

View File

@ -996,15 +996,26 @@ public class DeviceServiceImpl implements DeviceService
private void setOnlineStatus(DeviceVO device, String onlineType) {
// 是否在线
String onlineStatus1 = iotService.getOnlineStatus(device.getMac(), device.getProductId(), onlineType).getStatus();
String onlineStatus2 = iotService.getOnlineStatus(device.getMac2(), device.getProductId(), onlineType).getStatus();
device.setOnlineStatus1(onlineStatus1);
device.setOnlineStatus2(onlineStatus2);
if (DeviceOnlineStatus.ONLINE.getStatus().equals(onlineStatus1) || DeviceOnlineStatus.ONLINE.getStatus().equals(onlineStatus2)) {
device.setOnlineStatus(DeviceOnlineStatus.ONLINE.getStatus());
device.setLastOnlineTime(LocalDateTime.now());
String onlineStatus1 = iotService.getOnlineStatus(device.getMac(), device.getProductId(), onlineType);
String onlineStatus2 = iotService.getOnlineStatus(device.getMac2(), device.getProductId(), onlineType);
// 若有一个没获取到锁则不更新状态
boolean unlockMac1 = StringUtils.isNotBlank(device.getMac()) && onlineStatus1 == null;
boolean unlockMac2 = StringUtils.isNotBlank(device.getMac2()) && onlineStatus2 == null;
if (unlockMac1 || unlockMac2){
device.setOnlineStatus(null);
device.setOnlineStatus1(null);
device.setOnlineStatus2(null);
device.setLastOnlineTime(null);
} else {
device.setOnlineStatus(DeviceOnlineStatus.OFFLINE.getStatus());
device.setOnlineStatus1(onlineStatus1);
device.setOnlineStatus2(onlineStatus2);
if (DeviceOnlineStatus.ONLINE.getStatus().equals(onlineStatus1) || DeviceOnlineStatus.ONLINE.getStatus().equals(onlineStatus2)) {
device.setOnlineStatus(DeviceOnlineStatus.ONLINE.getStatus());
device.setLastOnlineTime(LocalDateTime.now());
} else {
device.setOnlineStatus(DeviceOnlineStatus.OFFLINE.getStatus());
}
}
}
@ -1338,11 +1349,15 @@ public class DeviceServiceImpl implements DeviceService
// 若物联网设备的时长或者电量小于当前设备数据库的值则执行一次同步开启
// 一般情况下物联网设备的值会大于或等于当前数据库的值
// 恢复时长数据库时长大于0时且当前设备时长小于数据库时长
long deviceSeconds = device.getRemainTime() == null ? 0 : device.getRemainTime().longValue();
if (device.getSurplusSecondsDb() > deviceSeconds) {
if (deviceSeconds > 0 && device.getSurplusSecondsDb() > deviceSeconds) {
this.syncTime(device.getDeviceId(), LocalDateTime.now(), "设备监控-同步时长");
}
if (device.getSurplusEleDb().compareTo(device.getSurplusEle()) > 0) {
// 恢复电量数据库电量大于0时且当前设备电量小于数据库电量
BigDecimal surplusEleDb = device.getSurplusEleDb();
if (surplusEleDb.compareTo(BigDecimal.ZERO) > 0 && surplusEleDb.compareTo(device.getSurplusEle()) > 0 ) {
this.syncEle(device.getDeviceId(), "设备监控-同步电量");
}

View File

@ -73,8 +73,8 @@ public class BillMonitorTask {
}
try {
// 判断设备是否在线
DeviceOnlineStatus online = iotService.getOnlineStatus(bill);
if (!DeviceOnlineStatus.ONLINE.equals(online)) {
String online = iotService.getOnlineStatus(bill);
if (online != null && !DeviceOnlineStatus.ONLINE.getStatus().equals(online)) {
log.warn("关闭低功率订单{}时,设备未在线", bill.getBillNo());
continue;
}

View File

@ -0,0 +1,41 @@
package com.ruoyi.task.commandLog;
import com.ruoyi.common.constant.CacheConstants;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.utils.collection.CollectionUtils;
import com.ruoyi.ss.commandLog.domain.CommandLog;
import com.ruoyi.ss.commandLog.service.ICommandLogService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.List;
/**
* @author wjh
* 2025/1/4
*/
@Component
@Slf4j
public class CommandLogTask {
@Autowired
private RedisCache redisCache;
@Autowired
private ICommandLogService commandLogService;
// 从缓存中获取数据并插入到数据库中
public void recordRedis() {
List<CommandLog> list = redisCache.getAndClearCacheList(CacheConstants.INSERT_COMMAND_LOG);
if (CollectionUtils.isEmptyElement(list)) {
log.info("暂无需要保存的数据");
return;
}
// 插入数据库
int insert = commandLogService.batchInsert(list);
log.info("插入命令日志成功,共插入{}条数据", insert);
}
}

View File

@ -16,5 +16,5 @@ PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
<!-- 使用驼峰命名法转换字段 -->
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>
</configuration>