【功能修改】IoT:设备状态从 status 到 state,移除已禁用

This commit is contained in:
YunaiV 2025-01-29 00:17:08 +08:00
parent f14cc470aa
commit f6366d9b55
12 changed files with 74 additions and 136 deletions

View File

@ -1,7 +1,7 @@
package cn.iocoder.yudao.module.iot.api.device.dto;
import cn.iocoder.yudao.framework.common.validation.InEnum;
import cn.iocoder.yudao.module.iot.enums.device.IotDeviceStatusEnum;
import cn.iocoder.yudao.module.iot.enums.device.IotDeviceStateEnum;
import jakarta.validation.constraints.NotEmpty;
import lombok.Data;
import lombok.NoArgsConstructor;
@ -19,7 +19,7 @@ public class IotDeviceStatusUpdateReqDTO extends IotDeviceUpstreamAbstractReqDTO
* 设备状态
*/
@NotEmpty(message = "设备状态不能为空")
@InEnum(IotDeviceStatusEnum.class) // 只使用在线离线
@InEnum(IotDeviceStateEnum.class) // 只使用在线离线
private Integer status;
}

View File

@ -14,6 +14,6 @@ public class DictTypeConstants {
public static final String DATA_FORMAT = "iot_data_format";
public static final String VALIDATE_TYPE = "iot_validate_type";
public static final String DEVICE_STATUS = "iot_device_status";
public static final String DEVICE_STATE = "iot_device_state";
}

View File

@ -0,0 +1,38 @@
package cn.iocoder.yudao.module.iot.enums.device;
import cn.iocoder.yudao.framework.common.core.ArrayValuable;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import java.util.Arrays;
/**
* IoT 设备状态枚举
*
* @author haohao
*/
@RequiredArgsConstructor
@Getter
public enum IotDeviceStateEnum implements ArrayValuable<Integer> {
INACTIVE(0, "未激活"),
ONLINE(1, "在线"),
OFFLINE(2, "离线");
public static final Integer[] ARRAYS = Arrays.stream(values()).map(IotDeviceStateEnum::getState).toArray(Integer[]::new);
/**
* 状态
*/
private final Integer state;
/**
* 状态名
*/
private final String name;
@Override
public Integer[] array() {
return ARRAYS;
}
}

View File

@ -1,55 +0,0 @@
package cn.iocoder.yudao.module.iot.enums.device;
import cn.iocoder.yudao.framework.common.core.ArrayValuable;
import lombok.Getter;
import java.util.Arrays;
/**
* IoT 设备状态枚举
*
* @author haohao
*/
@Getter
public enum IotDeviceStatusEnum implements ArrayValuable<Integer> {
INACTIVE(0, "未激活"),
ONLINE(1, "在线"),
OFFLINE(2, "离线"),
DISABLED(3, "已禁用");
public static final Integer[] ARRAYS = Arrays.stream(values()).map(IotDeviceStatusEnum::getStatus).toArray(Integer[]::new);
/**
* 状态
*/
private final Integer status;
/**
* 状态名
*/
private final String name;
IotDeviceStatusEnum(Integer status, String name) {
this.status = status;
this.name = name;
}
public static IotDeviceStatusEnum fromStatus(Integer status) {
for (IotDeviceStatusEnum value : values()) {
if (value.getStatus().equals(status)) {
return value;
}
}
return null;
}
public static boolean isValidStatus(Integer status) {
return fromStatus(status) != null;
}
@Override
public Integer[] array() {
return ARRAYS;
}
}

View File

@ -45,14 +45,6 @@ public class IotDeviceController {
return success(deviceService.createDevice(createReqVO));
}
@PutMapping("/update-status")
@Operation(summary = "更新设备状态")
@PreAuthorize("@ss.hasPermission('iot:device:update')")
public CommonResult<Boolean> updateDeviceStatus(@Valid @RequestBody IotDeviceStatusUpdateReqVO updateReqVO) {
deviceService.updateDeviceStatus(updateReqVO);
return success(true);
}
@PutMapping("/update")
@Operation(summary = "更新设备")
@PreAuthorize("@ss.hasPermission('iot:device:update')")

View File

@ -2,7 +2,7 @@ package cn.iocoder.yudao.module.iot.controller.admin.device.vo.device;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.validation.InEnum;
import cn.iocoder.yudao.module.iot.enums.device.IotDeviceStatusEnum;
import cn.iocoder.yudao.module.iot.enums.device.IotDeviceStateEnum;
import cn.iocoder.yudao.module.iot.enums.product.IotProductDeviceTypeEnum;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@ -25,7 +25,7 @@ public class IotDevicePageReqVO extends PageParam {
private Integer deviceType;
@Schema(description = "设备状态", example = "1")
@InEnum(IotDeviceStatusEnum.class)
@InEnum(IotDeviceStateEnum.class)
private Integer status;
@Schema(description = "设备分组编号", example = "1024")

View File

@ -10,7 +10,7 @@ import lombok.Data;
import java.time.LocalDateTime;
import java.util.Set;
import static cn.iocoder.yudao.module.iot.enums.DictTypeConstants.DEVICE_STATUS;
import static cn.iocoder.yudao.module.iot.enums.DictTypeConstants.DEVICE_STATE;
@Schema(description = "管理后台 - IoT 设备 Response VO")
@Data
@ -60,20 +60,16 @@ public class IotDeviceRespVO {
@Schema(description = "设备状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@ExcelProperty(value = "设备状态", converter = DictConvert.class)
@DictFormat(DEVICE_STATUS)
private Integer status;
@Schema(description = "设备状态最后更新时间")
@ExcelProperty("设备状态最后更新时间")
private LocalDateTime statusLastUpdateTime;
@DictFormat(DEVICE_STATE)
private Integer state;
@Schema(description = "最后上线时间")
@ExcelProperty("最后上线时间")
private LocalDateTime lastOnlineTime;
private LocalDateTime onlineTime;
@Schema(description = "最后离线时间")
@ExcelProperty("最后离线时间")
private LocalDateTime lastOfflineTime;
private LocalDateTime offlineTime;
@Schema(description = "设备激活时间")
@ExcelProperty("设备激活时间")

View File

@ -1,21 +0,0 @@
package cn.iocoder.yudao.module.iot.controller.admin.device.vo.device;
import cn.iocoder.yudao.framework.common.validation.InEnum;
import cn.iocoder.yudao.module.iot.enums.device.IotDeviceStatusEnum;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
@Schema(description = "管理后台 - IoT 设备状态更新 Request VO")
@Data
public class IotDeviceStatusUpdateReqVO {
@Schema(description = "设备编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@NotNull(message = "设备编号不能为空")
private Long id;
@Schema(description = "设备状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@NotNull(message = "设备状态不能为空")
@InEnum(IotDeviceStatusEnum.class)
private Integer status;
}

View File

@ -3,7 +3,7 @@ package cn.iocoder.yudao.module.iot.dal.dataobject.device;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
import cn.iocoder.yudao.framework.mybatis.core.type.LongSetTypeHandler;
import cn.iocoder.yudao.module.iot.dal.dataobject.product.IotProductDO;
import cn.iocoder.yudao.module.iot.enums.device.IotDeviceStatusEnum;
import cn.iocoder.yudao.module.iot.enums.device.IotDeviceStateEnum;
import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
@ -94,22 +94,17 @@ public class IotDeviceDO extends BaseDO {
/**
* 设备状态
* <p>
* 枚举 {@link IotDeviceStatusEnum}
* 枚举 {@link IotDeviceStateEnum}
*/
private Integer status;
/**
* 设备状态最后更新时间
*/
private LocalDateTime statusLastUpdateTime;
private Integer state;
/**
* 最后上线时间
*/
private LocalDateTime lastOnlineTime;
private LocalDateTime onlineTime;
/**
* 最后离线时间
*/
private LocalDateTime lastOfflineTime;
private LocalDateTime offlineTime;
/**
* 设备激活时间
*/

View File

@ -25,7 +25,7 @@ public interface IotDeviceMapper extends BaseMapperX<IotDeviceDO> {
.eqIfPresent(IotDeviceDO::getProductId, reqVO.getProductId())
.eqIfPresent(IotDeviceDO::getDeviceType, reqVO.getDeviceType())
.likeIfPresent(IotDeviceDO::getNickname, reqVO.getNickname())
.eqIfPresent(IotDeviceDO::getStatus, reqVO.getStatus())
.eqIfPresent(IotDeviceDO::getState, reqVO.getStatus())
.apply(ObjectUtil.isNotNull(reqVO.getGroupId()), "FIND_IN_SET(" + reqVO.getGroupId() + ",group_ids) > 0")
.orderByDesc(IotDeviceDO::getId));
}

View File

@ -34,9 +34,10 @@ public interface IotDeviceService {
/**
* 更新设备状态
*
* @param updateReqVO 更新信息
* @param id 编号
* @param state 状态
*/
void updateDeviceStatus(IotDeviceStatusUpdateReqVO updateReqVO);
void updateDeviceState(Long id, Integer state);
/**
* 更新设备分组

View File

@ -19,7 +19,7 @@ import cn.iocoder.yudao.module.iot.dal.dataobject.product.IotProductDO;
import cn.iocoder.yudao.module.iot.dal.mysql.device.IotDeviceMapper;
import cn.iocoder.yudao.module.iot.dal.redis.RedisKeyConstants;
import cn.iocoder.yudao.module.iot.enums.device.IotDeviceMessageTypeEnum;
import cn.iocoder.yudao.module.iot.enums.device.IotDeviceStatusEnum;
import cn.iocoder.yudao.module.iot.enums.device.IotDeviceStateEnum;
import cn.iocoder.yudao.module.iot.enums.product.IotProductDeviceTypeEnum;
import cn.iocoder.yudao.module.iot.service.device.upstream.IotDeviceUpstreamService;
import cn.iocoder.yudao.module.iot.service.product.IotProductService;
@ -89,7 +89,6 @@ public class IotDeviceServiceImpl implements IotDeviceService {
deviceGroupService.validateDeviceGroupExists(createReqVO.getGroupIds());
// 2.1 转换 VO DO
// TODO @芋艿state 相关的参数另外到底叫 state还是 status
// TODO @芋艿各种 mqtt 是不是可以简化
IotDeviceDO device = BeanUtils.toBean(createReqVO, IotDeviceDO.class, o -> {
o.setProductKey(product.getProductKey()).setDeviceType(product.getDeviceType());
@ -99,7 +98,7 @@ public class IotDeviceServiceImpl implements IotDeviceService {
.setMqttUsername(generateMqttUsername(o.getDeviceName(), o.getProductKey()))
.setMqttPassword(generateMqttPassword());
// 设置设备状态为未激活
o.setStatus(IotDeviceStatusEnum.INACTIVE.getStatus()).setStatusLastUpdateTime(LocalDateTime.now());
o.setState(IotDeviceStateEnum.INACTIVE.getState());
});
// 2.2 插入到数据库
deviceMapper.insert(device);
@ -232,29 +231,22 @@ public class IotDeviceServiceImpl implements IotDeviceService {
}
@Override
public void updateDeviceStatus(IotDeviceStatusUpdateReqVO updateReqVO) {
// TODO @芋艿state 相关的参数另外到底叫 state还是 status
// TODO @芋艿各种时间需要 check 优化处理下
public void updateDeviceState(Long id, Integer state) {
// 1. 校验存在
IotDeviceDO device = validateDeviceExists(updateReqVO.getId());
IotDeviceDO device = validateDeviceExists(id);
// 2.1 更新状态和更新时间
IotDeviceDO updateDevice = BeanUtils.toBean(updateReqVO, IotDeviceDO.class)
.setStatusLastUpdateTime(LocalDateTime.now());
// 2.2 更新状态相关时间
if (Objects.equals(device.getStatus(), IotDeviceStatusEnum.INACTIVE.getStatus())
&& Objects.equals(updateDevice.getStatus(), IotDeviceStatusEnum.ONLINE.getStatus())) {
// 从未激活到在线设置激活时间和最后上线时间
updateDevice.setActiveTime(LocalDateTime.now()).setLastOnlineTime(LocalDateTime.now());
} else if (Objects.equals(updateDevice.getStatus(), IotDeviceStatusEnum.ONLINE.getStatus())) {
// 如果是上线设置最后上线时间
updateDevice.setLastOnlineTime(LocalDateTime.now());
} else if (Objects.equals(updateDevice.getStatus(), IotDeviceStatusEnum.OFFLINE.getStatus())) {
// 如果是离线设置最后离线时间
updateDevice.setLastOfflineTime(LocalDateTime.now());
// 2. 更新状态和时间
IotDeviceDO updateObj = new IotDeviceDO().setId(id).setState(state);
if (device.getOnlineTime() == null
&& Objects.equals(state, IotDeviceStateEnum.ONLINE.getState())) {
updateObj.setActiveTime(LocalDateTime.now());
}
// 2.3 更新到数据库
deviceMapper.updateById(updateDevice);
if (Objects.equals(state, IotDeviceStateEnum.ONLINE.getState())) {
updateObj.setOnlineTime(LocalDateTime.now());
} else if (Objects.equals(state, IotDeviceStateEnum.OFFLINE.getState())) {
updateObj.setOfflineTime(LocalDateTime.now());
}
deviceMapper.updateById(updateObj);
// 3. 清空对应缓存
deleteDeviceCache(device);
@ -417,8 +409,8 @@ public class IotDeviceServiceImpl implements IotDeviceService {
// 2.3 情况三状态变更
if (Objects.equals(reportReqVO.getType(), IotDeviceMessageTypeEnum.STATE.getType())) {
// TODO 芋艿待实现
updateDeviceStatus(new IotDeviceStatusUpdateReqVO().setId(device.getId())
.setStatus((Integer) reportReqVO.getData()));
// updateDeviceState(new IotDeviceStatusUpdateReqVO().setId(device.getId())
// .setStatus((Integer) reportReqVO.getData()));
return;
}
throw new IllegalArgumentException("未知的类型:" + reportReqVO.getType());