Commit 44ecbd09cc18d5736fd01b8fa9e753b2809d3e64

Authored by 芯火源
1 parent 1075c6f7

fix(DEFECT-1299): 网关子设备标识符是否重复校验

必须确保网关对应的子设备的设备标识符的唯一性
@@ -4,6 +4,7 @@ import com.fasterxml.jackson.databind.JsonNode; @@ -4,6 +4,7 @@ import com.fasterxml.jackson.databind.JsonNode;
4 import com.fasterxml.jackson.databind.ObjectMapper; 4 import com.fasterxml.jackson.databind.ObjectMapper;
5 import com.fasterxml.jackson.databind.node.ObjectNode; 5 import com.fasterxml.jackson.databind.node.ObjectNode;
6 import io.swagger.annotations.Api; 6 import io.swagger.annotations.Api;
  7 +import io.swagger.annotations.ApiModelProperty;
7 import io.swagger.annotations.ApiOperation; 8 import io.swagger.annotations.ApiOperation;
8 import io.swagger.annotations.ApiParam; 9 import io.swagger.annotations.ApiParam;
9 import lombok.RequiredArgsConstructor; 10 import lombok.RequiredArgsConstructor;
@@ -84,6 +85,11 @@ public class TkDeviceController extends BaseController { @@ -84,6 +85,11 @@ public class TkDeviceController extends BaseController {
84 ErrorMessage.DEVICE_NOT_EXISTENCE_IN_TENANT.getMessage()); 85 ErrorMessage.DEVICE_NOT_EXISTENCE_IN_TENANT.getMessage());
85 } 86 }
86 } 87 }
  88 + String identifier = StringUtils.isBlank(deviceDTO.getCode())?deviceDTO.getName():deviceDTO.getCode();
  89 + String markResult =tkdeviceService.markExisted(getCurrentUser().getCurrentTenantId(), gatewayId,deviceDTO.getId(),identifier);
  90 + if(StringUtils.isNotEmpty(markResult)){
  91 + throw new TkDataValidationException(markResult);
  92 + }
87 93
88 /** 94 /**
89 * 子设备编辑业务逻辑: 设备地址码必须同时设置到附加信息字段内。 1、新增或编辑网关和直连设备 2、新增网关子设备 3、编辑网关子设备时,关联关系已存在(未切换网关) 95 * 子设备编辑业务逻辑: 设备地址码必须同时设置到附加信息字段内。 1、新增或编辑网关和直连设备 2、新增网关子设备 3、编辑网关子设备时,关联关系已存在(未切换网关)
@@ -494,7 +500,19 @@ public class TkDeviceController extends BaseController { @@ -494,7 +500,19 @@ public class TkDeviceController extends BaseController {
494 result.setMessage(str); 500 result.setMessage(str);
495 return result; 501 return result;
496 } 502 }
497 - 503 + @PreAuthorize("@check.checkPermissions({'TENANT_ADMIN','CUSTOMER_USER'},{})")
  504 + @GetMapping("exist")
  505 + @ApiOperation("设备标识符是否已经被使用")
  506 + public ResponseResult<Boolean> existed(
  507 + @ApiParam(value = "网关设备主键") @RequestParam(name="gateway",required = false) String gatewayId,
  508 + @ApiParam(value = "当前设备主键,编辑时使用") @RequestParam(name="devId",required = false) String devId,
  509 + @ApiParam(value = "设备标识符,例如:设备名称、地址码", required = true)@RequestParam("identifier") String identifier)
  510 + throws ThingsboardException {
  511 + String str = tkdeviceService.markExisted(getCurrentUser().getCurrentTenantId(),gatewayId,devId,identifier);
  512 + ResponseResult result = ResponseResult.success(StringUtils.isEmpty(str) ? true : false);
  513 + result.setMessage(str);
  514 + return result;
  515 + }
498 @GetMapping({"/attributes/{deviceProfileId}"}) 516 @GetMapping({"/attributes/{deviceProfileId}"})
499 @ApiOperation("获取设备的属性") 517 @ApiOperation("获取设备的属性")
500 public ResponseEntity<JsonNode> getDeviceAttributes( 518 public ResponseEntity<JsonNode> getDeviceAttributes(
@@ -100,6 +100,8 @@ public enum ErrorMessage { @@ -100,6 +100,8 @@ public enum ErrorMessage {
100 TASK_CENTER_IS_DISABLED(400076,"【%s】任务是禁用状态,不能执行"), 100 TASK_CENTER_IS_DISABLED(400076,"【%s】任务是禁用状态,不能执行"),
101 NAME_OR_IDENTIFIER_IS_EMPTY(400077,"【%s】的名称或标识符不能为空或空字符串"), 101 NAME_OR_IDENTIFIER_IS_EMPTY(400077,"【%s】的名称或标识符不能为空或空字符串"),
102 IDENTIFIER_ALREADY_EXISTS(400078,"标识符【%s】已经存在"), 102 IDENTIFIER_ALREADY_EXISTS(400078,"标识符【%s】已经存在"),
  103 + DEVICE_GATEWAY_NOT_EXTIED(400079,"网关设备【%s】不存在"),
  104 + DEVICE_IDENTIFIER_REPEATED(400079,"设备标识【%s】与设备【%s】重复"),
103 HAVE_NO_PERMISSION(500002,"没有修改权限"); 105 HAVE_NO_PERMISSION(500002,"没有修改权限");
104 private final int code; 106 private final int code;
105 private String message; 107 private String message;
@@ -758,4 +758,49 @@ public class TkDeviceServiceImpl extends AbstractBaseService<DeviceMapper, TkDev @@ -758,4 +758,49 @@ public class TkDeviceServiceImpl extends AbstractBaseService<DeviceMapper, TkDev
758 } 758 }
759 return result; 759 return result;
760 } 760 }
  761 +
  762 + @Override
  763 + public String markExisted(String tenantId,String gatewayId,String deviceId, String identifier) {
  764 + if(StringUtils.isNotBlank(deviceId)){//编辑设备时,未修改设备标识符
  765 + TkDeviceEntity self = baseMapper.selectOne(
  766 + new LambdaQueryWrapper<TkDeviceEntity>()
  767 + .eq(TkDeviceEntity::getTenantId, tenantId)
  768 + .eq(TkDeviceEntity::getId, deviceId));
  769 + if(self.getGatewayId().equals(gatewayId)
  770 + &&( self.getCode().equals(identifier) || self.getName().equals(identifier))){
  771 + return "";
  772 + }
  773 + }
  774 + TkDeviceEntity gateway =null;
  775 + if(StringUtils.isNotBlank(gatewayId)){
  776 + gateway = baseMapper.selectOne(
  777 + new LambdaQueryWrapper<TkDeviceEntity>()
  778 + .eq(TkDeviceEntity::getTenantId, tenantId)
  779 + .eq(TkDeviceEntity::getTbDeviceId, gatewayId));
  780 + if (gateway ==null ) {
  781 + return String.format(ErrorMessage.DEVICE_GATEWAY_NOT_EXTIED.getMessage(),gatewayId);
  782 + }
  783 + }
  784 + LambdaQueryWrapper<TkDeviceEntity> filter =new LambdaQueryWrapper<>();
  785 + filter.eq(TkDeviceEntity::getTenantId, tenantId);
  786 + DeviceProfileDTO profile=null;
  787 + if(gateway !=null){
  788 + filter.eq(TkDeviceEntity::getGatewayId, gatewayId);
  789 + profile =tkProfileMapper.selectDetail(tenantId,gateway.getProfileId());
  790 + }
  791 +
  792 + if(profile !=null && TransportTypeEnum.TCP.name().equals(profile.getTransportType())){
  793 + filter.eq(TkDeviceEntity::getCode, identifier);
  794 + }else{
  795 + filter.eq(TkDeviceEntity::getName, identifier);
  796 + }
  797 + List<TkDeviceEntity> self = baseMapper.selectList(filter);
  798 + if(self ==null || self.isEmpty()){
  799 + return "";
  800 + }else{
  801 + String names = String.join(",",self.stream().map(f->f.getName()).collect(Collectors.toList()));
  802 + return String.format(ErrorMessage.DEVICE_IDENTIFIER_REPEATED.getMessage(),identifier
  803 + ,names);
  804 + }
  805 + }
761 } 806 }
@@ -108,7 +108,16 @@ public interface TkDeviceService extends BaseService<TkDeviceEntity> { @@ -108,7 +108,16 @@ public interface TkDeviceService extends BaseService<TkDeviceEntity> {
108 * @return 场景联动ID 108 * @return 场景联动ID
109 */ 109 */
110 String otherUsing(String deviceId, String tenantId); 110 String otherUsing(String deviceId, String tenantId);
111 - 111 + /**
  112 + * 设备标识符是否已经被使用
  113 + *
  114 + * @param tenantId 租户ID
  115 + * @param gatewayId 网关设备主键
  116 + * @param deviceId 网关设备主键
  117 + * @param identifier 设备标识符,例如:设备名称、TCP子设备的地址码
  118 + * @return 场景联动ID
  119 + */
  120 + String markExisted(String tenantId,String gatewayId,String deviceId, String identifier);
112 /** 121 /**
113 * 主设备信息 122 * 主设备信息
114 * 123 *