Commit ce7aceb2230a4f9ed51f5994d9f5e403afc93721

Authored by xp.Huang
1 parent 85fdd054

fix:删除网关设备时,如果下挂的有网关子设备则进行异常提示

@@ -306,11 +306,13 @@ public class TkDeviceController extends BaseController { @@ -306,11 +306,13 @@ public class TkDeviceController extends BaseController {
306 public void deleteDevices(@Validated({DeleteGroup.class}) @RequestBody DeleteDTO deleteDTO) 306 public void deleteDevices(@Validated({DeleteGroup.class}) @RequestBody DeleteDTO deleteDTO)
307 throws ThingsboardException { 307 throws ThingsboardException {
308 String currentTenantId = getCurrentUser().getCurrentTenantId(); 308 String currentTenantId = getCurrentUser().getCurrentTenantId();
309 - List<String> tdIds = tkdeviceService.findTbDeviceId(currentTenantId, deleteDTO.getIds());  
310 - for (String id : tdIds) {  
311 - deleteTbDevice(id); 309 + List<String> tdIds = tkdeviceService.findTbDeviceIdAndCheckForDelete(currentTenantId, deleteDTO.getIds());
  310 + if(null !=tdIds){
  311 + for (String id : tdIds) {
  312 + deleteTbDevice(id);
  313 + }
  314 + tkdeviceService.deleteDevices(currentTenantId, deleteDTO.getIds());
312 } 315 }
313 - tkdeviceService.deleteDevices(currentTenantId, deleteDTO.getIds());  
314 } 316 }
315 317
316 private void deleteTbDevice(String id) throws ThingsboardException { 318 private void deleteTbDevice(String id) throws ThingsboardException {
@@ -112,6 +112,7 @@ public enum ErrorMessage { @@ -112,6 +112,7 @@ public enum ErrorMessage {
112 MESSAGE_TEMPLATE_DELETED(400020,"消息模板不存在!"), 112 MESSAGE_TEMPLATE_DELETED(400020,"消息模板不存在!"),
113 NEED_MAIN_PARAMETER(400021, "缺少必要参数【%s】"), 113 NEED_MAIN_PARAMETER(400021, "缺少必要参数【%s】"),
114 REGISTER_VALUE_IS_NONE(400022, "寄存器值不能为空"), 114 REGISTER_VALUE_IS_NONE(400022, "寄存器值不能为空"),
  115 + GATE_WAY_DEVICE_HAS_SENSOR(400023, "网关设备【%s】有下挂网关子设备"),
115 NOT_ALLOED_ISOLATED_IN_MONOLITH(500003,"【monolith】模式下,不能选择【isolated】类型的租户配置"), 116 NOT_ALLOED_ISOLATED_IN_MONOLITH(500003,"【monolith】模式下,不能选择【isolated】类型的租户配置"),
116 MESSAGE_TEMPLATE_USING_CONFIG(500004,"消息配置正在被消息模板【%s】使用"); 117 MESSAGE_TEMPLATE_USING_CONFIG(500004,"消息配置正在被消息模板【%s】使用");
117 private final int code; 118 private final int code;
@@ -9,7 +9,6 @@ import com.google.common.util.concurrent.ListenableFuture; @@ -9,7 +9,6 @@ import com.google.common.util.concurrent.ListenableFuture;
9 import lombok.RequiredArgsConstructor; 9 import lombok.RequiredArgsConstructor;
10 import lombok.extern.slf4j.Slf4j; 10 import lombok.extern.slf4j.Slf4j;
11 import org.apache.commons.lang3.StringUtils; 11 import org.apache.commons.lang3.StringUtils;
12 -import org.jetbrains.annotations.NotNull;  
13 import org.jetbrains.annotations.Nullable; 12 import org.jetbrains.annotations.Nullable;
14 import org.springframework.cache.annotation.Cacheable; 13 import org.springframework.cache.annotation.Cacheable;
15 import org.springframework.stereotype.Service; 14 import org.springframework.stereotype.Service;
@@ -94,7 +93,8 @@ public class TkDeviceServiceImpl extends AbstractBaseService<DeviceMapper, TkDev @@ -94,7 +93,8 @@ public class TkDeviceServiceImpl extends AbstractBaseService<DeviceMapper, TkDev
94 } 93 }
95 94
96 @Override 95 @Override
97 - public void validateFormData(String currentTenantId, DeviceDTO deviceDTO) throws RuntimeException{ 96 + public void validateFormData(String currentTenantId, DeviceDTO deviceDTO)
  97 + throws RuntimeException {
98 boolean insert = StringUtils.isBlank(deviceDTO.getId()); 98 boolean insert = StringUtils.isBlank(deviceDTO.getId());
99 String deviceTenantId; 99 String deviceTenantId;
100 if (StringUtils.isBlank(deviceDTO.getName())) { 100 if (StringUtils.isBlank(deviceDTO.getName())) {
@@ -132,25 +132,30 @@ public class TkDeviceServiceImpl extends AbstractBaseService<DeviceMapper, TkDev @@ -132,25 +132,30 @@ public class TkDeviceServiceImpl extends AbstractBaseService<DeviceMapper, TkDev
132 DeviceProfile deviceProfile = 132 DeviceProfile deviceProfile =
133 deviceProfileDao.findById(id, UUID.fromString(deviceDTO.getProfileId())); 133 deviceProfileDao.findById(id, UUID.fromString(deviceDTO.getProfileId()));
134 OrganizationDTO organization = 134 OrganizationDTO organization =
135 - organizationService.findOrganizationById(deviceDTO.getOrganizationId(),deviceTenantId); 135 + organizationService.findOrganizationById(deviceDTO.getOrganizationId(), deviceTenantId);
136 if (null == deviceProfile || null == organization) { 136 if (null == deviceProfile || null == organization) {
137 throw new TkDataValidationException(ErrorMessage.INVALID_PARAMETER.getMessage()); 137 throw new TkDataValidationException(ErrorMessage.INVALID_PARAMETER.getMessage());
138 } else if (!organization.getTenantId().equals(deviceTenantId)) { 138 } else if (!organization.getTenantId().equals(deviceTenantId)) {
139 throw new TkDataValidationException(ErrorMessage.TENANT_MISMATCHING.getMessage()); 139 throw new TkDataValidationException(ErrorMessage.TENANT_MISMATCHING.getMessage());
140 } 140 }
141 - //如果是TCP的网关子设备,要验证其Code是否已在网关的其他子设备存在  
142 - if(Objects.equals(deviceDTO.getDeviceType(),DeviceTypeEnum.SENSOR) && Objects.equals(deviceProfile.getTransportType(),  
143 - DeviceTransportType.TCP)){ 141 + // 如果是TCP的网关子设备,要验证其Code是否已在网关的其他子设备存在
  142 + if (Objects.equals(deviceDTO.getDeviceType(), DeviceTypeEnum.SENSOR)
  143 + && Objects.equals(deviceProfile.getTransportType(), DeviceTransportType.TCP)) {
144 String gateWayId = deviceDTO.getGatewayId(); 144 String gateWayId = deviceDTO.getGatewayId();
145 - List<TkDeviceEntity> entities = baseMapper.selectList(new LambdaQueryWrapper<TkDeviceEntity>()  
146 - .eq(TkDeviceEntity::getTenantId,currentTenantId)  
147 - .eq(TkDeviceEntity::getGatewayId,gateWayId)  
148 - .ne(!insert,TkDeviceEntity::getId,deviceDTO.getId()));  
149 - if(null != entities && !entities.isEmpty()){  
150 - for (TkDeviceEntity entity:entities) {  
151 - if(Objects.equals(deviceDTO.getCode(),entity.getCode())){  
152 - throw new TkDataValidationException(String.format(ErrorMessage.DEVICE_IDENTIFIER_REPEATED.getMessage(),  
153 - deviceDTO.getCode(),StringUtils.isEmpty(entity.getAlias())?entity.getName():entity.getAlias())); 145 + List<TkDeviceEntity> entities =
  146 + baseMapper.selectList(
  147 + new LambdaQueryWrapper<TkDeviceEntity>()
  148 + .eq(TkDeviceEntity::getTenantId, currentTenantId)
  149 + .eq(TkDeviceEntity::getGatewayId, gateWayId)
  150 + .ne(!insert, TkDeviceEntity::getId, deviceDTO.getId()));
  151 + if (null != entities && !entities.isEmpty()) {
  152 + for (TkDeviceEntity entity : entities) {
  153 + if (Objects.equals(deviceDTO.getCode(), entity.getCode())) {
  154 + throw new TkDataValidationException(
  155 + String.format(
  156 + ErrorMessage.DEVICE_IDENTIFIER_REPEATED.getMessage(),
  157 + deviceDTO.getCode(),
  158 + StringUtils.isEmpty(entity.getAlias()) ? entity.getName() : entity.getAlias()));
154 } 159 }
155 } 160 }
156 } 161 }
@@ -248,21 +253,38 @@ public class TkDeviceServiceImpl extends AbstractBaseService<DeviceMapper, TkDev @@ -248,21 +253,38 @@ public class TkDeviceServiceImpl extends AbstractBaseService<DeviceMapper, TkDev
248 } 253 }
249 254
250 @Override 255 @Override
251 - public List<String> findTbDeviceId(String tenantId, Set<String> ids) { 256 + public List<String> findTbDeviceIdAndCheckForDelete(String tenantId, Set<String> ids) {
252 LambdaQueryWrapper<TkDeviceEntity> queryWrapper = 257 LambdaQueryWrapper<TkDeviceEntity> queryWrapper =
253 new QueryWrapper<TkDeviceEntity>() 258 new QueryWrapper<TkDeviceEntity>()
254 .lambda() 259 .lambda()
255 .eq(TkDeviceEntity::getTenantId, tenantId) 260 .eq(TkDeviceEntity::getTenantId, tenantId)
256 .in(TkDeviceEntity::getId, ids); 261 .in(TkDeviceEntity::getId, ids);
257 262
258 - List<String> tbDeviceIds =  
259 - baseMapper.selectList(queryWrapper).stream()  
260 - .map(TkDeviceEntity::getTbDeviceId)  
261 - .collect(Collectors.toList());  
262 - for (String tbDeviceId : tbDeviceIds) { 263 + List<TkDeviceEntity> list = baseMapper.selectList(queryWrapper);
  264 + if (null == list || list.isEmpty()) {
  265 + return null;
  266 + }
  267 + for (TkDeviceEntity entity : list) {
  268 + String tbDeviceId = entity.getTbDeviceId();
263 sceneNotUsed(tenantId, tbDeviceId, null); 269 sceneNotUsed(tenantId, tbDeviceId, null);
  270 + // 检查是否有网关子设备在使用该设备
  271 + if (Objects.equals(entity.getDeviceType(), DeviceTypeEnum.GATEWAY)) {
  272 + int sensorSize =
  273 + baseMapper
  274 + .selectList(
  275 + new LambdaQueryWrapper<TkDeviceEntity>()
  276 + .eq(TkDeviceEntity::getTenantId, tenantId)
  277 + .eq(TkDeviceEntity::getGatewayId, tbDeviceId))
  278 + .size();
  279 + if (sensorSize > FastIotConstants.MagicNumber.ZERO) {
  280 + throw new TkDataValidationException(
  281 + String.format(
  282 + ErrorMessage.GATE_WAY_DEVICE_HAS_SENSOR.getMessage(),
  283 + StringUtils.isEmpty(entity.getAlias()) ? entity.getName() : entity.getAlias()));
  284 + }
  285 + }
264 } 286 }
265 - return tbDeviceIds; 287 + return list.stream().map(TkDeviceEntity::getTbDeviceId).collect(Collectors.toList());
266 } 288 }
267 289
268 @Override 290 @Override
@@ -378,7 +400,8 @@ public class TkDeviceServiceImpl extends AbstractBaseService<DeviceMapper, TkDev @@ -378,7 +400,8 @@ public class TkDeviceServiceImpl extends AbstractBaseService<DeviceMapper, TkDev
378 String convertConfigId = 400 String convertConfigId =
379 Optional.ofNullable(queryMap.get("convertConfigId")).map(Object::toString).orElse(null); 401 Optional.ofNullable(queryMap.get("convertConfigId")).map(Object::toString).orElse(null);
380 if (!StringUtils.isEmpty(organizationId)) { 402 if (!StringUtils.isEmpty(organizationId)) {
381 - List<String> queryOrganizationIds = organizationService.organizationAllIds(tenantId, organizationId); 403 + List<String> queryOrganizationIds =
  404 + organizationService.organizationAllIds(tenantId, organizationId);
382 queryMap.put("organizationIds", queryOrganizationIds); 405 queryMap.put("organizationIds", queryOrganizationIds);
383 } 406 }
384 // 用于数据流转已选,待选过滤============开始 407 // 用于数据流转已选,待选过滤============开始
@@ -413,8 +436,6 @@ public class TkDeviceServiceImpl extends AbstractBaseService<DeviceMapper, TkDev @@ -413,8 +436,6 @@ public class TkDeviceServiceImpl extends AbstractBaseService<DeviceMapper, TkDev
413 return new TkPageData<>(records, deviceIPage.getTotal()); 436 return new TkPageData<>(records, deviceIPage.getTotal());
414 } 437 }
415 438
416 -  
417 -  
418 @Override 439 @Override
419 public TkPageData<RelationDeviceDTO> pageRelation(Map<String, Object> queryMap) { 440 public TkPageData<RelationDeviceDTO> pageRelation(Map<String, Object> queryMap) {
420 IPage<TkDeviceEntity> page = getPage(queryMap, "last_online_time", false); 441 IPage<TkDeviceEntity> page = getPage(queryMap, "last_online_time", false);
@@ -636,8 +657,8 @@ public class TkDeviceServiceImpl extends AbstractBaseService<DeviceMapper, TkDev @@ -636,8 +657,8 @@ public class TkDeviceServiceImpl extends AbstractBaseService<DeviceMapper, TkDev
636 attribute.put("name", dto.getFunctionName()); 657 attribute.put("name", dto.getFunctionName());
637 attribute.put("identifier", dto.getIdentifier()); 658 attribute.put("identifier", dto.getIdentifier());
638 attribute.put("detail", functionJson); 659 attribute.put("detail", functionJson);
639 - attribute.put("accessMode",dto.getAccessMode());  
640 - attribute.put("extensionDesc",dto.getExtensionDesc()); 660 + attribute.put("accessMode", dto.getAccessMode());
  661 + attribute.put("extensionDesc", dto.getExtensionDesc());
641 attributes.add(attribute); 662 attributes.add(attribute);
642 } 663 }
643 } 664 }
@@ -662,7 +683,10 @@ public class TkDeviceServiceImpl extends AbstractBaseService<DeviceMapper, TkDev @@ -662,7 +683,10 @@ public class TkDeviceServiceImpl extends AbstractBaseService<DeviceMapper, TkDev
662 } 683 }
663 return baseMapper.findDeviceInfo(tenantId, tbDeviceId); 684 return baseMapper.findDeviceInfo(tenantId, tbDeviceId);
664 } 685 }
665 - @Cacheable(cacheNames = FastIotConstants.CacheConfigKey.SCENE_REACT, key = "{#tenantId, #organizationId, #projectId}") 686 +
  687 + @Cacheable(
  688 + cacheNames = FastIotConstants.CacheConfigKey.SCENE_REACT,
  689 + key = "{#tenantId, #organizationId, #projectId}")
666 @Override 690 @Override
667 public List<String> rpcDevices(String tenantId, String organizationId, String projectId) { 691 public List<String> rpcDevices(String tenantId, String organizationId, String projectId) {
668 List<String> orgIds = organizationService.organizationAllIds(tenantId, organizationId); 692 List<String> orgIds = organizationService.organizationAllIds(tenantId, organizationId);
@@ -38,7 +38,13 @@ public interface TkDeviceService extends BaseService<TkDeviceEntity> { @@ -38,7 +38,13 @@ public interface TkDeviceService extends BaseService<TkDeviceEntity> {
38 */ 38 */
39 boolean deviceNameUsed(String tenantId, String deviceName, String deviceId); 39 boolean deviceNameUsed(String tenantId, String deviceName, String deviceId);
40 40
41 - List<String> findTbDeviceId(String tenantId, Set<String> ids); 41 + /**
  42 + * 设备删除前的检查
  43 + * @param tenantId 租户ID
  44 + * @param ids 删除的设备ID集合
  45 + * @return TB的设备ID集合
  46 + */
  47 + List<String> findTbDeviceIdAndCheckForDelete(String tenantId, Set<String> ids);
42 48
43 /** 49 /**
44 * 通过设备类型和组织ID查询所有的设备 50 * 通过设备类型和组织ID查询所有的设备