feat:【IoT 物联网】新增设备序列号唯一性校验,添加序列号查询方法
This commit is contained in:
parent
d783890b7c
commit
dd4027239e
@ -81,6 +81,10 @@ public interface IotDeviceMapper extends BaseMapperX<IotDeviceDO> {
|
|||||||
.in(IotDeviceDO::getDeviceName, deviceNames));
|
.in(IotDeviceDO::getDeviceName, deviceNames));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
default IotDeviceDO selectBySerialNumber(String serialNumber) {
|
||||||
|
return selectOne(IotDeviceDO::getSerialNumber, serialNumber);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询指定产品下的设备数量
|
* 查询指定产品下的设备数量
|
||||||
*
|
*
|
||||||
|
|||||||
@ -32,6 +32,7 @@ public interface ErrorCodeConstants {
|
|||||||
ErrorCode DEVICE_NOT_GATEWAY = new ErrorCode(1_050_003_005, "设备不是网关设备");
|
ErrorCode DEVICE_NOT_GATEWAY = new ErrorCode(1_050_003_005, "设备不是网关设备");
|
||||||
ErrorCode DEVICE_IMPORT_LIST_IS_EMPTY = new ErrorCode(1_050_003_006, "导入设备数据不能为空!");
|
ErrorCode DEVICE_IMPORT_LIST_IS_EMPTY = new ErrorCode(1_050_003_006, "导入设备数据不能为空!");
|
||||||
ErrorCode DEVICE_DOWNSTREAM_FAILED_SERVER_ID_NULL = new ErrorCode(1_050_003_007, "下行设备消息失败,原因:设备未连接网关");
|
ErrorCode DEVICE_DOWNSTREAM_FAILED_SERVER_ID_NULL = new ErrorCode(1_050_003_007, "下行设备消息失败,原因:设备未连接网关");
|
||||||
|
ErrorCode DEVICE_SERIAL_NUMBER_EXISTS = new ErrorCode(1_050_003_008, "设备序列号已存在,序列号必须全局唯一");
|
||||||
|
|
||||||
// ========== 产品分类 1-050-004-000 ==========
|
// ========== 产品分类 1-050-004-000 ==========
|
||||||
ErrorCode PRODUCT_CATEGORY_NOT_EXISTS = new ErrorCode(1_050_004_000, "产品分类不存在");
|
ErrorCode PRODUCT_CATEGORY_NOT_EXISTS = new ErrorCode(1_050_004_000, "产品分类不存在");
|
||||||
|
|||||||
@ -3,10 +3,9 @@ package cn.iocoder.yudao.module.iot.service.device;
|
|||||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
import cn.iocoder.yudao.module.iot.controller.admin.device.vo.device.*;
|
import cn.iocoder.yudao.module.iot.controller.admin.device.vo.device.*;
|
||||||
import cn.iocoder.yudao.module.iot.core.biz.dto.IotDeviceAuthReqDTO;
|
import cn.iocoder.yudao.module.iot.core.biz.dto.IotDeviceAuthReqDTO;
|
||||||
import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO;
|
|
||||||
import cn.iocoder.yudao.module.iot.core.enums.IotDeviceStateEnum;
|
import cn.iocoder.yudao.module.iot.core.enums.IotDeviceStateEnum;
|
||||||
|
import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO;
|
||||||
import jakarta.validation.Valid;
|
import jakarta.validation.Valid;
|
||||||
import jakarta.validation.constraints.NotEmpty;
|
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
@ -30,18 +29,6 @@ public interface IotDeviceService {
|
|||||||
*/
|
*/
|
||||||
Long createDevice(@Valid IotDeviceSaveReqVO createReqVO);
|
Long createDevice(@Valid IotDeviceSaveReqVO createReqVO);
|
||||||
|
|
||||||
/**
|
|
||||||
* 【设备注册】创建设备
|
|
||||||
*
|
|
||||||
* @param productKey 产品标识
|
|
||||||
* @param deviceName 设备名称
|
|
||||||
* @param gatewayId 网关设备 ID
|
|
||||||
* @return 设备
|
|
||||||
*/
|
|
||||||
IotDeviceDO createDevice(@NotEmpty(message = "产品标识不能为空") String productKey,
|
|
||||||
@NotEmpty(message = "设备名称不能为空") String deviceName,
|
|
||||||
Long gatewayId);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 更新设备
|
* 更新设备
|
||||||
*
|
*
|
||||||
|
|||||||
@ -73,6 +73,8 @@ public class IotDeviceServiceImpl implements IotDeviceService {
|
|||||||
createReqVO.getGatewayId(), product);
|
createReqVO.getGatewayId(), product);
|
||||||
// 1.3 校验分组存在
|
// 1.3 校验分组存在
|
||||||
deviceGroupService.validateDeviceGroupExists(createReqVO.getGroupIds());
|
deviceGroupService.validateDeviceGroupExists(createReqVO.getGroupIds());
|
||||||
|
// 1.4 校验设备序列号全局唯一
|
||||||
|
validateSerialNumberUnique(createReqVO.getSerialNumber(), null);
|
||||||
|
|
||||||
// 2. 插入到数据库
|
// 2. 插入到数据库
|
||||||
IotDeviceDO device = BeanUtils.toBean(createReqVO, IotDeviceDO.class);
|
IotDeviceDO device = BeanUtils.toBean(createReqVO, IotDeviceDO.class);
|
||||||
@ -81,34 +83,14 @@ public class IotDeviceServiceImpl implements IotDeviceService {
|
|||||||
return device.getId();
|
return device.getId();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public IotDeviceDO createDevice(String productKey, String deviceName, Long gatewayId) {
|
|
||||||
// 1.1 校验产品是否存在
|
|
||||||
IotProductDO product = TenantUtils.executeIgnore(() -> productService.getProductByProductKey(productKey));
|
|
||||||
if (product == null) {
|
|
||||||
throw exception(PRODUCT_NOT_EXISTS);
|
|
||||||
}
|
|
||||||
return TenantUtils.execute(product.getTenantId(), () -> {
|
|
||||||
// 1.2 校验设备名称在同一产品下是否唯一
|
|
||||||
validateCreateDeviceParam(productKey, deviceName, gatewayId, product);
|
|
||||||
|
|
||||||
// 2. 插入到数据库
|
|
||||||
IotDeviceDO device = new IotDeviceDO().setDeviceName(deviceName).setGatewayId(gatewayId);
|
|
||||||
initDevice(device, product);
|
|
||||||
deviceMapper.insert(device);
|
|
||||||
return device;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private void validateCreateDeviceParam(String productKey, String deviceName,
|
private void validateCreateDeviceParam(String productKey, String deviceName,
|
||||||
Long gatewayId, IotProductDO product) {
|
Long gatewayId, IotProductDO product) {
|
||||||
|
// 校验设备名称在同一产品下是否唯一
|
||||||
TenantUtils.executeIgnore(() -> {
|
TenantUtils.executeIgnore(() -> {
|
||||||
// 校验设备名称在同一产品下是否唯一
|
|
||||||
if (deviceMapper.selectByProductKeyAndDeviceName(productKey, deviceName) != null) {
|
if (deviceMapper.selectByProductKeyAndDeviceName(productKey, deviceName) != null) {
|
||||||
throw exception(DEVICE_NAME_EXISTS);
|
throw exception(DEVICE_NAME_EXISTS);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// 校验父设备是否为合法网关
|
// 校验父设备是否为合法网关
|
||||||
if (IotProductDeviceTypeEnum.isGatewaySub(product.getDeviceType())
|
if (IotProductDeviceTypeEnum.isGatewaySub(product.getDeviceType())
|
||||||
&& gatewayId != null) {
|
&& gatewayId != null) {
|
||||||
@ -116,6 +98,22 @@ public class IotDeviceServiceImpl implements IotDeviceService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 校验设备序列号全局唯一性
|
||||||
|
*
|
||||||
|
* @param serialNumber 设备序列号
|
||||||
|
* @param excludeId 排除的设备ID(用于更新时排除自身)
|
||||||
|
*/
|
||||||
|
private void validateSerialNumberUnique(String serialNumber, Long excludeId) {
|
||||||
|
if (StrUtil.isBlank(serialNumber)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
IotDeviceDO existDevice = deviceMapper.selectBySerialNumber(serialNumber);
|
||||||
|
if (existDevice != null && ObjUtil.notEqual(existDevice.getId(), excludeId)) {
|
||||||
|
throw exception(DEVICE_SERIAL_NUMBER_EXISTS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void initDevice(IotDeviceDO device, IotProductDO product) {
|
private void initDevice(IotDeviceDO device, IotProductDO product) {
|
||||||
device.setProductId(product.getId()).setProductKey(product.getProductKey())
|
device.setProductId(product.getId()).setProductKey(product.getProductKey())
|
||||||
.setDeviceType(product.getDeviceType());
|
.setDeviceType(product.getDeviceType());
|
||||||
@ -137,6 +135,8 @@ public class IotDeviceServiceImpl implements IotDeviceService {
|
|||||||
}
|
}
|
||||||
// 1.3 校验分组存在
|
// 1.3 校验分组存在
|
||||||
deviceGroupService.validateDeviceGroupExists(updateReqVO.getGroupIds());
|
deviceGroupService.validateDeviceGroupExists(updateReqVO.getGroupIds());
|
||||||
|
// 1.4 校验设备序列号全局唯一
|
||||||
|
validateSerialNumberUnique(updateReqVO.getSerialNumber(), updateReqVO.getId());
|
||||||
|
|
||||||
// 2. 更新到数据库
|
// 2. 更新到数据库
|
||||||
IotDeviceDO updateObj = BeanUtils.toBean(updateReqVO, IotDeviceDO.class);
|
IotDeviceDO updateObj = BeanUtils.toBean(updateReqVO, IotDeviceDO.class);
|
||||||
@ -417,6 +417,7 @@ public class IotDeviceServiceImpl implements IotDeviceService {
|
|||||||
devices.forEach(this::deleteDeviceCache);
|
devices.forEach(this::deleteDeviceCache);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
@Caching(evict = {
|
@Caching(evict = {
|
||||||
@CacheEvict(value = RedisKeyConstants.DEVICE, key = "#device.id"),
|
@CacheEvict(value = RedisKeyConstants.DEVICE, key = "#device.id"),
|
||||||
@CacheEvict(value = RedisKeyConstants.DEVICE, key = "#device.productKey + '_' + #device.deviceName")
|
@CacheEvict(value = RedisKeyConstants.DEVICE, key = "#device.productKey + '_' + #device.deviceName")
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user