Commit 307ffa79c0ac2339f61dc60f6c0d94af57edd488

Authored by 云中非
1 parent c7235c2d

refactor: 组织可用设备接口优化

1、租户管理员只能查看未分配客户的设备
2、客户只能查看分配给自己的。
... ... @@ -11,11 +11,13 @@ import lombok.RequiredArgsConstructor;
11 11 import org.apache.commons.lang3.StringUtils;
12 12 import org.springframework.stereotype.Service;
13 13 import org.springframework.transaction.annotation.Transactional;
  14 +import org.thingsboard.server.common.data.id.EntityId;
14 15 import org.thingsboard.server.common.data.yunteng.constant.FastIotConstants;
15 16 import org.thingsboard.server.common.data.yunteng.core.exception.YtDataValidationException;
16 17 import org.thingsboard.server.common.data.yunteng.core.message.ErrorMessage;
17 18 import org.thingsboard.server.common.data.yunteng.dto.*;
18 19 import org.thingsboard.server.common.data.yunteng.enums.ActionTypeEnum;
  20 +import org.thingsboard.server.common.data.yunteng.enums.ScopeEnum;
19 21 import org.thingsboard.server.common.data.yunteng.enums.TriggerTypeEnum;
20 22 import org.thingsboard.server.common.data.yunteng.utils.JacksonUtil;
21 23 import org.thingsboard.server.common.data.yunteng.utils.ReflectUtils;
... ... @@ -47,7 +49,6 @@ public class SceneLinkageServiceImpl extends AbstractBaseService<SceneLinkageMap
47 49 private final DoConditionService doConditionService;
48 50 private final DoActionService doActionService;
49 51 private final UserMapper userMapper;
50   - private final UserOrganizationMappingService userOrganizationMappingService;
51 52
52 53 /**
53 54 * 增加场景联动,触发器可以多个,执行条件可以多个,执行动作可以多个
... ... @@ -57,7 +58,7 @@ public class SceneLinkageServiceImpl extends AbstractBaseService<SceneLinkageMap
57 58 */
58 59 @Override
59 60 @Transactional
60   - public SceneLinkageDTO saveSceneLinkage(SceneLinkageDTO sceneLinkageDTO, String tenantId,boolean tenantAdmin,String currentUserId) {
  61 + public SceneLinkageDTO saveSceneLinkage(SceneLinkageDTO sceneLinkageDTO, String tenantId,String currentUserId,String customerId) {
61 62 sceneLinkageDTO.setTenantId(tenantId);
62 63 // 第一步保存场景,获取场景ID
63 64 // 场景对象
... ... @@ -70,7 +71,7 @@ public class SceneLinkageServiceImpl extends AbstractBaseService<SceneLinkageMap
70 71 }
71 72
72 73 String organizationId = sceneLinkage.getOrganizationId();
73   - List<DeviceDTO> organizationDevices = findDeviceList(organizationId,tenantAdmin,tenantId,currentUserId);
  74 + List<DeviceDTO> organizationDevices = findDeviceList(organizationId,tenantId,customerId);
74 75
75 76 List<String> tbDeviceIds = new ArrayList<>();
76 77 for (DeviceDTO item : organizationDevices) {
... ... @@ -126,7 +127,7 @@ public class SceneLinkageServiceImpl extends AbstractBaseService<SceneLinkageMap
126 127 */
127 128 @Override
128 129 @Transactional
129   - public SceneLinkageDTO updateSceneLinkage(SceneLinkageDTO sceneLinkageDTO, String tenantId,boolean tenantAdmin ,String currentUserId) {
  130 + public SceneLinkageDTO updateSceneLinkage(SceneLinkageDTO sceneLinkageDTO, String tenantId,String currentUserId,String customerId) {
130 131 // 获取场景
131 132 SceneLinkage sceneLinkage = baseMapper.selectById(sceneLinkageDTO.getId());
132 133 if (sceneLinkage == null) {
... ... @@ -136,7 +137,7 @@ public class SceneLinkageServiceImpl extends AbstractBaseService<SceneLinkageMap
136 137 throw new YtDataValidationException("你不是此场景的创建者");
137 138 }
138 139 String organizationId = sceneLinkage.getOrganizationId();
139   - List<DeviceDTO> organizationDevices = findDeviceList(organizationId,tenantAdmin,tenantId,currentUserId);
  140 + List<DeviceDTO> organizationDevices = findDeviceList(organizationId,tenantId,customerId);
140 141
141 142 List<String> tbDeviceIds = new ArrayList<>();
142 143 for (DeviceDTO item : organizationDevices) {
... ... @@ -163,13 +164,23 @@ public class SceneLinkageServiceImpl extends AbstractBaseService<SceneLinkageMap
163 164 List<TriggerDTO> triggerDTOS = sceneLinkage.getTriggers();
164 165 if (triggerDTOS != null && !triggerDTOS.isEmpty()) {
165 166 for (TriggerDTO triggerDTO : triggerDTOS) {
166   - String deviceId = triggerDTO.getEntityId();
167 167 if (!TriggerTypeEnum.DEVICE_TRIGGER.equals(triggerDTO.getTriggerType())) {
168 168 continue;
169 169 }
170   - if (!tbDeviceIds.contains(deviceId)) {
171   - throw new YtDataValidationException(ErrorMessage.ORGANIZATION_DEVICE_NOT_MATCHED_IN_TRIGGER.getMessage());
  170 + List<String> deviceIds = triggerDTO.getEntityId();
  171 + if(ScopeEnum.PART.equals(triggerDTO.getEntityType())){
  172 + if(deviceIds ==null || deviceIds.isEmpty()){
  173 + throw new YtDataValidationException(ErrorMessage.DEVICE_LOSED.getMessage());
  174 + }else{
  175 + for(String item: deviceIds){
  176 + if (!tbDeviceIds.contains(item)) {
  177 + throw new YtDataValidationException(ErrorMessage.ORGANIZATION_DEVICE_NOT_MATCHED_IN_TRIGGER.getMessage());
  178 + }
  179 + }
  180 + }
172 181 }
  182 +
  183 +
173 184 }
174 185 } else {
175 186 return;
... ... @@ -203,13 +214,21 @@ public class SceneLinkageServiceImpl extends AbstractBaseService<SceneLinkageMap
203 214 private void updateDoAction(SceneLinkageDTO sceneLinkageDTO, List<String> tbDeviceIds) {
204 215 List<DoActionDTO> actionDTOS = sceneLinkageDTO.getDoActions();
205 216 if (actionDTOS != null && !actionDTOS.isEmpty()) {
206   - for (DoActionDTO item : actionDTOS) {
207   - String deviceId = item.getDeviceId();
208   - if (!ActionTypeEnum.DEVICE_OUT.equals(item.getOutTarget())) {
  217 + for (DoActionDTO action : actionDTOS) {
  218 + if (!ActionTypeEnum.DEVICE_OUT.equals(action.getOutTarget())) {
209 219 continue;
210 220 }
211   - if (!tbDeviceIds.contains(deviceId)) {
212   - throw new YtDataValidationException(ErrorMessage.ORGANIZATION_DEVICE_NOT_MATCHED_IN_ACTION.getMessage());
  221 + List<String> deviceIds = action.getDeviceId();
  222 + if(ScopeEnum.PART.equals(action.getEntityType())){
  223 + if(deviceIds ==null || deviceIds.isEmpty()){
  224 + throw new YtDataValidationException(ErrorMessage.DEVICE_LOSED.getMessage());
  225 + }else{
  226 + for(String item: deviceIds){
  227 + if (!tbDeviceIds.contains(item)) {
  228 + throw new YtDataValidationException(ErrorMessage.ORGANIZATION_DEVICE_NOT_MATCHED_IN_ACTION.getMessage());
  229 + }
  230 + }
  231 + }
213 232 }
214 233 }
215 234 }
... ... @@ -225,10 +244,12 @@ public class SceneLinkageServiceImpl extends AbstractBaseService<SceneLinkageMap
225 244 .map(doActionDTO -> {
226 245 doActionDTO.setTenantId(sceneLinkageDTO.getTenantId());
227 246 doActionDTO.setSceneLinkageId(sceneLinkageDTO.getId());
228   - ObjectNode doContext = JacksonUtil.newObjectNode();
229   - doContext.put("method","methodThingskit");
230   - doContext.put("params",doActionDTO.getDoContext());
231   - doActionDTO.setDoContext(doContext);
  247 + if(ActionTypeEnum.DEVICE_OUT.equals(doActionDTO.getOutTarget())){
  248 + ObjectNode doContext = JacksonUtil.newObjectNode();
  249 + doContext.put("method","methodThingskit");
  250 + doContext.put("params",doActionDTO.getDoContext());
  251 + doActionDTO.setDoContext(doContext);
  252 + }
232 253 return doActionDTO.getEntity(DoAction.class);
233 254 })
234 255 .collect(Collectors.toList());
... ... @@ -246,13 +267,21 @@ public class SceneLinkageServiceImpl extends AbstractBaseService<SceneLinkageMap
246 267 private void updateDoCondition(SceneLinkageDTO sceneLinkageDTO, List<String> tbDeviceIds) {
247 268 List<DoConditionDTO> conditionDTOS = sceneLinkageDTO.getDoConditions();
248 269 if (conditionDTOS != null && !conditionDTOS.isEmpty()) {
249   - for (DoConditionDTO item : conditionDTOS) {
250   - String deviceId = item.getEntityId();
251   - if (!TriggerTypeEnum.DEVICE_TRIGGER.equals(item.getTriggerType())) {
  270 + for (DoConditionDTO condition : conditionDTOS) {
  271 + if (!ActionTypeEnum.DEVICE_OUT.equals(condition.getTriggerType())) {
252 272 continue;
253 273 }
254   - if (!tbDeviceIds.contains(deviceId)) {
255   - throw new YtDataValidationException(ErrorMessage.ORGANIZATION_DEVICE_NOT_MATCHED_IN_CONDITION.getMessage());
  274 + List<String> deviceIds = condition.getEntityId();
  275 + if(ScopeEnum.PART.equals(condition.getEntityType())){
  276 + if(deviceIds ==null || deviceIds.isEmpty()){
  277 + throw new YtDataValidationException(ErrorMessage.DEVICE_LOSED.getMessage());
  278 + }else{
  279 + for(String item: deviceIds){
  280 + if (!tbDeviceIds.contains(item)) {
  281 + throw new YtDataValidationException(ErrorMessage.ORGANIZATION_DEVICE_NOT_MATCHED_IN_ACTION.getMessage());
  282 + }
  283 + }
  284 + }
256 285 }
257 286 }
258 287 }
... ... @@ -340,63 +369,55 @@ public class SceneLinkageServiceImpl extends AbstractBaseService<SceneLinkageMap
340 369
341 370 /**
342 371 * @param organizationId 组织ID
343   - * @param isTenantAdmin true租户管理员 false客户
344 372 * @param tenantId 租户ID
345   - * @param currentUserId 当前用户ID
  373 + * @param customerId 客户ID
346 374 * @return 设备集合
347 375 */
348 376 @Override
349 377 public List<DeviceDTO> findDeviceList(
350   - String organizationId, boolean isTenantAdmin, String tenantId, String currentUserId) {
351   - List<String> organizationIds = new ArrayList<>();
352   - organizationIds.add(organizationId);
  378 + String organizationId, String tenantId, String customerId) {
  379 + List<String> organizationFilter = new ArrayList<>();
  380 + organizationFilter.add(organizationId);
353 381 // 查询该组织的所有子类
354   - List<String> ids =
355   - organizationMapper.findOrganizationTreeList(tenantId, organizationIds).stream()
  382 + List<String> orgIds =
  383 + organizationMapper.findOrganizationTreeList(tenantId, organizationFilter).stream()
356 384 .map(organization -> organization.getId())
357 385 .collect(Collectors.toList());
358 386 // 拿到当前组织ids所包含的设备集合
359   - if(ids.isEmpty()){
  387 + if(orgIds.isEmpty()){
360 388 throw new YtDataValidationException(ErrorMessage.ORGANIZATION_NOT_EXTIED.getMessage());
361 389 }
362   - List<YtDevice> deviceList =
  390 + List<YtDevice> orgDevices =
363 391 deviceMapper.selectList(
364   - new QueryWrapper<YtDevice>().lambda().in(YtDevice::getOrganizationId, ids));
365   - List<DeviceDTO> deviceDTOList =
366   - deviceList.stream()
367   - .map(device -> device.getDTO(DeviceDTO.class))
368   - .collect(Collectors.toList());
  392 + new QueryWrapper<YtDevice>().lambda().in(YtDevice::getOrganizationId, orgIds));
369 393
370   - List<DeviceDTO> result = new ArrayList<>();
371   - if (!isTenantAdmin) {
372   - // 查找分配给客户的设备
373   - List<String> list =
374   - deviceMapper.findDeviceIdsByCustomerId(userMapper.findUserCustomerIdById(currentUserId));
375   - list.forEach(
376   - id -> {
377   - for (DeviceDTO dto : deviceDTOList) {
378   - if (dto.getTbDeviceId().equals(id)) {
379   - result.add(dto);
380   - break;
381   - }
382   - }
383   - });
384   - } else {
385   - return deviceDTOList;
  394 +
  395 +
  396 +
  397 + List<String> customerDevices = deviceMapper.findDeviceIdsByCustomerId(customerId);
  398 + if(customerDevices ==null || customerDevices.isEmpty()){
  399 + return null;
386 400 }
  401 + List<DeviceDTO> result =orgDevices.stream()
  402 + .filter(f -> customerDevices.contains(f.getTbDeviceId()))
  403 + .map(device -> device.getDTO(DeviceDTO.class))
  404 + .collect(Collectors.toList());
  405 +
  406 +
387 407 return result;
388 408 }
389 409
390 410 /**
391 411 * 场景联动节点配置信息
392 412 *
393   - * @param sceneId 场景联动主键
394   - * @param tenantId 租户主键
  413 + * @param currentSceneId 场景联动主键
  414 + * @param tenantId 租户主键
  415 + * @param customerId 客户主键
395 416 * @param state 是否禁用场景联动,true标识禁用,false标识启用。
396 417 * @return
397 418 */
398 419 @Override
399   - public JsonNode getRuleNodeConfig(String sceneId, String tenantId, Integer state) {
  420 + public JsonNode getRuleNodeConfig(String currentSceneId, String tenantId,String customerId, Integer state) {
400 421 String ruleTyp = "org.thingsboard.rule.engine.filter.TbSceneReactNode";
401 422 List<SceneLinkage> runningScenes = baseMapper.selectList(
402 423 new QueryWrapper<SceneLinkage>()
... ... @@ -405,50 +426,84 @@ public class SceneLinkageServiceImpl extends AbstractBaseService<SceneLinkageMap
405 426 .eq(SceneLinkage::getStatus, FastIotConstants.StateValue.ENABLE)
406 427 );
407 428 Set<String> enableIds = new HashSet<>();
408   - enableIds.add(sceneId);
  429 + enableIds.add(currentSceneId);
409 430 for (SceneLinkage item : runningScenes) {
410 431 enableIds.add(item.getId());
411 432 }
412 433 if (state == FastIotConstants.StateValue.DISABLE) {
413   - enableIds.remove(sceneId);
  434 + enableIds.remove(currentSceneId);
414 435 }
415 436
416 437 if(enableIds.size() <= 0){
417 438 return null;
418 439 }
419   - List<Trigger> triggers = triggerMapper.selectList(
  440 +
  441 + Map<String, List<String>> maps = new HashMap<>();
  442 +
  443 + List<Trigger> partTriggers = triggerMapper.selectList(
420 444 new QueryWrapper<Trigger>()
421 445 .lambda()
422 446 .eq(Trigger::getTenantId, tenantId)
423 447 .eq(Trigger::getTriggerType, TriggerTypeEnum.DEVICE_TRIGGER)
  448 + .eq(Trigger::getEntityType, ScopeEnum.PART)
424 449 .in(Trigger::getSceneLinkageId, enableIds)
425 450 );
  451 + Set<String> exceptedSeneIds = new HashSet<>();
  452 + for (Trigger item : partTriggers) {
  453 + String scenId = item.getSceneLinkageId();
  454 + exceptedSeneIds.add(scenId);
  455 + deviceSceneMap(maps, item.getEntityId(),scenId );
  456 + }
426 457
427   - Map<String, List<String>> devices = new HashMap<>();
428   - for (Trigger item : triggers) {
429   - String deviceId = item.getEntityId();
430   - List<String> scenes = devices.computeIfAbsent(deviceId, k -> new ArrayList<String>());
431   - String triggerScenId = item.getSceneLinkageId();
432   - if (!scenes.contains(triggerScenId)) {
433   - scenes.add(triggerScenId);
434   - }
435   - if (scenes.isEmpty()) {
436   - devices.remove(deviceId);
437   - } else {
438   - devices.put(deviceId, scenes);
  458 + enableIds.removeAll(exceptedSeneIds);
  459 + List<SceneLinkage> allTriggers = sceneLinkageMapper.selectList(
  460 + new QueryWrapper<SceneLinkage>()
  461 + .lambda()
  462 + .eq(SceneLinkage::getTenantId, tenantId)
  463 + .in(SceneLinkage::getId, enableIds)
  464 + );
  465 + for(SceneLinkage scene:allTriggers){
  466 + List<DeviceDTO> organizationDevices = findDeviceList(scene.getOrganizationId(),tenantId,customerId);
  467 + List<String> devices = new ArrayList<>();
  468 + for(DeviceDTO item:organizationDevices){
  469 + devices.add(item.getTbDeviceId());
439 470 }
  471 + deviceSceneMap(maps, devices,scene.getId() );
440 472 }
441   - if (devices.isEmpty()) {
  473 +
  474 +
  475 +
  476 + if (maps.isEmpty()) {
442 477 return null;
443 478 }
444 479
445 480 Map<String, Map> engineConfig = new HashMap<>();
446   - engineConfig.put("scenes", devices);
  481 + engineConfig.put("scenes", maps);
447 482
448 483
449 484 return JacksonUtil.convertValue(engineConfig, JsonNode.class);
450 485 }
451 486
  487 + /**
  488 + * 设备与场景联动的映射集合
  489 + * @param resultMap 缓存设备和场景联动映射结果的集合
  490 + * @param devices 设备主键集合
  491 + * @param scenId 场景联动主键
  492 + */
  493 + private void deviceSceneMap(Map<String, List<String>> resultMap, List<String> devices, String scenId) {
  494 + for(String deviceId: devices){
  495 + List<String> scenes = resultMap.computeIfAbsent(deviceId, k -> new ArrayList<String>());
  496 + if (!scenes.contains(scenId)) {
  497 + scenes.add(scenId);
  498 + }
  499 + if (scenes.isEmpty()) {
  500 + resultMap.remove(deviceId);
  501 + } else {
  502 + resultMap.put(deviceId, scenes);
  503 + }
  504 + }
  505 + }
  506 +
452 507 private List<String> getQueryOrganizationIds(String tenantId, List<String> organizationIds) {
453 508 // 查询该组织的所有子类
454 509 List<OrganizationDTO> organizationDTOS =
... ...
... ... @@ -20,11 +20,11 @@ public interface SceneLinkageService extends BaseService<SceneLinkage>{
20 20 * 新增场景联动
21 21 * @param sceneLinkageDTO 场景联动信息
22 22 * @param tenantId 租户主键
23   - * @param tenantAdmin 当前用户是否租户管理员
24 23 * @param currentUserId 当前登录用户主键
  24 + * @param customerId 客户ID
25 25 * @return sceneLinkageDTO
26 26 */
27   - SceneLinkageDTO saveSceneLinkage(SceneLinkageDTO sceneLinkageDTO, String tenantId,boolean tenantAdmin,String currentUserId);
  27 + SceneLinkageDTO saveSceneLinkage(SceneLinkageDTO sceneLinkageDTO, String tenantId,String currentUserId,String customerId);
28 28
29 29 /**
30 30 * 删除场景联动
... ... @@ -37,11 +37,11 @@ public interface SceneLinkageService extends BaseService<SceneLinkage>{
37 37 * 修改场景联动
38 38 * @param sceneLinkageDTO 场景联动信息
39 39 * @param tenantId 租户主键
40   - * @param tenantAdmin 当前用户是否租户管理员
41 40 * @param currentUserId 当前登录用户主键
  41 + * @param customerId 客户ID
42 42 * @return
43 43 */
44   - SceneLinkageDTO updateSceneLinkage(SceneLinkageDTO sceneLinkageDTO,String tenantId,boolean tenantAdmin,String currentUserId);
  44 + SceneLinkageDTO updateSceneLinkage(SceneLinkageDTO sceneLinkageDTO,String tenantId,String currentUserId,String customerId);
45 45
46 46 /**
47 47 * 分页查询
... ... @@ -69,20 +69,20 @@ public interface SceneLinkageService extends BaseService<SceneLinkage>{
69 69 /**
70 70 * 通过组织id查询设备集合
71 71 * @param organizationId 组织ID
72   - * @param isTenantAdmin true租户管理员 false客户
73   - * @param tenantId 租户ID
74   - * @param currentUserId 当前用户ID
  72 + * @param tenantId 租户ID
  73 + * @param customerId 客户ID
75 74 * @return
76 75 */
77   - List<DeviceDTO> findDeviceList(String organizationId,boolean isTenantAdmin,String tenantId,String currentUserId);
  76 + List<DeviceDTO> findDeviceList(String organizationId,String tenantId,String customerId);
78 77
79 78 /**
80 79 * 获取租户的场景联动节点配置信息
81 80 * @param sceneId 场景联动主键
82 81 * @param tenantId 租户主键
  82 + * @param customerId 客户主键
83 83 * @param state 是否启动
84 84 * @return
85 85 */
86   - JsonNode getRuleNodeConfig(String sceneId,String tenantId,Integer state);
  86 + JsonNode getRuleNodeConfig(String sceneId,String tenantId,String customerId,Integer state);
87 87
88 88 }
... ...