在线状态优化
This commit is contained in:
parent
6bcda98673
commit
2d4f601816
|
@ -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";
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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", "*/*");
|
||||
|
|
|
@ -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">
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -35,12 +33,12 @@ public interface IotService {
|
|||
* @param productId
|
||||
* @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);
|
||||
|
||||
/**
|
||||
* 通电
|
||||
|
|
|
@ -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)) {
|
||||
// 加锁,防止第一次会有多个请求进入
|
||||
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, "获取在线状态");
|
||||
return res != null && res.isSuccess() ? DeviceOnlineStatus.ONLINE : DeviceOnlineStatus.OFFLINE;
|
||||
|
||||
// 若是离线,则直接返回离线
|
||||
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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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=",">
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -996,8 +996,18 @@ 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();
|
||||
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.setOnlineStatus1(onlineStatus1);
|
||||
device.setOnlineStatus2(onlineStatus2);
|
||||
if (DeviceOnlineStatus.ONLINE.getStatus().equals(onlineStatus1) || DeviceOnlineStatus.ONLINE.getStatus().equals(onlineStatus2)) {
|
||||
|
@ -1007,6 +1017,7 @@ public class DeviceServiceImpl implements DeviceService
|
|||
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(), "设备监控-同步电量");
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user