feat:【IoT 物联网】新增设备序列号唯一性校验,添加序列号查询方法
This commit is contained in:
@@ -81,6 +81,10 @@ public interface IotDeviceMapper extends BaseMapperX<IotDeviceDO> {
|
||||
.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_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_SERIAL_NUMBER_EXISTS = new ErrorCode(1_050_003_008, "设备序列号已存在,序列号必须全局唯一");
|
||||
|
||||
// ========== 产品分类 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.module.iot.controller.admin.device.vo.device.*;
|
||||
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.dal.dataobject.device.IotDeviceDO;
|
||||
import jakarta.validation.Valid;
|
||||
import jakarta.validation.constraints.NotEmpty;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.time.LocalDateTime;
|
||||
@@ -30,18 +29,6 @@ public interface IotDeviceService {
|
||||
*/
|
||||
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);
|
||||
// 1.3 校验分组存在
|
||||
deviceGroupService.validateDeviceGroupExists(createReqVO.getGroupIds());
|
||||
// 1.4 校验设备序列号全局唯一
|
||||
validateSerialNumberUnique(createReqVO.getSerialNumber(), null);
|
||||
|
||||
// 2. 插入到数据库
|
||||
IotDeviceDO device = BeanUtils.toBean(createReqVO, IotDeviceDO.class);
|
||||
@@ -81,34 +83,14 @@ public class IotDeviceServiceImpl implements IotDeviceService {
|
||||
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,
|
||||
Long gatewayId, IotProductDO product) {
|
||||
// 校验设备名称在同一产品下是否唯一
|
||||
TenantUtils.executeIgnore(() -> {
|
||||
// 校验设备名称在同一产品下是否唯一
|
||||
if (deviceMapper.selectByProductKeyAndDeviceName(productKey, deviceName) != null) {
|
||||
throw exception(DEVICE_NAME_EXISTS);
|
||||
}
|
||||
});
|
||||
|
||||
// 校验父设备是否为合法网关
|
||||
if (IotProductDeviceTypeEnum.isGatewaySub(product.getDeviceType())
|
||||
&& 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) {
|
||||
device.setProductId(product.getId()).setProductKey(product.getProductKey())
|
||||
.setDeviceType(product.getDeviceType());
|
||||
@@ -137,6 +135,8 @@ public class IotDeviceServiceImpl implements IotDeviceService {
|
||||
}
|
||||
// 1.3 校验分组存在
|
||||
deviceGroupService.validateDeviceGroupExists(updateReqVO.getGroupIds());
|
||||
// 1.4 校验设备序列号全局唯一
|
||||
validateSerialNumberUnique(updateReqVO.getSerialNumber(), updateReqVO.getId());
|
||||
|
||||
// 2. 更新到数据库
|
||||
IotDeviceDO updateObj = BeanUtils.toBean(updateReqVO, IotDeviceDO.class);
|
||||
@@ -417,6 +417,7 @@ public class IotDeviceServiceImpl implements IotDeviceService {
|
||||
devices.forEach(this::deleteDeviceCache);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@Caching(evict = {
|
||||
@CacheEvict(value = RedisKeyConstants.DEVICE, key = "#device.id"),
|
||||
@CacheEvict(value = RedisKeyConstants.DEVICE, key = "#device.productKey + '_' + #device.deviceName")
|
||||
|
||||
Reference in New Issue
Block a user