优化在线逻辑
This commit is contained in:
parent
33b469cdbc
commit
6be8a70cf4
|
@ -127,4 +127,9 @@ public class CacheConstants
|
||||||
* 设备更新物联网状态队列
|
* 设备更新物联网状态队列
|
||||||
*/
|
*/
|
||||||
public static final String DEVICE_UPDATE_IOT_QUEUE = "device_update_iot_queue";
|
public static final String DEVICE_UPDATE_IOT_QUEUE = "device_update_iot_queue";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设备在线状态
|
||||||
|
*/
|
||||||
|
public static final String MAC_ONLINE_STATUS = "mac_online_status:";
|
||||||
}
|
}
|
||||||
|
|
|
@ -341,4 +341,19 @@ public class RedisCache
|
||||||
// 执行 Lua 脚本
|
// 执行 Lua 脚本
|
||||||
return (List<T>) redisTemplate.<T>execute(redisScript, Collections.singletonList(key));
|
return (List<T>) redisTemplate.<T>execute(redisScript, Collections.singletonList(key));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取并清空Hash缓存中的所有数据(原子性操作)
|
||||||
|
*
|
||||||
|
* @param key 缓存的键值
|
||||||
|
* @return Hash中的所有数据
|
||||||
|
*/
|
||||||
|
public <T> List<T> getAndClearHashValues(final String key) {
|
||||||
|
String scriptText =
|
||||||
|
"local values = redis.call('HVALS', KEYS[1]) " +
|
||||||
|
"redis.call('DEL', KEYS[1]) " +
|
||||||
|
"return values";
|
||||||
|
RedisScript<List<T>> redisScript = new DefaultRedisScript<>(scriptText, (Class<List<T>>) (Class<?>) List.class);
|
||||||
|
return (List<T>) redisTemplate.execute(redisScript, Collections.singletonList(key));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,8 @@ public enum RedisLockKey {
|
||||||
DEVICE_MAC_UNIQUE("device_mac_unique", "设备MAC唯一"),
|
DEVICE_MAC_UNIQUE("device_mac_unique", "设备MAC唯一"),
|
||||||
USER_NAME_UNIQUE("user_name_unique", "用户账号唯一"),
|
USER_NAME_UNIQUE("user_name_unique", "用户账号唯一"),
|
||||||
DEVICE_IOT_REFRESH("device_iot_refresh", "设备物联网信息刷新"),
|
DEVICE_IOT_REFRESH("device_iot_refresh", "设备物联网信息刷新"),
|
||||||
DEVICE_UPDATE_IOT_LOCK("device_update_iot_lock", "设备更新物联网信息锁");
|
DEVICE_UPDATE_IOT_LOCK("device_update_iot_lock", "设备更新物联网信息锁"),
|
||||||
|
DEVICE_IOT_OPERATION("device_iot_operation", "设备物联网操作锁");
|
||||||
|
|
||||||
private final String key;
|
private final String key;
|
||||||
private final String name;
|
private final String name;
|
||||||
|
|
|
@ -64,4 +64,7 @@ public class DeviceQuery extends DeviceVO {
|
||||||
@DateTimeFormat(pattern = "yyyy-MM-dd")
|
@DateTimeFormat(pattern = "yyyy-MM-dd")
|
||||||
private List<LocalDate> createDateRange;
|
private List<LocalDate> createDateRange;
|
||||||
|
|
||||||
|
@ApiModelProperty("订单设备状态列表")
|
||||||
|
private List<String> orderDeviceStatusList;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -131,6 +131,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||||
<if test="query.lastTimeEnd != null">and bd.last_time <= #{query.lastTimeEnd}</if>
|
<if test="query.lastTimeEnd != null">and bd.last_time <= #{query.lastTimeEnd}</if>
|
||||||
<if test="query.lastTimeStart != null">and bd.last_time >= #{query.lastTimeStart}</if>
|
<if test="query.lastTimeStart != null">and bd.last_time >= #{query.lastTimeStart}</if>
|
||||||
<if test="query.locationType != null and query.locationType != ''">and bd.location_type = #{query.locationType}</if>
|
<if test="query.locationType != null and query.locationType != ''">and bd.location_type = #{query.locationType}</if>
|
||||||
|
<if test="query.orderDeviceId != null">and bd.order_device_id = #{query.orderDeviceId}</if>
|
||||||
<if test="query.keyword != null and query.keyword != ''">
|
<if test="query.keyword != null and query.keyword != ''">
|
||||||
and (
|
and (
|
||||||
bd.sn like concat('%', #{query.keyword}, '%')
|
bd.sn like concat('%', #{query.keyword}, '%')
|
||||||
|
@ -155,6 +156,12 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||||
#{item}
|
#{item}
|
||||||
</foreach>
|
</foreach>
|
||||||
</if>
|
</if>
|
||||||
|
<if test="query.orderDeviceStatusList != null and query.orderDeviceStatusList.size() > 0">
|
||||||
|
and bod.status in
|
||||||
|
<foreach item="item" collection="query.orderDeviceStatusList" open="(" separator="," close=")">
|
||||||
|
#{item}
|
||||||
|
</foreach>
|
||||||
|
</if>
|
||||||
<if test="query.center != null and query.center.size() == 2 and query.radius != null">
|
<if test="query.center != null and query.center.size() == 2 and query.radius != null">
|
||||||
and #{query.radius} >= round(st_distance_sphere(point(#{query.center[0]}, #{query.center[1]}), point(bd.longitude, bd.latitude)))
|
and #{query.radius} >= round(st_distance_sphere(point(#{query.center[0]}, #{query.center[1]}), point(bd.longitude, bd.latitude)))
|
||||||
</if>
|
</if>
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package com.ruoyi.bst.device.service;
|
package com.ruoyi.bst.device.service;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
@ -8,6 +9,7 @@ import com.ruoyi.bst.device.domain.DeviceVO;
|
||||||
import com.ruoyi.bst.device.domain.dto.DeviceBltUploadDTO;
|
import com.ruoyi.bst.device.domain.dto.DeviceBltUploadDTO;
|
||||||
import com.ruoyi.bst.device.domain.enums.DeviceUnLockType;
|
import com.ruoyi.bst.device.domain.enums.DeviceUnLockType;
|
||||||
import com.ruoyi.bst.device.domain.vo.DeviceIotVO;
|
import com.ruoyi.bst.device.domain.vo.DeviceIotVO;
|
||||||
|
import com.ruoyi.bst.device.domain.vo.DeviceOnlineInfo;
|
||||||
|
|
||||||
public interface DeviceIotService {
|
public interface DeviceIotService {
|
||||||
|
|
||||||
|
@ -154,4 +156,19 @@ public interface DeviceIotService {
|
||||||
*/
|
*/
|
||||||
int bltUpload(DeviceBltUploadDTO dto);
|
int bltUpload(DeviceBltUploadDTO dto);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新设备在线状态
|
||||||
|
* @param mac 设备mac地址
|
||||||
|
* @param status 在线状态
|
||||||
|
* @param at 时间
|
||||||
|
*/
|
||||||
|
int updateDeviceOnlineStatus(String mac, String status, LocalDateTime at);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取设备在线状态
|
||||||
|
* @param mac 设备mac地址
|
||||||
|
* @return 设备在线状态
|
||||||
|
*/
|
||||||
|
DeviceOnlineInfo getDeviceOnlineStatus(String mac);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -152,11 +152,6 @@ public interface DeviceService
|
||||||
*/
|
*/
|
||||||
public int clearCurrentOrderDevice(Long id, Long orderDeviceId);
|
public int clearCurrentOrderDevice(Long id, Long orderDeviceId);
|
||||||
|
|
||||||
/**
|
|
||||||
* 根据mac更新在线状态
|
|
||||||
*/
|
|
||||||
int updateOnlineStatusByMac(String mac, String onlineStatus);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 划拨运营区
|
* 划拨运营区
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -19,6 +19,7 @@ import com.ruoyi.bst.device.domain.enums.DeviceQuality;
|
||||||
import com.ruoyi.bst.device.domain.enums.DeviceStatus;
|
import com.ruoyi.bst.device.domain.enums.DeviceStatus;
|
||||||
import com.ruoyi.bst.device.domain.enums.DeviceUnLockType;
|
import com.ruoyi.bst.device.domain.enums.DeviceUnLockType;
|
||||||
import com.ruoyi.bst.device.domain.vo.DeviceIotVO;
|
import com.ruoyi.bst.device.domain.vo.DeviceIotVO;
|
||||||
|
import com.ruoyi.bst.device.domain.vo.DeviceOnlineInfo;
|
||||||
import com.ruoyi.bst.device.mapper.DeviceMapper;
|
import com.ruoyi.bst.device.mapper.DeviceMapper;
|
||||||
import com.ruoyi.bst.device.service.DeviceIotService;
|
import com.ruoyi.bst.device.service.DeviceIotService;
|
||||||
import com.ruoyi.bst.device.service.DeviceService;
|
import com.ruoyi.bst.device.service.DeviceService;
|
||||||
|
@ -79,6 +80,7 @@ public class DeviceIotServiceImpl implements DeviceIotService {
|
||||||
|
|
||||||
private final static Integer SUB_FAST = 5; // 上报频率(快)
|
private final static Integer SUB_FAST = 5; // 上报频率(快)
|
||||||
private final static Integer SUB_SLOW = 300; // 上报频率(慢)
|
private final static Integer SUB_SLOW = 300; // 上报频率(慢)
|
||||||
|
private final static Integer SUB_X_SLOW = 50; // 上报频率(X开头硬件)
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DeviceIotVO unlock(DeviceVO device, DeviceUnLockType type, String reason, boolean requiredIot) {
|
public DeviceIotVO unlock(DeviceVO device, DeviceUnLockType type, String reason, boolean requiredIot) {
|
||||||
|
@ -154,21 +156,27 @@ public class DeviceIotServiceImpl implements DeviceIotService {
|
||||||
ServiceUtil.assertion(!DeviceStatus.canUserLock().contains(device.getStatus()), "设备%s当前状态不允许用户锁车", device.getSn());
|
ServiceUtil.assertion(!DeviceStatus.canUserLock().contains(device.getStatus()), "设备%s当前状态不允许用户锁车", device.getSn());
|
||||||
query.setStatusList(DeviceStatus.canUserLock());
|
query.setStatusList(DeviceStatus.canUserLock());
|
||||||
}
|
}
|
||||||
|
if (DeviceStatus.TEMP_LOCKED.getCode().equals(data.getStatus())) {
|
||||||
|
query.setOrderDeviceId(device.getOrderDeviceId());
|
||||||
|
query.setOrderDeviceStatusList(OrderDeviceStatus.inUse());
|
||||||
|
}
|
||||||
|
|
||||||
transactionTemplate.execute(status -> {
|
transactionTemplate.execute(status -> {
|
||||||
// 更新设备状态
|
// 更新设备状态
|
||||||
int rows = deviceMapper.updateByQuerySimple(data, query);
|
int rows = deviceMapper.updateByQuery(data, query);
|
||||||
vo.setDb(rows);
|
vo.setDb(rows);
|
||||||
|
|
||||||
if (rows > 0) {
|
if (rows > 0) {
|
||||||
// 发送命令锁车
|
// 发送命令锁车
|
||||||
CommandResponse res = null;
|
CommandResponse res = null;
|
||||||
|
|
||||||
|
int sub = getDeviceSubSlow(device);
|
||||||
if (DeviceStatus.TEMP_LOCKED.getCode().equals(data.getStatus())) {
|
if (DeviceStatus.TEMP_LOCKED.getCode().equals(data.getStatus())) {
|
||||||
// 临时锁车
|
// 临时锁车
|
||||||
res = iotService.tempLock(device, SUB_SLOW, reason, 3);
|
res = iotService.tempLock(device, sub, reason, 3);
|
||||||
} else {
|
} else {
|
||||||
// 锁车
|
// 锁车
|
||||||
res = iotService.lock(device, SUB_SLOW, reason, 3);
|
res = iotService.lock(device, sub, reason, 3);
|
||||||
}
|
}
|
||||||
boolean iot = IotUtil.isSuccess(res);
|
boolean iot = IotUtil.isSuccess(res);
|
||||||
ServiceUtil.assertion(requiredIot && !iot, IotUtil.getMsg(res), ServiceCode.IOT_FAILED);
|
ServiceUtil.assertion(requiredIot && !iot, IotUtil.getMsg(res), ServiceCode.IOT_FAILED);
|
||||||
|
@ -181,6 +189,13 @@ public class DeviceIotServiceImpl implements DeviceIotService {
|
||||||
return vo;
|
return vo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int getDeviceSubSlow(DeviceVO device) {
|
||||||
|
if (device != null && device.getHardwareVersion() != null && device.getHardwareVersion().startsWith("X")) {
|
||||||
|
return SUB_X_SLOW;
|
||||||
|
}
|
||||||
|
return SUB_SLOW;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DeviceIotVO qLock(DeviceVO device, String reason, boolean requiredIot) {
|
public DeviceIotVO qLock(DeviceVO device, String reason, boolean requiredIot) {
|
||||||
if (device == null || device.getId() == null) {
|
if (device == null || device.getId() == null) {
|
||||||
|
@ -297,12 +312,10 @@ public class DeviceIotServiceImpl implements DeviceIotService {
|
||||||
}
|
}
|
||||||
|
|
||||||
public int updateIot(Device device) {
|
public int updateIot(Device device) {
|
||||||
if (device == null) {
|
if (device == null || StringUtils.isBlank(device.getMac())) {
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if (StringUtils.isBlank(device.getMac()) && device.getId() == null) {
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Device data = new Device();
|
Device data = new Device();
|
||||||
data.setMac(device.getMac());
|
data.setMac(device.getMac());
|
||||||
data.setVoltage(device.getVoltage());
|
data.setVoltage(device.getVoltage());
|
||||||
|
@ -320,7 +333,7 @@ public class DeviceIotServiceImpl implements DeviceIotService {
|
||||||
data.setSoftwareVersion(device.getSoftwareVersion());
|
data.setSoftwareVersion(device.getSoftwareVersion());
|
||||||
|
|
||||||
// 添加到缓存队列
|
// 添加到缓存队列
|
||||||
redisCache.rightPush(CacheConstants.DEVICE_UPDATE_IOT_QUEUE, data);
|
redisCache.setCacheMapValue(CacheConstants.DEVICE_UPDATE_IOT_QUEUE, data.getMac(), data);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -385,7 +398,7 @@ public class DeviceIotServiceImpl implements DeviceIotService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (DeviceLockStatus.CLOSE.getCode().equals(device.getLockStatus()) && !DeviceQuality.CLOSE.getCode().equals(device.getQuality())) {
|
if (DeviceLockStatus.CLOSE.getCode().equals(device.getLockStatus()) && !DeviceQuality.CLOSE.getCode().equals(device.getQuality())) {
|
||||||
CommandResponse res = iotService.lock(device, SUB_SLOW, "重新尝试锁车", 1);
|
CommandResponse res = iotService.lock(device, getDeviceSubSlow(device), "重新尝试锁车", 1);
|
||||||
if (device.getOrderId() != null) {
|
if (device.getOrderId() != null) {
|
||||||
operLogService.operSysLog("【设备监控】发现未关闭的车辆", IotUtil.isSuccess(res), LogBizType.ORDER, device.getOrderId(), device);
|
operLogService.operSysLog("【设备监控】发现未关闭的车辆", IotUtil.isSuccess(res), LogBizType.ORDER, device.getOrderId(), device);
|
||||||
} else {
|
} else {
|
||||||
|
@ -459,4 +472,37 @@ public class DeviceIotServiceImpl implements DeviceIotService {
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int updateDeviceOnlineStatus(String mac, String status, LocalDateTime at) {
|
||||||
|
if (StringUtils.isBlank(mac) || StringUtils.isBlank(status)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
DeviceOnlineInfo info = this.getDeviceOnlineStatus(mac);
|
||||||
|
if (info == null) {
|
||||||
|
info = new DeviceOnlineInfo();
|
||||||
|
}
|
||||||
|
|
||||||
|
info.setMac(mac);
|
||||||
|
info.setStatus(status);
|
||||||
|
info.setAt(at);
|
||||||
|
|
||||||
|
if (DeviceOnlineStatus.ONLINE.getStatus().equals(status)) {
|
||||||
|
info.setLastOnlineTime(at);
|
||||||
|
}
|
||||||
|
|
||||||
|
String key = CacheConstants.MAC_ONLINE_STATUS + mac;
|
||||||
|
redisCache.setCacheObject(key, info);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DeviceOnlineInfo getDeviceOnlineStatus(String mac) {
|
||||||
|
if (StringUtils.isBlank(mac)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
String key = CacheConstants.MAC_ONLINE_STATUS + mac;
|
||||||
|
return redisCache.getCacheObject(key);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
package com.ruoyi.bst.device.service.impl;
|
package com.ruoyi.bst.device.service.impl;
|
||||||
|
|
||||||
import java.time.LocalDateTime;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
@ -34,7 +33,6 @@ import com.ruoyi.common.utils.DateUtils;
|
||||||
import com.ruoyi.common.utils.ServiceUtil;
|
import com.ruoyi.common.utils.ServiceUtil;
|
||||||
import com.ruoyi.common.utils.StringUtils;
|
import com.ruoyi.common.utils.StringUtils;
|
||||||
import com.ruoyi.common.utils.collection.CollectionUtils;
|
import com.ruoyi.common.utils.collection.CollectionUtils;
|
||||||
import com.ruoyi.iot.service.impl.DeviceOnlineStatus;
|
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
@ -480,20 +478,6 @@ public class DeviceServiceImpl implements DeviceService
|
||||||
return deviceMapper.clearCurrentOrderDevice(id, orderDeviceId);
|
return deviceMapper.clearCurrentOrderDevice(id, orderDeviceId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public int updateOnlineStatusByMac(String mac, String onlineStatus) {
|
|
||||||
if (StringUtils.isBlank(mac) || StringUtils.isBlank(onlineStatus)) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
Device data = new Device();
|
|
||||||
data.setOnlineStatus(onlineStatus);
|
|
||||||
if (DeviceOnlineStatus.ONLINE.getStatus().equals(onlineStatus)) {
|
|
||||||
data.setLastTime(LocalDateTime.now());
|
|
||||||
}
|
|
||||||
data.setMac(mac);
|
|
||||||
return deviceIotService.updateIot(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int transfer(List<DeviceVO> deviceList, Long areaId) {
|
public int transfer(List<DeviceVO> deviceList, Long areaId) {
|
||||||
if (CollectionUtils.isEmptyElement(deviceList) || areaId == null) {
|
if (CollectionUtils.isEmptyElement(deviceList) || areaId == null) {
|
||||||
|
|
|
@ -93,13 +93,15 @@ public class OrderPayHandlerImpl implements PayHandler {
|
||||||
int start = orderDeviceService.start(orderDevice);
|
int start = orderDeviceService.start(orderDevice);
|
||||||
ServiceUtil.assertion(start != 1, "开始使用ID为%s的订单设备失败", orderDevice.getId());
|
ServiceUtil.assertion(start != 1, "开始使用ID为%s的订单设备失败", orderDevice.getId());
|
||||||
|
|
||||||
|
return rows;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (result != null && result == 1) {
|
||||||
// 解锁设备
|
// 解锁设备
|
||||||
DeviceIotVO unlock = deviceIotService.unlock(orderDevice.getDeviceId(), DeviceUnLockType.USER, "订单支付成功开锁:" + order.getNo(), false);
|
DeviceIotVO unlock = deviceIotService.unlock(orderDevice.getDeviceId(), DeviceUnLockType.USER, "订单支付成功开锁:" + order.getNo(), false);
|
||||||
operLogService.operSysLog("订单支付成功开锁", unlock.isIotSuccess(), LogBizType.ORDER, order.getId(), orderDevice.getDeviceId(), orderDevice.getDeviceLongitude(), orderDevice.getDeviceLatitude());
|
operLogService.operSysLog("订单支付成功开锁", unlock.isIotSuccess(), LogBizType.ORDER, order.getId(), orderDevice.getDeviceId(), orderDevice.getDeviceLongitude(), orderDevice.getDeviceLatitude());
|
||||||
ServiceUtil.assertion(unlock.getDb() <= 0, "ID为%s的设备解锁失败", orderDevice.getDeviceId());
|
ServiceUtil.assertion(unlock.getDb() <= 0, "ID为%s的设备解锁失败", orderDevice.getDeviceId());
|
||||||
|
}
|
||||||
return rows;
|
|
||||||
});
|
|
||||||
|
|
||||||
return result != null && result == 1;
|
return result != null && result == 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -112,6 +112,9 @@ public class IotReceiveServiceImpl implements IotReceiveService {
|
||||||
// 增加更新频率控制
|
// 增加更新频率控制
|
||||||
this.updateDeviceIot(device);
|
this.updateDeviceIot(device);
|
||||||
|
|
||||||
|
// 更新设备在线状态
|
||||||
|
deviceIotService.updateDeviceOnlineStatus(device.getMac(), DeviceOnlineStatus.ONLINE.getStatus(), at);
|
||||||
|
|
||||||
// 定位无效,不处理
|
// 定位无效,不处理
|
||||||
if (device.getLongitude() == null || device.getLatitude() == null) {
|
if (device.getLongitude() == null || device.getLatitude() == null) {
|
||||||
log.info("设备{}定位无效,不处理", device.getMac());
|
log.info("设备{}定位无效,不处理", device.getMac());
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package com.ruoyi.iot.service.impl;
|
package com.ruoyi.iot.service.impl;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -17,7 +18,7 @@ import com.alibaba.fastjson2.JSONObject;
|
||||||
import com.ruoyi.bst.commandLog.domain.CommandLog;
|
import com.ruoyi.bst.commandLog.domain.CommandLog;
|
||||||
import com.ruoyi.bst.commandLog.domain.enums.CommandLogType;
|
import com.ruoyi.bst.commandLog.domain.enums.CommandLogType;
|
||||||
import com.ruoyi.bst.commandLog.service.CommandLogService;
|
import com.ruoyi.bst.commandLog.service.CommandLogService;
|
||||||
import com.ruoyi.bst.device.service.DeviceService;
|
import com.ruoyi.bst.device.service.DeviceIotService;
|
||||||
import com.ruoyi.common.constant.CacheConstants;
|
import com.ruoyi.common.constant.CacheConstants;
|
||||||
import com.ruoyi.common.constant.HttpStatus;
|
import com.ruoyi.common.constant.HttpStatus;
|
||||||
import com.ruoyi.common.core.domain.model.LoginUser;
|
import com.ruoyi.common.core.domain.model.LoginUser;
|
||||||
|
@ -87,7 +88,7 @@ public class IotServiceImpl implements IotService {
|
||||||
private RedisLock redisLock;
|
private RedisLock redisLock;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private DeviceService deviceService;
|
private DeviceIotService deviceIotService;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private ScheduledExecutorService scheduledExecutorService;
|
private ScheduledExecutorService scheduledExecutorService;
|
||||||
|
@ -306,19 +307,9 @@ public class IotServiceImpl implements IotService {
|
||||||
String status = this.parseToOnlineStatus(res, deviceName, true);
|
String status = this.parseToOnlineStatus(res, deviceName, true);
|
||||||
redisCache.setCacheObject(this.getOnlineCacheKey(deviceName), status, 10, TimeUnit.SECONDS);
|
redisCache.setCacheObject(this.getOnlineCacheKey(deviceName), status, 10, TimeUnit.SECONDS);
|
||||||
|
|
||||||
// 异步更新设备在线状态
|
// 更新设备在线状态
|
||||||
boolean lock = redisLock.lock(RedisLockKey.DEVICE_UPDATE_IOT_LOCK, deviceName, 60L);
|
deviceIotService.updateDeviceOnlineStatus(deviceName, status, LocalDateTime.now());
|
||||||
if (lock ) {
|
|
||||||
scheduledExecutorService.execute(() -> {
|
|
||||||
int update = deviceService.updateOnlineStatusByMac(deviceName, status);
|
|
||||||
if (update != 1) {
|
|
||||||
log.error("异步更新设备在线状态失败,MAC={},status={}", deviceName, status);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
log.info("设备{}更新太频繁,跳过本次更新", deviceName);
|
|
||||||
}
|
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
this.addCommandLog(device, command, "操作失败:" + e.getMessage(), reason, null, result);
|
this.addCommandLog(device, command, "操作失败:" + e.getMessage(), reason, null, result);
|
||||||
|
|
|
@ -4,7 +4,6 @@ import java.time.LocalDateTime;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import com.ruoyi.common.utils.collection.CollectionUtils;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
@ -14,6 +13,7 @@ import com.ruoyi.bst.device.service.DeviceIotService;
|
||||||
import com.ruoyi.bst.device.service.DeviceService;
|
import com.ruoyi.bst.device.service.DeviceService;
|
||||||
import com.ruoyi.common.constant.CacheConstants;
|
import com.ruoyi.common.constant.CacheConstants;
|
||||||
import com.ruoyi.common.core.redis.RedisCache;
|
import com.ruoyi.common.core.redis.RedisCache;
|
||||||
|
import com.ruoyi.common.utils.collection.CollectionUtils;
|
||||||
import com.ruoyi.iot.service.impl.DeviceOnlineStatus;
|
import com.ruoyi.iot.service.impl.DeviceOnlineStatus;
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
@ -53,7 +53,7 @@ public class DeviceTask {
|
||||||
|
|
||||||
public void refreshIot() {
|
public void refreshIot() {
|
||||||
// 从队列中获取数据
|
// 从队列中获取数据
|
||||||
List<Device> deviceList = redisCache.getAndClearCacheList(CacheConstants.DEVICE_UPDATE_IOT_QUEUE);
|
List<Device> deviceList = redisCache.getAndClearHashValues(CacheConstants.DEVICE_UPDATE_IOT_QUEUE);
|
||||||
if (CollectionUtils.isEmptyElement(deviceList)) {
|
if (CollectionUtils.isEmptyElement(deviceList)) {
|
||||||
return ;
|
return ;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package com.ruoyi.web.app;
|
package com.ruoyi.web.app;
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
@ -9,7 +10,9 @@ import org.springframework.web.bind.annotation.RequestParam;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
import com.ruoyi.bst.device.domain.DeviceQuery;
|
import com.ruoyi.bst.device.domain.DeviceQuery;
|
||||||
|
import com.ruoyi.bst.device.domain.DeviceVO;
|
||||||
import com.ruoyi.bst.device.domain.enums.DeviceStatus;
|
import com.ruoyi.bst.device.domain.enums.DeviceStatus;
|
||||||
|
import com.ruoyi.bst.device.service.DeviceAssembler;
|
||||||
import com.ruoyi.bst.device.service.DeviceService;
|
import com.ruoyi.bst.device.service.DeviceService;
|
||||||
import com.ruoyi.common.annotation.Anonymous;
|
import com.ruoyi.common.annotation.Anonymous;
|
||||||
import com.ruoyi.common.core.controller.BaseController;
|
import com.ruoyi.common.core.controller.BaseController;
|
||||||
|
@ -24,6 +27,9 @@ public class AppDeviceController extends BaseController {
|
||||||
@Autowired
|
@Autowired
|
||||||
private DeviceService deviceService;
|
private DeviceService deviceService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private DeviceAssembler deviceAssembler;
|
||||||
|
|
||||||
@ApiOperation("获取附近可用车辆列表")
|
@ApiOperation("获取附近可用车辆列表")
|
||||||
@GetMapping("/listNearBy")
|
@GetMapping("/listNearBy")
|
||||||
@Anonymous
|
@Anonymous
|
||||||
|
@ -38,14 +44,18 @@ public class AppDeviceController extends BaseController {
|
||||||
return error("中心坐标格式错误,必须包含经度和纬度");
|
return error("中心坐标格式错误,必须包含经度和纬度");
|
||||||
}
|
}
|
||||||
query.setStatus(DeviceStatus.AVAILABLE.getCode());
|
query.setStatus(DeviceStatus.AVAILABLE.getCode());
|
||||||
return success(deviceService.selectDeviceList(query));
|
List<DeviceVO> list = deviceService.selectDeviceList(query);
|
||||||
|
deviceAssembler.assembleOnlineStatus(list);
|
||||||
|
return success(list);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ApiOperation("获取可用车辆详情")
|
@ApiOperation("获取可用车辆详情")
|
||||||
@GetMapping("/availableDetail")
|
@GetMapping("/availableDetail")
|
||||||
@Anonymous
|
@Anonymous
|
||||||
public AjaxResult getAvailableDetail(@RequestParam(required = false) Long id, @RequestParam(required = false) String sn) {
|
public AjaxResult getAvailableDetail(@RequestParam(required = false) Long id, @RequestParam(required = false) String sn) {
|
||||||
return success(deviceService.selectAvaliableDevice(id, sn));
|
DeviceVO device = deviceService.selectAvaliableDevice(id, sn);
|
||||||
|
deviceAssembler.assembleOnlineStatus(device);
|
||||||
|
return success(device);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package com.ruoyi.web.app;
|
package com.ruoyi.web.app;
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.validation.annotation.Validated;
|
import org.springframework.validation.annotation.Validated;
|
||||||
|
@ -17,6 +18,8 @@ import com.ruoyi.bst.device.service.DeviceService;
|
||||||
import com.ruoyi.common.annotation.Log;
|
import com.ruoyi.common.annotation.Log;
|
||||||
import com.ruoyi.common.core.controller.BaseController;
|
import com.ruoyi.common.core.controller.BaseController;
|
||||||
import com.ruoyi.common.core.domain.AjaxResult;
|
import com.ruoyi.common.core.domain.AjaxResult;
|
||||||
|
import com.ruoyi.common.core.redis.RedisLock;
|
||||||
|
import com.ruoyi.common.core.redis.enums.RedisLockKey;
|
||||||
import com.ruoyi.common.enums.BusinessType;
|
import com.ruoyi.common.enums.BusinessType;
|
||||||
import com.ruoyi.common.enums.LogBizType;
|
import com.ruoyi.common.enums.LogBizType;
|
||||||
import com.ruoyi.common.utils.MathUtils;
|
import com.ruoyi.common.utils.MathUtils;
|
||||||
|
@ -36,6 +39,36 @@ public class AppDeviceIotController extends BaseController {
|
||||||
@Autowired
|
@Autowired
|
||||||
private DeviceService deviceService;
|
private DeviceService deviceService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private RedisLock redisLock;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 执行带设备锁的操作
|
||||||
|
* @param device 设备信息
|
||||||
|
* @param operation 具体操作
|
||||||
|
* @return 操作结果
|
||||||
|
*/
|
||||||
|
private AjaxResult executeWithLock(Long deviceId, Supplier<AjaxResult> operation) {
|
||||||
|
ServiceUtil.assertion(deviceId == null, "设备ID不能为空");
|
||||||
|
// 获取设备锁
|
||||||
|
boolean lock = redisLock.lock(RedisLockKey.DEVICE_IOT_OPERATION, deviceId);
|
||||||
|
if (!lock) {
|
||||||
|
return AjaxResult.error("设备操作过于频繁,请稍后再试");
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
return operation.get();
|
||||||
|
} finally {
|
||||||
|
redisLock.unlock(RedisLockKey.DEVICE_IOT_OPERATION, deviceId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private DeviceVO getDevice(Long id, String sn) {
|
||||||
|
if (id != null) {
|
||||||
|
return deviceService.selectDeviceById(id);
|
||||||
|
} else {
|
||||||
|
return deviceService.selectDeviceBySn(sn);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@ApiOperation("用户响铃寻车")
|
@ApiOperation("用户响铃寻车")
|
||||||
@PutMapping("/ring")
|
@PutMapping("/ring")
|
||||||
|
@ -44,12 +77,7 @@ public class AppDeviceIotController extends BaseController {
|
||||||
@RequestParam(required = false) String sn,
|
@RequestParam(required = false) String sn,
|
||||||
@RequestParam(required = false) BigDecimal lon,
|
@RequestParam(required = false) BigDecimal lon,
|
||||||
@RequestParam(required = false) BigDecimal lat) {
|
@RequestParam(required = false) BigDecimal lat) {
|
||||||
DeviceVO device = null;
|
DeviceVO device = getDevice(id, sn);
|
||||||
if (id != null) {
|
|
||||||
device = deviceService.selectDeviceById(id);
|
|
||||||
} else {
|
|
||||||
device = deviceService.selectDeviceBySn(sn);
|
|
||||||
}
|
|
||||||
ServiceUtil.assertion(device == null, "当前车辆不存在,无法响铃寻车");
|
ServiceUtil.assertion(device == null, "当前车辆不存在,无法响铃寻车");
|
||||||
|
|
||||||
if (device.getAreaRequiredRingRadius() != null && device.getAreaRequiredRingRadius()) {
|
if (device.getAreaRequiredRingRadius() != null && device.getAreaRequiredRingRadius()) {
|
||||||
|
@ -59,7 +87,9 @@ public class AppDeviceIotController extends BaseController {
|
||||||
"您当前距离车辆%s米,无法响铃寻车。请距离车辆%s米以内再试", distance, device.getAreaRingRadius());
|
"您当前距离车辆%s米,无法响铃寻车。请距离车辆%s米以内再试", distance, device.getAreaRingRadius());
|
||||||
}
|
}
|
||||||
|
|
||||||
return toAjax(deviceIotService.play(device, IotConstants.PLAY_WARNING, "用户响铃寻车", true));
|
return executeWithLock(device.getId(), () -> {
|
||||||
|
return toAjax(deviceIotService.play(device, IotConstants.PLAY_WARNING, "用户响铃寻车", true));
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ApiOperation("蓝牙上传设备信息")
|
@ApiOperation("蓝牙上传设备信息")
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package com.ruoyi.web.app;
|
package com.ruoyi.web.app;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.validation.annotation.Validated;
|
import org.springframework.validation.annotation.Validated;
|
||||||
|
@ -33,6 +34,8 @@ import com.ruoyi.common.annotation.Log;
|
||||||
import com.ruoyi.common.core.controller.BaseController;
|
import com.ruoyi.common.core.controller.BaseController;
|
||||||
import com.ruoyi.common.core.domain.AjaxResult;
|
import com.ruoyi.common.core.domain.AjaxResult;
|
||||||
import com.ruoyi.common.core.page.TableDataInfo;
|
import com.ruoyi.common.core.page.TableDataInfo;
|
||||||
|
import com.ruoyi.common.core.redis.RedisLock;
|
||||||
|
import com.ruoyi.common.core.redis.enums.RedisLockKey;
|
||||||
import com.ruoyi.common.enums.BusinessType;
|
import com.ruoyi.common.enums.BusinessType;
|
||||||
import com.ruoyi.common.enums.LogBizType;
|
import com.ruoyi.common.enums.LogBizType;
|
||||||
import com.ruoyi.common.utils.LogParamHolder;
|
import com.ruoyi.common.utils.LogParamHolder;
|
||||||
|
@ -53,6 +56,27 @@ public class AppOrderController extends BaseController {
|
||||||
@Autowired
|
@Autowired
|
||||||
private OrderValidator orderValidator;
|
private OrderValidator orderValidator;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private RedisLock redisLock;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 执行带设备锁的操作
|
||||||
|
* @param device 设备信息
|
||||||
|
* @param operation 具体操作
|
||||||
|
* @return 操作结果
|
||||||
|
*/
|
||||||
|
private AjaxResult executeWithLock(Long deviceId, Supplier<AjaxResult> operation) {
|
||||||
|
ServiceUtil.assertion(deviceId == null, "设备ID不能为空");
|
||||||
|
Long lockKey = deviceId;
|
||||||
|
boolean lock = redisLock.lock(RedisLockKey.DEVICE_IOT_OPERATION, lockKey);
|
||||||
|
ServiceUtil.assertion(!lock, "设备操作过于频繁,请稍后再试");
|
||||||
|
try {
|
||||||
|
return operation.get();
|
||||||
|
} finally {
|
||||||
|
redisLock.unlock(RedisLockKey.DEVICE_IOT_OPERATION, lockKey);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@ApiOperation("获取我的订单列表")
|
@ApiOperation("获取我的订单列表")
|
||||||
@GetMapping("/mineList")
|
@GetMapping("/mineList")
|
||||||
public TableDataInfo getMineList(OrderQuery query) {
|
public TableDataInfo getMineList(OrderQuery query) {
|
||||||
|
@ -149,7 +173,9 @@ public class AppOrderController extends BaseController {
|
||||||
if (dto.getRequiredIot() == null) {
|
if (dto.getRequiredIot() == null) {
|
||||||
dto.setRequiredIot(true);
|
dto.setRequiredIot(true);
|
||||||
}
|
}
|
||||||
return success(orderService.openDevice(dto));
|
return executeWithLock(order.getDeviceId(), () -> {
|
||||||
|
return success(orderService.openDevice(dto));
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ApiOperation("临时锁车")
|
@ApiOperation("临时锁车")
|
||||||
|
@ -167,7 +193,9 @@ public class AppOrderController extends BaseController {
|
||||||
if (dto.getRequiredIot() == null) {
|
if (dto.getRequiredIot() == null) {
|
||||||
dto.setRequiredIot(true);
|
dto.setRequiredIot(true);
|
||||||
}
|
}
|
||||||
return success(orderService.closeDevice(dto));
|
return executeWithLock(order.getDeviceId(), () -> {
|
||||||
|
return success(orderService.closeDevice(dto));
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ApiOperation("换车")
|
@ApiOperation("换车")
|
||||||
|
|
|
@ -1,12 +1,9 @@
|
||||||
package com.ruoyi.web.bst;
|
package com.ruoyi.web.bst;
|
||||||
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
import com.ruoyi.bst.areaJoin.domain.enums.AreaJoinPermission;
|
|
||||||
import com.ruoyi.common.utils.collection.CollectionUtils;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.security.access.prepost.PreAuthorize;
|
import org.springframework.security.access.prepost.PreAuthorize;
|
||||||
import org.springframework.validation.annotation.Validated;
|
import org.springframework.validation.annotation.Validated;
|
||||||
|
@ -21,10 +18,12 @@ import org.springframework.web.bind.annotation.RequestParam;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
import com.ruoyi.bst.area.service.AreaValidator;
|
import com.ruoyi.bst.area.service.AreaValidator;
|
||||||
|
import com.ruoyi.bst.areaJoin.domain.enums.AreaJoinPermission;
|
||||||
import com.ruoyi.bst.device.domain.Device;
|
import com.ruoyi.bst.device.domain.Device;
|
||||||
import com.ruoyi.bst.device.domain.DeviceQuery;
|
import com.ruoyi.bst.device.domain.DeviceQuery;
|
||||||
import com.ruoyi.bst.device.domain.DeviceVO;
|
import com.ruoyi.bst.device.domain.DeviceVO;
|
||||||
import com.ruoyi.bst.device.domain.dto.DeviceTransferDTO;
|
import com.ruoyi.bst.device.domain.dto.DeviceTransferDTO;
|
||||||
|
import com.ruoyi.bst.device.service.DeviceAssembler;
|
||||||
import com.ruoyi.bst.device.service.DeviceConverter;
|
import com.ruoyi.bst.device.service.DeviceConverter;
|
||||||
import com.ruoyi.bst.device.service.DeviceIotService;
|
import com.ruoyi.bst.device.service.DeviceIotService;
|
||||||
import com.ruoyi.bst.device.service.DeviceService;
|
import com.ruoyi.bst.device.service.DeviceService;
|
||||||
|
@ -68,6 +67,8 @@ public class DeviceController extends BaseController
|
||||||
@Autowired
|
@Autowired
|
||||||
private DeviceIotService deviceIotService;
|
private DeviceIotService deviceIotService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private DeviceAssembler deviceAssembler;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询设备列表
|
* 查询设备列表
|
||||||
|
@ -84,6 +85,7 @@ public class DeviceController extends BaseController
|
||||||
if (query.getRefresh() != null && query.getRefresh()) {
|
if (query.getRefresh() != null && query.getRefresh()) {
|
||||||
deviceIotService.refresh(list, IotConstants.ONLINE_TYPE_COMMAND);
|
deviceIotService.refresh(list, IotConstants.ONLINE_TYPE_COMMAND);
|
||||||
}
|
}
|
||||||
|
deviceAssembler.assembleOnlineStatus(list);
|
||||||
return getDataTable(list);
|
return getDataTable(list);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -102,6 +104,7 @@ public class DeviceController extends BaseController
|
||||||
if (query.getRefresh() != null && query.getRefresh()) {
|
if (query.getRefresh() != null && query.getRefresh()) {
|
||||||
deviceIotService.refresh(list, IotConstants.ONLINE_TYPE_COMMAND);
|
deviceIotService.refresh(list, IotConstants.ONLINE_TYPE_COMMAND);
|
||||||
}
|
}
|
||||||
|
deviceAssembler.assembleOnlineStatus(list);
|
||||||
return success(list);
|
return success(list);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -134,6 +137,7 @@ public class DeviceController extends BaseController
|
||||||
if (refresh) {
|
if (refresh) {
|
||||||
deviceIotService.refresh(device, IotConstants.ONLINE_TYPE_COMMAND);
|
deviceIotService.refresh(device, IotConstants.ONLINE_TYPE_COMMAND);
|
||||||
}
|
}
|
||||||
|
deviceAssembler.assembleOnlineStatus(device);
|
||||||
|
|
||||||
return success(device);
|
return success(device);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
package com.ruoyi.web.bst;
|
package com.ruoyi.web.bst;
|
||||||
|
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.security.access.prepost.PreAuthorize;
|
import org.springframework.security.access.prepost.PreAuthorize;
|
||||||
import org.springframework.web.bind.annotation.PutMapping;
|
import org.springframework.web.bind.annotation.PutMapping;
|
||||||
|
@ -16,12 +18,18 @@ import com.ruoyi.bst.device.service.DeviceValidator;
|
||||||
import com.ruoyi.common.annotation.Log;
|
import com.ruoyi.common.annotation.Log;
|
||||||
import com.ruoyi.common.core.controller.BaseController;
|
import com.ruoyi.common.core.controller.BaseController;
|
||||||
import com.ruoyi.common.core.domain.AjaxResult;
|
import com.ruoyi.common.core.domain.AjaxResult;
|
||||||
|
import com.ruoyi.common.core.redis.RedisLock;
|
||||||
|
import com.ruoyi.common.core.redis.enums.RedisLockKey;
|
||||||
import com.ruoyi.common.enums.BusinessType;
|
import com.ruoyi.common.enums.BusinessType;
|
||||||
import com.ruoyi.common.enums.LogBizType;
|
import com.ruoyi.common.enums.LogBizType;
|
||||||
|
import com.ruoyi.common.utils.ServiceUtil;
|
||||||
import com.ruoyi.iot.constants.IotConstants;
|
import com.ruoyi.iot.constants.IotConstants;
|
||||||
|
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("/bst/device/iot")
|
@RequestMapping("/bst/device/iot")
|
||||||
|
@Slf4j
|
||||||
public class DeviceIotController extends BaseController {
|
public class DeviceIotController extends BaseController {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
|
@ -33,16 +41,39 @@ public class DeviceIotController extends BaseController {
|
||||||
@Autowired
|
@Autowired
|
||||||
private DeviceValidator deviceValidator;
|
private DeviceValidator deviceValidator;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private RedisLock redisLock;
|
||||||
|
|
||||||
private DeviceVO getDevice(Long id, String sn) {
|
private DeviceVO getDevice(Long id, String sn) {
|
||||||
return deviceService.selectDevice(id, sn, true, AreaJoinPermission.DEVICE_EDIT);
|
return deviceService.selectDevice(id, sn, true, AreaJoinPermission.DEVICE_EDIT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 执行带设备锁的操作
|
||||||
|
* @param device 设备信息
|
||||||
|
* @param operation 具体操作
|
||||||
|
* @return 操作结果
|
||||||
|
*/
|
||||||
|
private AjaxResult executeWithLock(DeviceVO device, Supplier<AjaxResult> operation) {
|
||||||
|
if (device == null) {
|
||||||
|
return toAjax(0);
|
||||||
|
}
|
||||||
|
Long lockKey = device.getId();
|
||||||
|
boolean lock = redisLock.lock(RedisLockKey.DEVICE_IOT_OPERATION, lockKey);
|
||||||
|
ServiceUtil.assertion(!lock, "设备操作过于频繁,请稍后再试");
|
||||||
|
try {
|
||||||
|
return operation.get();
|
||||||
|
} finally {
|
||||||
|
redisLock.unlock(RedisLockKey.DEVICE_IOT_OPERATION, lockKey);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@PreAuthorize("@ss.hasPermi('bst:device:unlock')")
|
@PreAuthorize("@ss.hasPermi('bst:device:unlock')")
|
||||||
@Log(title = "管理员开锁", businessType = BusinessType.OTHER, bizIdName = "arg0", bizType = LogBizType.DEVICE)
|
@Log(title = "管理员开锁", businessType = BusinessType.OTHER, bizIdName = "arg0", bizType = LogBizType.DEVICE)
|
||||||
@PutMapping("/unlock")
|
@PutMapping("/unlock")
|
||||||
public AjaxResult unlock(@RequestParam(required = false) Long id, @RequestParam(required = false) String sn) {
|
public AjaxResult unlock(@RequestParam(required = false) Long id, @RequestParam(required = false) String sn) {
|
||||||
DeviceVO device = this.getDevice(id, sn);
|
DeviceVO device = this.getDevice(id, sn);
|
||||||
return success(deviceIotService.unlock(device, DeviceUnLockType.ADMIN, "管理员开锁", true));
|
return executeWithLock(device, () -> success(deviceIotService.unlock(device, DeviceUnLockType.ADMIN, "管理员开锁", true)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@PreAuthorize("@ss.hasPermi('bst:device:lock')")
|
@PreAuthorize("@ss.hasPermi('bst:device:lock')")
|
||||||
|
@ -50,7 +81,7 @@ public class DeviceIotController extends BaseController {
|
||||||
@PutMapping("/lock")
|
@PutMapping("/lock")
|
||||||
public AjaxResult lock(@RequestParam(required = false) Long id, @RequestParam(required = false) String sn) {
|
public AjaxResult lock(@RequestParam(required = false) Long id, @RequestParam(required = false) String sn) {
|
||||||
DeviceVO device = this.getDevice(id, sn);
|
DeviceVO device = this.getDevice(id, sn);
|
||||||
return success(deviceIotService.lock(device, true, "管理员锁车", true));
|
return executeWithLock(device, () -> success(deviceIotService.lock(device, true, "管理员锁车", true)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@PreAuthorize("@ss.hasPermi('bst:device:ring')")
|
@PreAuthorize("@ss.hasPermi('bst:device:ring')")
|
||||||
|
@ -58,7 +89,7 @@ public class DeviceIotController extends BaseController {
|
||||||
@PutMapping("/ring")
|
@PutMapping("/ring")
|
||||||
public AjaxResult ring(@RequestParam(required = false) Long id, @RequestParam(required = false) String sn) {
|
public AjaxResult ring(@RequestParam(required = false) Long id, @RequestParam(required = false) String sn) {
|
||||||
DeviceVO device = this.getDevice(id, sn);
|
DeviceVO device = this.getDevice(id, sn);
|
||||||
return toAjax(deviceIotService.play(device, IotConstants.PLAY_WARNING, "管理员响铃寻车", true));
|
return executeWithLock(device, () -> success(deviceIotService.play(device, IotConstants.PLAY_WARNING, "管理员响铃寻车", true)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@PreAuthorize("@ss.hasPermi('bst:device:reboot')")
|
@PreAuthorize("@ss.hasPermi('bst:device:reboot')")
|
||||||
|
@ -66,7 +97,7 @@ public class DeviceIotController extends BaseController {
|
||||||
@PutMapping("/reboot")
|
@PutMapping("/reboot")
|
||||||
public AjaxResult reboot(@RequestParam(required = false) Long id, @RequestParam(required = false) String sn) {
|
public AjaxResult reboot(@RequestParam(required = false) Long id, @RequestParam(required = false) String sn) {
|
||||||
DeviceVO device = this.getDevice(id, sn);
|
DeviceVO device = this.getDevice(id, sn);
|
||||||
return toAjax(deviceIotService.reboot(device, "管理员重启", true));
|
return executeWithLock(device, () -> success(deviceIotService.reboot(device, "管理员重启", true)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@PreAuthorize("@ss.hasPermi('bst:device:unlockSeat')")
|
@PreAuthorize("@ss.hasPermi('bst:device:unlockSeat')")
|
||||||
|
@ -74,7 +105,7 @@ public class DeviceIotController extends BaseController {
|
||||||
@PutMapping("/unlockSeat")
|
@PutMapping("/unlockSeat")
|
||||||
public AjaxResult unlockSeat(@RequestParam(required = false) Long id, @RequestParam(required = false) String sn) {
|
public AjaxResult unlockSeat(@RequestParam(required = false) Long id, @RequestParam(required = false) String sn) {
|
||||||
DeviceVO device = this.getDevice(id, sn);
|
DeviceVO device = this.getDevice(id, sn);
|
||||||
return toAjax(deviceIotService.unlockSeat(device, "管理员开坐垫锁", true));
|
return executeWithLock(device, () -> success(deviceIotService.unlockSeat(device, "管理员开坐垫锁", true)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@PreAuthorize("@ss.hasPermi('bst:device:refresh')")
|
@PreAuthorize("@ss.hasPermi('bst:device:refresh')")
|
||||||
|
@ -82,8 +113,10 @@ public class DeviceIotController extends BaseController {
|
||||||
@PutMapping("/refresh")
|
@PutMapping("/refresh")
|
||||||
public AjaxResult refresh(@RequestParam(required = false) Long id, @RequestParam(required = false) String sn) {
|
public AjaxResult refresh(@RequestParam(required = false) Long id, @RequestParam(required = false) String sn) {
|
||||||
DeviceVO device = this.getDevice(id, sn);
|
DeviceVO device = this.getDevice(id, sn);
|
||||||
deviceIotService.refresh(device, IotConstants.ONLINE_TYPE_COMMAND);
|
return executeWithLock(device, () -> {
|
||||||
return success(device);
|
deviceIotService.refresh(device, IotConstants.ONLINE_TYPE_COMMAND);
|
||||||
|
return success(device);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@PreAuthorize("@ss.hasPermi('bst:device:music')")
|
@PreAuthorize("@ss.hasPermi('bst:device:music')")
|
||||||
|
@ -91,6 +124,6 @@ public class DeviceIotController extends BaseController {
|
||||||
@PutMapping("/music")
|
@PutMapping("/music")
|
||||||
public AjaxResult music(@RequestParam(required = false) Long id, @RequestParam(required = false) String sn, @RequestParam String music) {
|
public AjaxResult music(@RequestParam(required = false) Long id, @RequestParam(required = false) String sn, @RequestParam String music) {
|
||||||
DeviceVO device = this.getDevice(id, sn);
|
DeviceVO device = this.getDevice(id, sn);
|
||||||
return success(deviceIotService.setMusic(device, music, "管理员设置声音", true));
|
return executeWithLock(device, () -> success(deviceIotService.setMusic(device, music, "管理员设置声音", true)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -128,7 +128,7 @@ iot:
|
||||||
# iot秘钥
|
# iot秘钥
|
||||||
accessKey: dJqF0qYhUbK/o1Pr9I5qxNoP14FlJLC+BFK2ZTjUX+lnKwoNYvBYsM/7Xu1ERIzSkUoxVkP/N1RMvGlBKMoBtA==
|
accessKey: dJqF0qYhUbK/o1Pr9I5qxNoP14FlJLC+BFK2ZTjUX+lnKwoNYvBYsM/7Xu1ERIzSkUoxVkP/N1RMvGlBKMoBtA==
|
||||||
# 超时响应时间(秒)
|
# 超时响应时间(秒)
|
||||||
timeout: 10
|
timeout: 5
|
||||||
# token过期时间
|
# token过期时间
|
||||||
daysToExpire: 100
|
daysToExpire: 100
|
||||||
# 推送消息token
|
# 推送消息token
|
||||||
|
|
Loading…
Reference in New Issue
Block a user