diff --git a/ruoyi-service/src/main/java/com/ruoyi/bst/device/domain/DeviceQuery.java b/ruoyi-service/src/main/java/com/ruoyi/bst/device/domain/DeviceQuery.java index d92a5ff..ce846dc 100644 --- a/ruoyi-service/src/main/java/com/ruoyi/bst/device/domain/DeviceQuery.java +++ b/ruoyi-service/src/main/java/com/ruoyi/bst/device/domain/DeviceQuery.java @@ -1,8 +1,11 @@ package com.ruoyi.bst.device.domain; import java.math.BigDecimal; +import java.time.LocalDateTime; import java.util.List; +import org.springframework.format.annotation.DateTimeFormat; + import io.swagger.annotations.ApiModelProperty; import lombok.Data; @@ -47,4 +50,9 @@ public class DeviceQuery extends DeviceVO { @ApiModelProperty("关键词") private String keyword; + + @ApiModelProperty("最后上报时间(结束)") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime lastTimeEnd; + } diff --git a/ruoyi-service/src/main/java/com/ruoyi/bst/device/service/DeviceIotService.java b/ruoyi-service/src/main/java/com/ruoyi/bst/device/service/DeviceIotService.java index 5d9850f..531f752 100644 --- a/ruoyi-service/src/main/java/com/ruoyi/bst/device/service/DeviceIotService.java +++ b/ruoyi-service/src/main/java/com/ruoyi/bst/device/service/DeviceIotService.java @@ -3,6 +3,7 @@ package com.ruoyi.bst.device.service; import java.util.Collections; import java.util.List; +import com.ruoyi.bst.device.domain.Device; import com.ruoyi.bst.device.domain.DeviceVO; import com.ruoyi.bst.device.domain.enums.DeviceUnLockType; import com.ruoyi.bst.device.domain.vo.DeviceIotVO; @@ -138,4 +139,11 @@ public interface DeviceIotService { */ DeviceIotVO setMusic(DeviceVO device, String music, String reason, boolean requiredIot); + /** + * 更新物联网信息 + * @param device + * @return + */ + int updateIot(Device device); + } diff --git a/ruoyi-service/src/main/java/com/ruoyi/bst/device/service/DeviceService.java b/ruoyi-service/src/main/java/com/ruoyi/bst/device/service/DeviceService.java index 53d6aed..498e543 100644 --- a/ruoyi-service/src/main/java/com/ruoyi/bst/device/service/DeviceService.java +++ b/ruoyi-service/src/main/java/com/ruoyi/bst/device/service/DeviceService.java @@ -202,5 +202,13 @@ public interface DeviceService */ public List listSnByMac(List macList); + /** + * 条件更新 + * @param data + * @param query + * @return + */ + public int updateByQuery(Device data, DeviceQuery query); + } diff --git a/ruoyi-service/src/main/java/com/ruoyi/bst/device/service/impl/DeviceIotServiceImpl.java b/ruoyi-service/src/main/java/com/ruoyi/bst/device/service/impl/DeviceIotServiceImpl.java index a250e5f..88cb718 100644 --- a/ruoyi-service/src/main/java/com/ruoyi/bst/device/service/impl/DeviceIotServiceImpl.java +++ b/ruoyi-service/src/main/java/com/ruoyi/bst/device/service/impl/DeviceIotServiceImpl.java @@ -26,7 +26,6 @@ import com.ruoyi.bst.device.utils.DeviceUtil; import com.ruoyi.bst.orderDevice.domain.enums.OrderDeviceStatus; import com.ruoyi.common.constants.ServiceCode; import com.ruoyi.common.core.redis.RedisLock; -import com.ruoyi.common.core.redis.enums.RedisLockKey; import com.ruoyi.common.utils.MathUtils; import com.ruoyi.common.utils.ServiceUtil; import com.ruoyi.common.utils.StringUtils; @@ -276,27 +275,27 @@ public class DeviceIotServiceImpl implements DeviceIotService { } // 异步更新数据库 - scheduledExecutorService.schedule(() -> { - for (DeviceVO device : deviceList) { - try { - // 加锁,控制更新频率 - boolean lock = redisLock.lock(RedisLockKey.DEVICE_IOT_REFRESH, device.getMac(), 10); - if (!lock) { - continue; - } + // scheduledExecutorService.schedule(() -> { + // for (DeviceVO device : deviceList) { + // try { + // // 加锁,控制更新频率 + // boolean lock = redisLock.lock(RedisLockKey.DEVICE_IOT_REFRESH, device.getMac(), 10); + // if (!lock) { + // continue; + // } - // 获取在线状态 - if (StringUtils.hasText(onlineType)) { - String onlineStatus = iotService.getOnlineStatus(device, onlineType); - this.setOnlineStatus(device, onlineStatus); - } - // 更新物联网信息 - this.updateIot(device); - } catch (Exception e) { - log.error("更新设备{}物联网信息失败", device.getSn(), e); - } - } - }, 0, TimeUnit.SECONDS); + // // 获取在线状态 + // if (StringUtils.hasText(onlineType)) { + // String onlineStatus = iotService.getOnlineStatus(device, onlineType); + // this.setOnlineStatus(device, onlineStatus); + // } + // // 更新物联网信息 + // this.updateIot(device); + // } catch (Exception e) { + // log.error("更新设备{}物联网信息失败", device.getSn(), e); + // } + // } + // }, 0, TimeUnit.SECONDS); } private void setOnlineStatus(DeviceVO device, String onlineStatus) { @@ -308,11 +307,13 @@ public class DeviceIotServiceImpl implements DeviceIotService { } public int updateIot(Device device) { - if (device == null || device.getId() == null) { + if (device == null) { + return 0; + } + if (StringUtils.isBlank(device.getMac()) || device.getId() == null) { return 0; } Device data = new Device(); - data.setId(device.getId()); data.setVoltage(device.getVoltage()); data.setSignalStrength(device.getSignalStrength()); data.setQuality(device.getQuality()); @@ -326,7 +327,10 @@ public class DeviceIotServiceImpl implements DeviceIotService { data.setOnlineStatus(device.getOnlineStatus()); data.setLastOnlineTime(device.getLastOnlineTime()); data.setSoftwareVersion(device.getSoftwareVersion()); - return deviceMapper.updateDevice(data); + DeviceQuery query = new DeviceQuery(); + query.setId(device.getId()); + query.setMac(device.getMac()); + return deviceMapper.updateByQuery(data, query); } @Override diff --git a/ruoyi-service/src/main/java/com/ruoyi/bst/device/service/impl/DeviceServiceImpl.java b/ruoyi-service/src/main/java/com/ruoyi/bst/device/service/impl/DeviceServiceImpl.java index 916872d..9be4bac 100644 --- a/ruoyi-service/src/main/java/com/ruoyi/bst/device/service/impl/DeviceServiceImpl.java +++ b/ruoyi-service/src/main/java/com/ruoyi/bst/device/service/impl/DeviceServiceImpl.java @@ -580,6 +580,12 @@ public class DeviceServiceImpl implements DeviceService DeviceQuery query = new DeviceQuery(); query.setMacList(macList); return deviceMapper.selectMacSnList(query); - } + + @Override + public int updateByQuery(Device data, DeviceQuery query) { + return deviceMapper.updateByQuery(data, query); + } + + } diff --git a/ruoyi-service/src/main/java/com/ruoyi/bst/device/utils/DeviceUtil.java b/ruoyi-service/src/main/java/com/ruoyi/bst/device/utils/DeviceUtil.java index adacd8d..0f51f8b 100644 --- a/ruoyi-service/src/main/java/com/ruoyi/bst/device/utils/DeviceUtil.java +++ b/ruoyi-service/src/main/java/com/ruoyi/bst/device/utils/DeviceUtil.java @@ -37,7 +37,8 @@ public class DeviceUtil { } } } - + + device.setLastTime(at); device.setVoltage(sys.getBat()); device.setSignalStrength(sys.getCsq()); device.setQuality(sys.getQ()); @@ -61,7 +62,6 @@ public class DeviceUtil { setIotSysInfo(device, sys, iot.getAt()); } device.setSoftwareVersion(iot.getVer()); - device.setLastTime(iot.getAt()); } /** diff --git a/ruoyi-service/src/main/java/com/ruoyi/bst/order/service/impl/OrderServiceImpl.java b/ruoyi-service/src/main/java/com/ruoyi/bst/order/service/impl/OrderServiceImpl.java index 652ee18..9d82327 100644 --- a/ruoyi-service/src/main/java/com/ruoyi/bst/order/service/impl/OrderServiceImpl.java +++ b/ruoyi-service/src/main/java/com/ruoyi/bst/order/service/impl/OrderServiceImpl.java @@ -4,7 +4,6 @@ import java.math.BigDecimal; import java.time.Duration; import java.time.LocalDateTime; import java.util.List; -import java.util.Objects; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; @@ -68,7 +67,6 @@ import com.ruoyi.bst.pay.service.PayConverter; import com.ruoyi.bst.pay.service.PayService; import com.ruoyi.bst.refund.domain.enums.RefundType; import com.ruoyi.bst.sms.service.SmsService; -import com.ruoyi.common.core.domain.vo.UserVO; import com.ruoyi.common.core.redis.RedisLock; import com.ruoyi.common.core.redis.enums.RedisLockKey; import com.ruoyi.common.utils.DateUtils; @@ -251,12 +249,11 @@ public class OrderServiceImpl implements OrderService // 校验参数 orderValidator.validate(bo); - // 若设备当前订单未支付,且是当前用户的订单,则将其取消 + // 若设备当前订单未支付,则将其取消 DeviceVO device = bo.getDevice(); - UserVO user = bo.getUser(); - if (device.getOrderId() != null && OrderStatus.WAIT_PAY.getCode().equals(device.getOrderStatus()) && Objects.equals(device.getOrderUserId(), user.getUserId())) { - int cancel = this.cancelOrder(device.getOrderId(), "取消用户重复订单"); - ServiceUtil.assertion(cancel != 1, "取消用户重复订单失败"); + if (device.getOrderId() != null && OrderStatus.WAIT_PAY.getCode().equals(device.getOrderStatus())) { + int cancel = this.cancelOrder(device.getOrderId(), "取消上一个未支付订单"); + ServiceUtil.assertion(cancel != 1, "取消上一个未支付订单失败"); } return transactionTemplate.execute(status -> { diff --git a/ruoyi-service/src/main/java/com/ruoyi/iot/service/impl/IotReceiveServiceImpl.java b/ruoyi-service/src/main/java/com/ruoyi/iot/service/impl/IotReceiveServiceImpl.java index 50d9443..a2f0ffe 100644 --- a/ruoyi-service/src/main/java/com/ruoyi/iot/service/impl/IotReceiveServiceImpl.java +++ b/ruoyi-service/src/main/java/com/ruoyi/iot/service/impl/IotReceiveServiceImpl.java @@ -85,16 +85,10 @@ public class IotReceiveServiceImpl implements IotReceiveService { } // 转为设备信息 - log.info("收到sys数据:" + msg.getValue()); + log.info("收到sys数据:{}", msg.getValue()); IotDeviceSysInfo sys = IotUtil.toSysInfo(msg.getValue()); LocalDateTime at = DateUtils.toLocalDateTime(msg.getAt()); - // 0,0定位不处理 - if (MathUtils.equals(sys.getLon(), BigDecimal.ZERO) && MathUtils.equals(sys.getLat(), BigDecimal.ZERO)) { - log.info("设备{}定位异常:{},{},不处理", msg.getDevName(), sys.getLon(), sys.getLat()); - return; - } - // 处理设备定位BUG,若出现BUG则重启设备 int handle = this.handleDeviceLocationBug(device, sys, at); if (handle == 1) { @@ -103,17 +97,19 @@ public class IotReceiveServiceImpl implements IotReceiveService { // 设置设备信息 DeviceUtil.setIotSysInfo(device, sys, at); - device.setLastTime(at); - device.setLastLocationTime(at); - // 卫星数量小于5,不处理设备操作 - if (device.getSatellites() == null || device.getSatellites() < 5) { - log.error("卫星数量小于5,不处理: {}", device.getMac()); - return; + // 更新设备信息 + device.setOnlineStatus(DeviceOnlineStatus.ONLINE.getStatus()); + device.setLastOnlineTime(at); + int update = deviceIotService.updateIot(device); + if (update != 1) { + log.error("更新设备信息失败: {}", msg.getDevName()); } + // 处理运营区 this.handleArea(device); + // 处理定位日志 this.handleLocationLog(device); } } @@ -147,6 +143,11 @@ public class IotReceiveServiceImpl implements IotReceiveService { if (duration.getSeconds() > 60) { return 0; } + // 0,0定位不处理 + if (MathUtils.equals(sys.getLon(), BigDecimal.ZERO) && MathUtils.equals(sys.getLat(), BigDecimal.ZERO)) { + log.info("设备{}定位异常:{},{},不处理", device.getMac(), sys.getLon(), sys.getLat()); + return 0; + } boolean isOpen = DeviceQuality.OPEN.getCode().equals(sys.getQ()); // 电门是否开启 // 需要在设备未启动的时候做,否则可能有安全问题 if (!isOpen) { @@ -174,6 +175,16 @@ public class IotReceiveServiceImpl implements IotReceiveService { if (duration.getSeconds() > 60) { return; } + // 卫星数量小于5,不处理设备操作 + if (device.getSatellites() == null || device.getSatellites() < 5) { + log.error("卫星数量小于5,不处理: {}", device.getMac()); + return; + } + // 0,0定位不处理 + if (MathUtils.equals(device.getLongitude(), BigDecimal.ZERO) && MathUtils.equals(device.getLatitude(), BigDecimal.ZERO)) { + log.info("设备{}定位异常:{},{},不处理", device.getMac(), device.getLongitude(), device.getLatitude()); + return; + } // 若处理过,则不处理 String key = CacheConstants.DEVICE_AREA_HANDLE_KEY + device.getMac(); Integer isHandle = redisCache.getCacheObject(key); @@ -275,6 +286,17 @@ public class IotReceiveServiceImpl implements IotReceiveService { // 定位日志处理 private void handleLocationLog(DeviceVO device) { + + // 卫星数量小于5,不处理设备操作 + if (device.getSatellites() == null || device.getSatellites() < 5) { + log.error("卫星数量小于5,不处理: {}", device.getMac()); + return; + } + // 0,0定位不处理 + if (MathUtils.equals(device.getLongitude(), BigDecimal.ZERO) && MathUtils.equals(device.getLatitude(), BigDecimal.ZERO)) { + log.info("设备{}定位异常:{},{},不处理", device.getMac(), device.getLongitude(), device.getLatitude()); + return; + } // 转换定位日志 LocationLog po = locationLogConverter.toPo(device); if (po == null) { diff --git a/ruoyi-service/src/main/java/com/ruoyi/iot/service/impl/IotServiceImpl.java b/ruoyi-service/src/main/java/com/ruoyi/iot/service/impl/IotServiceImpl.java index afb4d7a..2d38675 100644 --- a/ruoyi-service/src/main/java/com/ruoyi/iot/service/impl/IotServiceImpl.java +++ b/ruoyi-service/src/main/java/com/ruoyi/iot/service/impl/IotServiceImpl.java @@ -280,9 +280,9 @@ public class IotServiceImpl implements IotService { // 记录成功日志 this.addCommandLog(device, command, res.getMsg(), reason, res.getCode(), result); - // 转为在线状态,并缓存结果30秒 + // 转为在线状态,并缓存结果10秒 String status = this.parseToOnlineStatus(res, deviceName, true); - redisCache.setCacheObject(this.getOnlineCacheKey(deviceName), status, 30, TimeUnit.SECONDS); + redisCache.setCacheObject(this.getOnlineCacheKey(deviceName), status, 10, TimeUnit.SECONDS); // 异步更新设备在线状态 scheduledExecutorService.schedule(() -> { int update = deviceService.updateOnlineStatusByMac(deviceName, status); diff --git a/ruoyi-web/src/main/java/com/ruoyi/task/device/DeviceTask.java b/ruoyi-web/src/main/java/com/ruoyi/task/device/DeviceTask.java index 23d4027..8efff1b 100644 --- a/ruoyi-web/src/main/java/com/ruoyi/task/device/DeviceTask.java +++ b/ruoyi-web/src/main/java/com/ruoyi/task/device/DeviceTask.java @@ -1,14 +1,19 @@ package com.ruoyi.task.device; +import java.time.LocalDateTime; +import java.util.ArrayList; + import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; +import com.ruoyi.bst.device.domain.Device; +import com.ruoyi.bst.device.domain.DeviceQuery; import com.ruoyi.bst.device.service.DeviceIotService; +import com.ruoyi.bst.device.service.DeviceService; +import com.ruoyi.iot.service.impl.DeviceOnlineStatus; import lombok.extern.slf4j.Slf4j; -import java.util.ArrayList; - @Component @Slf4j public class DeviceTask { @@ -16,9 +21,27 @@ public class DeviceTask { @Autowired private DeviceIotService deviceIotService; + @Autowired + private DeviceService deviceService; + // 监控所有设备 public void monitorAll() { deviceIotService.monitor(new ArrayList<>()); } + /** + * 将过久未上报数据的设备设置为离线 + */ + public void monitorOffline(long seconds) { + // 条件:在线且最后上报时间小于当前时间 - seconds秒 + DeviceQuery query = new DeviceQuery(); + query.setOnlineStatus(DeviceOnlineStatus.ONLINE.getStatus()); + query.setLastTimeEnd(LocalDateTime.now().plusSeconds(-seconds)); + + Device data = new Device(); + data.setOnlineStatus(DeviceOnlineStatus.OFFLINE.getStatus()); + int update = deviceService.updateByQuery(data, query); + log.info("更新了{}条离线的设备数据", update); + } + }