Commit b38380d08ecb8e3e34e7706293bf9aed57c63dc1

Authored by xp.Huang
2 parents 72c89096 a3bdf4b9

Merge branch '20221203' into 'master'

refactor: 场景联动设备过滤条件添加产品

See merge request huang/thingsboard3.3.2!148
... ... @@ -475,8 +475,10 @@ public class TkDeviceController extends BaseController {
475 475 DeviceProfileId deviceProfileId =
476 476 new DeviceProfileId(UUID.fromString(deviceDTO.getProfileId()));
477 477
  478 + CustomerId customerId = StringUtils.isBlank(deviceDTO.getCustomerId())?null:new CustomerId(UUID.fromString(deviceDTO.getCustomerId()));
  479 +
478 480 tbDevice.setAdditionalInfo(additionalInfo);
479   - tbDevice.setCustomerId(null);
  481 + tbDevice.setCustomerId(customerId);
480 482 tbDevice.setDeviceProfileId(deviceProfileId);
481 483 tbDevice.setLabel(deviceDTO.getLabel());
482 484 tbDevice.setName(deviceDTO.getName());
... ...
... ... @@ -43,6 +43,7 @@ public class DeviceDTO extends TenantDTO {
43 43 @ApiModelProperty(value = "关联网关设备")
44 44 private String gatewayId;
45 45 private String gatewayName;
  46 + private String gatewayAlias;
46 47
47 48 @ApiModelProperty(value = "设备凭证")
48 49 private TkCredentialsDto deviceToken;
... ...
1 1 package org.thingsboard.server.common.data.yunteng.dto;
  2 +import com.fasterxml.jackson.annotation.JsonFormat;
  3 +import com.fasterxml.jackson.databind.annotation.JsonSerialize;
  4 +import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
2 5 import lombok.Data;
3 6 import org.thingsboard.server.common.data.yunteng.enums.DeviceState;
4 7
  8 +import java.time.LocalDateTime;
  9 +
5 10 @Data
6 11 public class RelationDeviceDTO {
7 12 private String tbDeviceId;
8 13 private String tbDeviceName;
  14 + private String alias;
9 15 private String label;
10 16 private DeviceState deviceState;
11   - private Long createdTime;
  17 +
  18 + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
  19 + @JsonSerialize(using = LocalDateTimeSerializer.class)
  20 + private LocalDateTime createdTime;
12 21 private Long lastOnlineTime;
13 22
14 23 public void setDeviceState(boolean deviceState) {
... ...
... ... @@ -5,12 +5,17 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
5 5 import lombok.RequiredArgsConstructor;
6 6 import org.springframework.stereotype.Service;
7 7 import org.thingsboard.server.common.data.yunteng.dto.DoActionDTO;
  8 +import org.thingsboard.server.common.data.yunteng.enums.DeviceTypeEnum;
  9 +import org.thingsboard.server.common.data.yunteng.enums.ScopeEnum;
  10 +import org.thingsboard.server.dao.yunteng.entities.TkDeviceEntity;
8 11 import org.thingsboard.server.dao.yunteng.entities.TkDoActionEntity;
9 12 import org.thingsboard.server.dao.yunteng.entities.TenantBaseEntity;
  13 +import org.thingsboard.server.dao.yunteng.mapper.DeviceMapper;
10 14 import org.thingsboard.server.dao.yunteng.mapper.DoActionMapper;
11 15 import org.thingsboard.server.dao.yunteng.service.AbstractBaseService;
12 16 import org.thingsboard.server.dao.yunteng.service.DoActionService;
13 17
  18 +import java.util.ArrayList;
14 19 import java.util.List;
15 20 import java.util.Set;
16 21 import java.util.stream.Collectors;
... ... @@ -20,13 +25,36 @@ import java.util.stream.Collectors;
20 25 @RequiredArgsConstructor
21 26 public class TkDoActionServiceImpl extends AbstractBaseService<DoActionMapper, TkDoActionEntity>
22 27 implements DoActionService {
  28 + private final DeviceMapper deviceMapper;
23 29 @Override
24   - public List<TkDoActionEntity> getActions(String sceneId) {
  30 + public List<TkDoActionEntity> getActionsByAll(String sceneId) {
25 31 LambdaQueryWrapper filter =
26   - new QueryWrapper<TkDoActionEntity>().lambda().eq(TkDoActionEntity::getSceneLinkageId, sceneId);
  32 + new LambdaQueryWrapper<TkDoActionEntity>().eq(TkDoActionEntity::getSceneLinkageId, sceneId).eq(TkDoActionEntity::getEntityType, ScopeEnum.ALL);
27 33 return baseMapper.selectList(filter);
28 34 }
29 35
  36 +
  37 + @Override
  38 + public List<TkDoActionEntity> getActionsByPart(String sceneId) {
  39 + LambdaQueryWrapper filter =
  40 + new LambdaQueryWrapper<TkDoActionEntity>().eq(TkDoActionEntity::getSceneLinkageId, sceneId).eq(TkDoActionEntity::getEntityType, ScopeEnum.PART);
  41 + List<TkDoActionEntity> source = baseMapper.selectList(filter);
  42 + return source.stream().map(t ->{
  43 + List<TkDeviceEntity> partDevices = deviceMapper.selectList(new LambdaQueryWrapper<TkDeviceEntity>().in(TkDeviceEntity::getTbDeviceId,t.getDeviceId()));
  44 + List<String> deviceId = new ArrayList<>();
  45 + for(TkDeviceEntity item : partDevices){
  46 + if(!DeviceTypeEnum.SENSOR.equals(item.getDeviceType())){
  47 + //网关子设备才需要重写deviceId字段
  48 + break;
  49 + }
  50 + deviceId.add(item.getGatewayId());
  51 + }
  52 + t.setDeviceId(deviceId);
  53 + return t;
  54 + }).collect(Collectors.toList());
  55 +
  56 + }
  57 +
30 58 @Override
31 59 public List<DoActionDTO> findDoActionByAlarmProfileIds(
32 60 String tenantId, Set<String> alarmProfileIds) {
... ...
... ... @@ -440,8 +440,7 @@ public class TkSceneLinkageServiceImpl extends AbstractBaseService<SceneLinkageM
440 440 String currentSceneId, String tenantId, String customerId, Integer state) {
441 441 List<TkSceneLinkageEntity> runningScenes =
442 442 baseMapper.selectList(
443   - new QueryWrapper<TkSceneLinkageEntity>()
444   - .lambda()
  443 + new LambdaQueryWrapper<TkSceneLinkageEntity>()
445 444 .eq(TkSceneLinkageEntity::getTenantId, tenantId)
446 445 .eq(TkSceneLinkageEntity::getStatus, FastIotConstants.StateValue.ENABLE));
447 446 Set<String> enableIds = new HashSet<>();
... ... @@ -468,17 +467,7 @@ public class TkSceneLinkageServiceImpl extends AbstractBaseService<SceneLinkageM
468 467
469 468 List<DeviceDTO> organizationDevices =
470 469 findDeviceList(self.getOrganizationId(), tenantId, customerId,new ArrayList<>());
471   - List<String> allDevices = new ArrayList<>();
472   - List<String> rpcDevices = new ArrayList<>();
473   - if(organizationDevices != null && !organizationDevices.isEmpty()){
474   - for (DeviceDTO item : organizationDevices) {
475   - allDevices.add(item.getTbDeviceId());
476   - DeviceTypeEnum deviceType = item.getDeviceType();
477   - if(!DeviceTypeEnum.SENSOR.equals(deviceType)){
478   - rpcDevices.add(item.getTbDeviceId());
479   - }
480   - }
481   - }
  470 +
482 471
483 472 Map<String, List<String>> matchedDevices = new HashMap<>();
484 473
... ... @@ -495,6 +484,7 @@ public class TkSceneLinkageServiceImpl extends AbstractBaseService<SceneLinkageM
495 484 String scenId = trigger.getSceneLinkageId();
496 485 List<String> devices = trigger.getEntityId();
497 486 if(currentSceneId.equals(scenId)){
  487 + List<String> allDevices = filterDevice(organizationDevices,trigger.getDeviceProfileId(),false);
498 488 if (ScopeEnum.ALL.equals(trigger.getEntityType()) ) {
499 489 devices = allDevices;
500 490 }else{
... ... @@ -516,7 +506,7 @@ public class TkSceneLinkageServiceImpl extends AbstractBaseService<SceneLinkageM
516 506 Executors.newScheduledThreadPool(1)
517 507 .schedule(
518 508 () -> {
519   - freshEntityIds(currentSceneId, allDevices,rpcDevices, triggers);
  509 + freshEntityIds(currentSceneId, organizationDevices, triggers);
520 510 },
521 511 1,
522 512 TimeUnit.SECONDS);
... ... @@ -528,51 +518,66 @@ public class TkSceneLinkageServiceImpl extends AbstractBaseService<SceneLinkageM
528 518 return JacksonUtil.convertValue(engineConfig, JsonNode.class);
529 519 }
530 520
  521 + private List<String> filterDevice(List<DeviceDTO> organizationDevices,String profileId,boolean rpc){
  522 + List<String> allDevices = new ArrayList<>();
  523 + if(organizationDevices != null && !organizationDevices.isEmpty()){
  524 + for (DeviceDTO item : organizationDevices) {
  525 + if(StringUtils.isBlank(item.getDeviceProfileId()) || !item.getDeviceProfileId().equals(profileId)){
  526 + continue;
  527 + }
  528 + DeviceTypeEnum deviceType = item.getDeviceType();
  529 + if(rpc && DeviceTypeEnum.SENSOR.equals(deviceType)){
  530 + allDevices.add(item.getGatewayId());
  531 + continue;
  532 + }
  533 + allDevices.add(item.getTbDeviceId());
  534 + }
  535 + }
  536 + return allDevices;
  537 + }
  538 +
531 539 /**
532 540 * 异步刷新场景联动的设备ID
533 541 *
534 542 * @param sceneId
535   - * @param allDevices
  543 + * @param organizationDevices
536 544 * @param triggers
537 545 */
538   - public void freshEntityIds(String sceneId, List<String> allDevices,List<String> rpcDevices, List<TkTriggerEntity> triggers) {
  546 + public void freshEntityIds(String sceneId, List<DeviceDTO> organizationDevices,List<TkTriggerEntity> triggers) {
539 547 triggers.forEach(
540 548 trigger -> {
541 549 if (ScopeEnum.ALL.equals(trigger.getEntityType())
542 550 && sceneId.equals(trigger.getSceneLinkageId())) {
543   - trigger.setEntityId(allDevices);
  551 + List<String> ids = filterDevice(organizationDevices,trigger.getDeviceProfileId(),false);
  552 + trigger.setEntityId(ids);
544 553 triggerMapper.updateById(trigger);
545 554 }
546 555 });
547 556
548 557 List<TkDoConditionEntity> conditions =
549 558 doConditionMapper.selectList(
550   - new QueryWrapper<TkDoConditionEntity>()
551   - .lambda()
  559 + new LambdaQueryWrapper<TkDoConditionEntity>()
552 560 .eq(TkDoConditionEntity::getSceneLinkageId, sceneId)
553 561 .eq(TkDoConditionEntity::getEntityType, ScopeEnum.ALL));
554 562 conditions.forEach(
555 563 item -> {
556 564 if (sceneId.equals(item.getSceneLinkageId())) {
557   - item.setEntityId(allDevices);
  565 + List<String> ids = filterDevice(organizationDevices,item.getDeviceProfileId(),false);
  566 + item.setEntityId(ids);
558 567 doConditionMapper.updateById(item);
559 568 }
560 569 });
561 570
562 571 List<TkDoActionEntity> actions =
563 572 doActionMapper.selectList(
564   - new QueryWrapper<TkDoActionEntity>()
565   - .lambda()
  573 + new LambdaQueryWrapper<TkDoActionEntity>()
566 574 .eq(TkDoActionEntity::getSceneLinkageId, sceneId)
567 575 .eq(TkDoActionEntity::getEntityType, ScopeEnum.ALL));
568 576 actions.forEach(
569 577 item -> {
570 578 if (sceneId.equals(item.getSceneLinkageId())) {
571   - if(ActionTypeEnum.DEVICE_OUT.equals(item.getOutTarget())){
572   - item.setDeviceId(rpcDevices);
573   - }else{
574   - item.setDeviceId(allDevices);
575   - }
  579 + List<String> ids = filterDevice(organizationDevices,item.getDeviceProfileId(),ActionTypeEnum.DEVICE_OUT.equals(item.getOutTarget())?true:false);
  580 + item.setDeviceId(ids);
576 581
577 582 doActionMapper.updateById(item);
578 583 }
... ...
... ... @@ -13,7 +13,8 @@ import java.util.Set;
13 13 */
14 14 public interface DoActionService extends BaseService<TkDoActionEntity>{
15 15
16   - List<TkDoActionEntity> getActions(String sceneId);
  16 + List<TkDoActionEntity> getActionsByAll(String sceneId);
  17 + List<TkDoActionEntity> getActionsByPart(String sceneId);
17 18
18 19 List<DoActionDTO> findDoActionByAlarmProfileIds(String tenantId, Set<String> alarmProfileIds);
19 20 }
... ...
... ... @@ -39,6 +39,7 @@
39 39 <result property="organizationId" column="organization_id"/>
40 40 <result property="gatewayId" column="gateway_id"/>
41 41 <result property="gatewayName" column="gateway_name"/>
  42 + <result property="gatewayAlias" column="gateway_alias"/>
42 43 <association property="deviceProfile"
43 44 javaType="org.thingsboard.server.common.data.yunteng.dto.DeviceProfileDTO">
44 45 <result property="name" column="profile_name"/>
... ... @@ -50,8 +51,9 @@
50 51 </association>
51 52 </resultMap>
52 53 <resultMap id="relationDeviceMap" type="org.thingsboard.server.common.data.yunteng.dto.RelationDeviceDTO">
53   - <result property="tbDeviceId" column="id"/>
  54 + <result property="tbDeviceId" column="tb_device_id"/>
54 55 <result property="tbDeviceName" column="name"/>
  56 + <result property="alias" column="alias"/>
55 57 <result property="label" column="label"/>
56 58 <result property="deviceState" column="status"/>
57 59 <result property="createdTime" column="created_time"/>
... ... @@ -71,7 +73,7 @@
71 73 </sql>
72 74 <sql id="detailColumns">
73 75 <include refid="pageColumns"/>
74   - ,ifd.gateway_id,idg.name gateway_name
  76 + ,ifd.gateway_id,idg.name gateway_name,idg.alias gateway_alias
75 77 </sql>
76 78 <sql id="pageColumns">
77 79 <include refid="basicColumns"/>
... ... @@ -103,6 +105,8 @@
103 105 ifd.name LIKE concat('%',#{queryMap.name}::TEXT,'%')
104 106 or
105 107 ifd.sn LIKE concat('%',#{queryMap.name}::TEXT,'%')
  108 + or
  109 + ifd.alias LIKE concat('%',#{queryMap.name}::TEXT,'%')
106 110 )
107 111 </if>
108 112 <if test="queryMap.deviceType !=null and queryMap.deviceType !=''">
... ... @@ -207,27 +211,26 @@
207 211 </select>
208 212 <select id="getRelationDevicePage" resultMap="relationDeviceMap">
209 213 SELECT
210   - de.id,
  214 + de.tb_device_id,
211 215 de.name,
  216 + de.alias,
212 217 de.label,
213   - de.created_time,
  218 + de.create_time as created_time,
214 219 A.bool_v AS status,
215 220 b.long_v AS last_online_time
216 221 FROM
217   - device de
218   - LEFT JOIN relation rt ON de."id" = rt.to_id
219   - LEFT JOIN attribute_kv A ON de."id" = A.entity_id
  222 + tk_device de
  223 + LEFT JOIN relation rt ON de.tb_device_id::uuid = rt.to_id
  224 + LEFT JOIN attribute_kv A ON de.tb_device_id::uuid = A.entity_id
220 225 AND A.entity_type = 'DEVICE'
221 226 AND A.attribute_key = 'active'
222   - LEFT JOIN attribute_kv b ON de."id" = b.entity_id
  227 + LEFT JOIN attribute_kv b ON de.tb_device_id::uuid = b.entity_id
223 228 AND b.entity_type = 'DEVICE'
224 229 AND b.attribute_key = 'lastActivityTime'
225 230 <where>
226 231 rt.from_id ::TEXT = #{queryMap.fromId}
227   - AND de.tenant_id ::TEXT = #{queryMap.tenantId}
228   - <if test="queryMap.customerId !=null and queryMap.customerId !=''">
229   - AND de.customer_id ::TEXT = #{queryMap.customerId}
230   - </if>
  232 + AND de.tenant_id = #{queryMap.tenantId}
  233 +
231 234 <if test="queryMap.name !=null and queryMap.name !=''">
232 235 AND de.name LIKE concat('%',#{queryMap.name}::TEXT,'%')
233 236 </if>
... ...
... ... @@ -97,7 +97,8 @@ class ReactState {
97 97 DoConditionService conditionService = SpringBeanUtils.getBean(DoConditionService.class);
98 98 this.conditions = conditionService.getConditions(reactId);
99 99 DoActionService actionService = SpringBeanUtils.getBean(DoActionService.class);
100   - this.actions = actionService.getActions(reactId);
  100 + this.actions = actionService.getActionsByAll(reactId);
  101 + this.actions.addAll(actionService.getActionsByPart(reactId));
101 102 for (TkDoActionEntity action : actions) {
102 103 /**动作中只有1个告警通知*/
103 104 if (ActionTypeEnum.MSG_NOTIFY.equals(action.getOutTarget())) {
... ... @@ -208,7 +209,8 @@ class ReactState {
208 209 if (alarm != null && alarm.getClearRule() != null) {
209 210 for (TriggerDTO rule : alarm.getClearRule()) {
210 211 if ((ScopeEnum.PART.equals(rule.getEntityType()) && !rule.getEntityId().contains(deviceId))
211   - || !alarmAction.getDeviceId().contains(deviceId)) {
  212 +// || !alarmAction.getDeviceId().contains(deviceId)
  213 + ) {
212 214 continue;
213 215 }
214 216
... ...