Commit 102e039bfd88c829cf8e455b3f88fc8bda692979

Authored by 芯火源
2 parents 11e7ab3d e6b8a885

Merge branch 'master' into 20230411

# Conflicts:
#	application/src/main/java/org/thingsboard/server/controller/BaseController.java
#	application/src/main/java/org/thingsboard/server/controller/yunteng/TkDataViewController.java
#	common/data/src/main/java/org/thingsboard/server/common/data/yunteng/dto/TkDataViewDTO.java
#	common/transport/tcp/src/main/java/org/thingsboard/server/transport/tcp/TcpTransportHandler.java
#	dao/src/main/java/org/thingsboard/server/dao/yunteng/entities/TkDataViewEntity.java
#	dao/src/main/java/org/thingsboard/server/dao/yunteng/impl/TkDataViewServiceImpl.java
#	dao/src/main/java/org/thingsboard/server/dao/yunteng/service/TkDataViewService.java
Showing 53 changed files with 1918 additions and 410 deletions
@@ -57,8 +57,11 @@ import org.thingsboard.server.common.data.rule.RuleNode; @@ -57,8 +57,11 @@ import org.thingsboard.server.common.data.rule.RuleNode;
57 import org.thingsboard.server.common.data.widget.WidgetTypeDetails; 57 import org.thingsboard.server.common.data.widget.WidgetTypeDetails;
58 import org.thingsboard.server.common.data.widget.WidgetsBundle; 58 import org.thingsboard.server.common.data.widget.WidgetsBundle;
59 import org.thingsboard.server.common.data.yunteng.constant.FastIotConstants; 59 import org.thingsboard.server.common.data.yunteng.constant.FastIotConstants;
  60 +import org.thingsboard.server.common.data.yunteng.core.cache.CacheUtils;
60 import org.thingsboard.server.common.data.yunteng.core.exception.TkDataValidationException; 61 import org.thingsboard.server.common.data.yunteng.core.exception.TkDataValidationException;
61 import org.thingsboard.server.common.data.yunteng.core.message.ErrorMessage; 62 import org.thingsboard.server.common.data.yunteng.core.message.ErrorMessage;
  63 +import org.thingsboard.server.common.data.yunteng.dto.PublicCustomerDTO;
  64 +import org.thingsboard.server.common.data.yunteng.enums.ViewType;
62 import org.thingsboard.server.common.data.yunteng.enums.TkScriptFunctionType; 65 import org.thingsboard.server.common.data.yunteng.enums.TkScriptFunctionType;
63 import org.thingsboard.server.dao.asset.AssetService; 66 import org.thingsboard.server.dao.asset.AssetService;
64 import org.thingsboard.server.dao.attributes.AttributesService; 67 import org.thingsboard.server.dao.attributes.AttributesService;
@@ -243,6 +246,10 @@ public abstract class BaseController { @@ -243,6 +246,10 @@ public abstract class BaseController {
243 @Getter 246 @Getter
244 protected boolean edgesEnabled; 247 protected boolean edgesEnabled;
245 248
  249 + //thingskit
  250 + @Autowired
  251 + private CacheUtils cacheUtils;
  252 +
246 @ExceptionHandler(ThingsboardException.class) 253 @ExceptionHandler(ThingsboardException.class)
247 public void handleThingsboardException(ThingsboardException ex, HttpServletResponse response) { 254 public void handleThingsboardException(ThingsboardException ex, HttpServletResponse response) {
248 errorResponseHandler.handle(ex, response); 255 errorResponseHandler.handle(ex, response);
@@ -888,9 +895,9 @@ public abstract class BaseController { @@ -888,9 +895,9 @@ public abstract class BaseController {
888 * 构建设备配置的配置数据 895 * 构建设备配置的配置数据
889 * @param transportType 产品的通信协议 896 * @param transportType 产品的通信协议
890 * @param deviceProfileData 空的设备配置数据 897 * @param deviceProfileData 空的设备配置数据
891 - * @return 898 + * @param scriptText 自定义数据协议的解析脚本
892 */ 899 */
893 - protected DeviceProfileData buildDeviceProfileData(String transportType,DeviceProfileData deviceProfileData) { 900 + protected DeviceProfileData buildDeviceProfileData(String transportType,DeviceProfileData deviceProfileData,String scriptText) {
894 if(null == deviceProfileData){ 901 if(null == deviceProfileData){
895 deviceProfileData = new DeviceProfileData(); 902 deviceProfileData = new DeviceProfileData();
896 } 903 }
@@ -900,6 +907,10 @@ public abstract class BaseController { @@ -900,6 +907,10 @@ public abstract class BaseController {
900 // 传输类型默认都是Default 907 // 传输类型默认都是Default
901 if(transportType ==null || DeviceTransportType.DEFAULT.name().equals(transportType)){ 908 if(transportType ==null || DeviceTransportType.DEFAULT.name().equals(transportType)){
902 deviceProfileData.setTransportConfiguration(new DefaultDeviceProfileTransportConfiguration()); 909 deviceProfileData.setTransportConfiguration(new DefaultDeviceProfileTransportConfiguration());
  910 + }else if(DeviceTransportType.TCP.name().equals(transportType)){
  911 + TkTcpDeviceProfileTransportConfiguration tcpDeviceProfileTransportConfiguration = (TkTcpDeviceProfileTransportConfiguration) deviceProfileData.getTransportConfiguration();
  912 + tcpDeviceProfileTransportConfiguration.setScriptText(scriptText);
  913 + deviceProfileData.setTransportConfiguration(tcpDeviceProfileTransportConfiguration);
903 }else{ 914 }else{
904 deviceProfileData.setTransportConfiguration(deviceProfileData.getTransportConfiguration()); 915 deviceProfileData.setTransportConfiguration(deviceProfileData.getTransportConfiguration());
905 } 916 }
@@ -949,4 +960,27 @@ public abstract class BaseController { @@ -949,4 +960,27 @@ public abstract class BaseController {
949 getTenantId(), savedDeviceProfile.getId(), EdgeEventActionType.UPDATED); 960 getTenantId(), savedDeviceProfile.getId(), EdgeEventActionType.UPDATED);
950 return savedDeviceProfile; 961 return savedDeviceProfile;
951 } 962 }
  963 +
  964 + /**
  965 + * 获取租户的公共ID并设置缓存
  966 + * @param tenantId 租户ID
  967 + * @return 公共ID
  968 + */
  969 + private String findPublicCustomerId(TenantId tenantId){
  970 + validateId(tenantId, INCORRECT_TENANT_ID + tenantId);
  971 + String cacheKey =
  972 + FastIotConstants.CacheConfigKey.PUBLIC_ID + tenantId.getId().toString();
  973 + Optional<String> publicId = cacheUtils.get(cacheKey);
  974 + return publicId.orElseGet(
  975 + () -> Optional.ofNullable(customerService.findOrCreatePublicCustomer(tenantId)).
  976 + map(customer -> customer.getId().getId().toString()).orElse(null));
  977 + }
  978 +
  979 + protected void setPublicCustomerIdToCache(PublicCustomerDTO dto) throws ThingsboardException {
  980 + String publicCustomerId = findPublicCustomerId(getTenantId());
  981 + if (Objects.equals(dto.getViewType(), ViewType.PUBLIC_VIEW)
  982 + && !StringUtils.isEmpty(publicCustomerId)) {
  983 + dto.setPublicId(publicCustomerId);
  984 + }
  985 + }
952 } 986 }
@@ -8,10 +8,13 @@ import org.springframework.http.ResponseEntity; @@ -8,10 +8,13 @@ import org.springframework.http.ResponseEntity;
8 import org.springframework.security.access.prepost.PreAuthorize; 8 import org.springframework.security.access.prepost.PreAuthorize;
9 import org.springframework.validation.annotation.Validated; 9 import org.springframework.validation.annotation.Validated;
10 import org.springframework.web.bind.annotation.*; 10 import org.springframework.web.bind.annotation.*;
  11 +import org.thingsboard.server.common.data.Customer;
11 import org.thingsboard.server.common.data.exception.ThingsboardException; 12 import org.thingsboard.server.common.data.exception.ThingsboardException;
12 import org.thingsboard.server.common.data.yunteng.common.AddGroup; 13 import org.thingsboard.server.common.data.yunteng.common.AddGroup;
13 import org.thingsboard.server.common.data.yunteng.common.DeleteGroup; 14 import org.thingsboard.server.common.data.yunteng.common.DeleteGroup;
14 import org.thingsboard.server.common.data.yunteng.common.UpdateGroup; 15 import org.thingsboard.server.common.data.yunteng.common.UpdateGroup;
  16 +import org.thingsboard.server.common.data.yunteng.core.exception.TkDataValidationException;
  17 +import org.thingsboard.server.common.data.yunteng.core.message.ErrorMessage;
15 import org.thingsboard.server.common.data.yunteng.dto.ConfigurationCenterDTO; 18 import org.thingsboard.server.common.data.yunteng.dto.ConfigurationCenterDTO;
16 import org.thingsboard.server.common.data.yunteng.dto.DeleteDTO; 19 import org.thingsboard.server.common.data.yunteng.dto.DeleteDTO;
17 import org.thingsboard.server.common.data.yunteng.dto.request.ConfigurationContentInfoDTO; 20 import org.thingsboard.server.common.data.yunteng.dto.request.ConfigurationContentInfoDTO;
@@ -31,7 +34,7 @@ import static org.thingsboard.server.common.data.yunteng.constant.QueryConstant. @@ -31,7 +34,7 @@ import static org.thingsboard.server.common.data.yunteng.constant.QueryConstant.
31 @PreAuthorize("@check.checkPermissions({'TENANT_ADMIN','CUSTOMER_USER'},{})") 34 @PreAuthorize("@check.checkPermissions({'TENANT_ADMIN','CUSTOMER_USER'},{})")
32 public class TkConfigurationCenterController extends BaseController { 35 public class TkConfigurationCenterController extends BaseController {
33 36
34 - private final TkConfigurationCenterService ytConfigurationCenterService; 37 + private final TkConfigurationCenterService tkConfigurationCenterService;
35 38
36 @GetMapping(params = {PAGE_SIZE, PAGE}) 39 @GetMapping(params = {PAGE_SIZE, PAGE})
37 @ApiOperation("分页") 40 @ApiOperation("分页")
@@ -62,8 +65,15 @@ public class TkConfigurationCenterController extends BaseController { @@ -62,8 +65,15 @@ public class TkConfigurationCenterController extends BaseController {
62 if (null != orderType) { 65 if (null != orderType) {
63 queryMap.put(ORDER_TYPE, orderType.name()); 66 queryMap.put(ORDER_TYPE, orderType.name());
64 } 67 }
65 - queryMap.put("userId",getCurrentUser().getCurrentUserId());  
66 - return ytConfigurationCenterService.page(queryMap, getCurrentUser().isTenantAdmin()); 68 + queryMap.put("userId", getCurrentUser().getCurrentUserId());
  69 + TkPageData<ConfigurationCenterDTO> pageData =
  70 + tkConfigurationCenterService.page(queryMap, getCurrentUser().isTenantAdmin());
  71 + if (!pageData.getItems().isEmpty()) {
  72 + for (ConfigurationCenterDTO dto : pageData.getItems()) {
  73 + setPublicCustomerIdToCache(dto);
  74 + }
  75 + }
  76 + return pageData;
67 } 77 }
68 78
69 @PostMapping 79 @PostMapping
@@ -75,7 +85,7 @@ public class TkConfigurationCenterController extends BaseController { @@ -75,7 +85,7 @@ public class TkConfigurationCenterController extends BaseController {
75 throws ThingsboardException { 85 throws ThingsboardException {
76 configurationCenterDTO.setTenantId(getCurrentUser().getCurrentTenantId()); 86 configurationCenterDTO.setTenantId(getCurrentUser().getCurrentTenantId());
77 return ResponseEntity.ok( 87 return ResponseEntity.ok(
78 - ytConfigurationCenterService.saveConfiguration(configurationCenterDTO)); 88 + tkConfigurationCenterService.saveConfiguration(configurationCenterDTO));
79 } 89 }
80 90
81 @PutMapping 91 @PutMapping
@@ -87,7 +97,7 @@ public class TkConfigurationCenterController extends BaseController { @@ -87,7 +97,7 @@ public class TkConfigurationCenterController extends BaseController {
87 throws ThingsboardException { 97 throws ThingsboardException {
88 configurationCenterDTO.setTenantId(getCurrentUser().getCurrentTenantId()); 98 configurationCenterDTO.setTenantId(getCurrentUser().getCurrentTenantId());
89 return ResponseEntity.ok( 99 return ResponseEntity.ok(
90 - ytConfigurationCenterService.updateConfiguration(configurationCenterDTO)); 100 + tkConfigurationCenterService.updateConfiguration(configurationCenterDTO));
91 } 101 }
92 102
93 @DeleteMapping 103 @DeleteMapping
@@ -98,17 +108,34 @@ public class TkConfigurationCenterController extends BaseController { @@ -98,17 +108,34 @@ public class TkConfigurationCenterController extends BaseController {
98 @Validated({DeleteGroup.class}) @RequestBody DeleteDTO deleteDTO) 108 @Validated({DeleteGroup.class}) @RequestBody DeleteDTO deleteDTO)
99 throws ThingsboardException { 109 throws ThingsboardException {
100 deleteDTO.setTenantId(getCurrentUser().getCurrentTenantId()); 110 deleteDTO.setTenantId(getCurrentUser().getCurrentTenantId());
101 - return ResponseEntity.ok(ytConfigurationCenterService.deleteConfigurationCenter(deleteDTO)); 111 + return ResponseEntity.ok(tkConfigurationCenterService.deleteConfigurationCenter(deleteDTO));
102 } 112 }
103 113
104 @GetMapping("/get_configuration_info/{id}") 114 @GetMapping("/get_configuration_info/{id}")
105 @ApiOperation("获取组态信息") 115 @ApiOperation("获取组态信息")
106 @PreAuthorize( 116 @PreAuthorize(
107 - "@check.checkPermissions({'TENANT_ADMIN','CUSTOMER_USER'},{'api:yt:configuration:center:get_configuration_info:design','api:yt:configuration:center:get_configuration_info:preview'})") 117 + "@check.checkPermissions({'TENANT_ADMIN','CUSTOMER_USER'},{'api:yt:configuration:center:get_configuration_info:design'"
  118 + + ",'api:yt:configuration:center:get_configuration_info:preview'})")
108 public ResponseEntity<ConfigurationContentInfoDTO> getConfigurationInfos( 119 public ResponseEntity<ConfigurationContentInfoDTO> getConfigurationInfos(
109 @PathVariable("id") String id) throws ThingsboardException { 120 @PathVariable("id") String id) throws ThingsboardException {
110 return ResponseEntity.ok( 121 return ResponseEntity.ok(
111 - ytConfigurationCenterService.getConfigurationInfos( 122 + tkConfigurationCenterService.getConfigurationInfos(
112 id, getCurrentUser().getCurrentTenantId())); 123 id, getCurrentUser().getCurrentTenantId()));
113 } 124 }
  125 +
  126 + @PostMapping("share/{id}")
  127 + @ApiOperation("分享")
  128 + @PreAuthorize("@check.checkPermissions({'TENANT_ADMIN'},{'api:yt:configuration:center:share'})")
  129 + public ResponseEntity<Boolean> share(
  130 + @PathVariable("id") String id,
  131 + @RequestParam(value = "accessCredentials", required = false) String accessCredentials,
  132 + @RequestParam(value = "isShare") boolean isShare)
  133 + throws ThingsboardException {
  134 + if (StringUtils.isEmpty(id)) {
  135 + throw new TkDataValidationException(ErrorMessage.INVALID_PARAMETER.getMessage());
  136 + }
  137 + return ResponseEntity.ok(
  138 + tkConfigurationCenterService.shareOrMonopolyConfigurationCenter(
  139 + isShare, id, accessCredentials, getCurrentUser().getCurrentTenantId()));
  140 + }
114 } 141 }
@@ -5,6 +5,7 @@ import io.swagger.annotations.ApiOperation; @@ -5,6 +5,7 @@ import io.swagger.annotations.ApiOperation;
5 import lombok.RequiredArgsConstructor; 5 import lombok.RequiredArgsConstructor;
6 import org.apache.commons.lang3.StringUtils; 6 import org.apache.commons.lang3.StringUtils;
7 import org.quartz.SchedulerException; 7 import org.quartz.SchedulerException;
  8 +import org.springframework.http.ResponseEntity;
8 import org.springframework.security.access.prepost.PreAuthorize; 9 import org.springframework.security.access.prepost.PreAuthorize;
9 import org.springframework.validation.annotation.Validated; 10 import org.springframework.validation.annotation.Validated;
10 import org.springframework.web.bind.annotation.*; 11 import org.springframework.web.bind.annotation.*;
@@ -23,9 +24,7 @@ import org.thingsboard.server.common.data.yunteng.utils.tools.TkPageData; @@ -23,9 +24,7 @@ import org.thingsboard.server.common.data.yunteng.utils.tools.TkPageData;
23 import org.thingsboard.server.controller.BaseController; 24 import org.thingsboard.server.controller.BaseController;
24 import org.thingsboard.server.dao.yunteng.service.TkDataBoardService; 25 import org.thingsboard.server.dao.yunteng.service.TkDataBoardService;
25 26
26 -import java.util.HashMap;  
27 -import java.util.List;  
28 -import java.util.Map; 27 +import java.util.*;
29 28
30 import static org.thingsboard.server.common.data.yunteng.constant.QueryConstant.*; 29 import static org.thingsboard.server.common.data.yunteng.constant.QueryConstant.*;
31 30
@@ -35,7 +34,7 @@ import static org.thingsboard.server.common.data.yunteng.constant.QueryConstant. @@ -35,7 +34,7 @@ import static org.thingsboard.server.common.data.yunteng.constant.QueryConstant.
35 @PreAuthorize("@check.checkPermissions({'TENANT_ADMIN','CUSTOMER_USER'},{})") 34 @PreAuthorize("@check.checkPermissions({'TENANT_ADMIN','CUSTOMER_USER'},{})")
36 @Api(tags = {"数据看板"}) 35 @Api(tags = {"数据看板"})
37 public class TkDataBoardController extends BaseController { 36 public class TkDataBoardController extends BaseController {
38 - private final TkDataBoardService ytDataBoardService; 37 + private final TkDataBoardService tkDataBoardService;
39 38
40 @GetMapping(params = {PAGE_SIZE, PAGE}) 39 @GetMapping(params = {PAGE_SIZE, PAGE})
41 @ApiOperation("分页查询") 40 @ApiOperation("分页查询")
@@ -59,22 +58,31 @@ public class TkDataBoardController extends BaseController { @@ -59,22 +58,31 @@ public class TkDataBoardController extends BaseController {
59 if (StringUtils.isNotBlank(name)) { 58 if (StringUtils.isNotBlank(name)) {
60 queryMap.put("name", name); 59 queryMap.put("name", name);
61 } 60 }
62 - queryMap.put("userId",getCurrentUser().getCurrentUserId());  
63 - return ytDataBoardService.dataBoardPage(queryMap, getCurrentUser().isTenantAdmin()); 61 + queryMap.put("userId", getCurrentUser().getCurrentUserId());
  62 + TkPageData<DataBoardDTO> pageData =
  63 + tkDataBoardService.dataBoardPage(queryMap, getCurrentUser().isTenantAdmin());
  64 + if(!pageData.getItems().isEmpty()){
  65 + for (DataBoardDTO dto : pageData.getItems()) {
  66 + setPublicCustomerIdToCache(dto);
  67 + }
  68 + }
  69 + return pageData;
64 } 70 }
65 71
66 @DeleteMapping 72 @DeleteMapping
67 @ApiOperation(value = "删除数据看板") 73 @ApiOperation(value = "删除数据看板")
68 - @PreAuthorize("@check.checkPermissions({'TENANT_ADMIN','CUSTOMER_USER'},{'api:yt:data_board:delete'})") 74 + @PreAuthorize(
  75 + "@check.checkPermissions({'TENANT_ADMIN','CUSTOMER_USER'},{'api:yt:data_board:delete'})")
69 public ResponseResult<Boolean> deleteDataBoard( 76 public ResponseResult<Boolean> deleteDataBoard(
70 @Validated(DeleteGroup.class) @RequestBody DeleteDTO deleteDTO) throws ThingsboardException { 77 @Validated(DeleteGroup.class) @RequestBody DeleteDTO deleteDTO) throws ThingsboardException {
71 deleteDTO.setTenantId(getCurrentUser().getCurrentTenantId()); 78 deleteDTO.setTenantId(getCurrentUser().getCurrentTenantId());
72 - return ResponseResult.success(ytDataBoardService.deleteDataBoard(deleteDTO)); 79 + return ResponseResult.success(tkDataBoardService.deleteDataBoard(deleteDTO));
73 } 80 }
74 81
75 @PostMapping("/add") 82 @PostMapping("/add")
76 @ApiOperation(value = "新增数据看板") 83 @ApiOperation(value = "新增数据看板")
77 - @PreAuthorize("@check.checkPermissions({'TENANT_ADMIN','CUSTOMER_USER'},{'api:yt:data_board:add:post'})") 84 + @PreAuthorize(
  85 + "@check.checkPermissions({'TENANT_ADMIN','CUSTOMER_USER'},{'api:yt:data_board:add:post'})")
78 public ResponseResult<DataBoardDTO> save( 86 public ResponseResult<DataBoardDTO> save(
79 @RequestBody @Validated(AddGroup.class) DataBoardDTO dataBoard) 87 @RequestBody @Validated(AddGroup.class) DataBoardDTO dataBoard)
80 throws SchedulerException, ThingsboardException { 88 throws SchedulerException, ThingsboardException {
@@ -85,7 +93,8 @@ public class TkDataBoardController extends BaseController { @@ -85,7 +93,8 @@ public class TkDataBoardController extends BaseController {
85 } 93 }
86 94
87 @PostMapping("/update") 95 @PostMapping("/update")
88 - @PreAuthorize("@check.checkPermissions({'TENANT_ADMIN','CUSTOMER_USER'},{'api:yt:data_board:update:update'})") 96 + @PreAuthorize(
  97 + "@check.checkPermissions({'TENANT_ADMIN','CUSTOMER_USER'},{'api:yt:data_board:update:update'})")
89 @ApiOperation(value = "编辑数据看板") 98 @ApiOperation(value = "编辑数据看板")
90 public ResponseResult<DataBoardDTO> update( 99 public ResponseResult<DataBoardDTO> update(
91 @RequestBody @Validated(UpdateGroup.class) DataBoardDTO dataBoard) 100 @RequestBody @Validated(UpdateGroup.class) DataBoardDTO dataBoard)
@@ -102,13 +111,29 @@ public class TkDataBoardController extends BaseController { @@ -102,13 +111,29 @@ public class TkDataBoardController extends BaseController {
102 @PathVariable("boardId") String boardId, @RequestBody List<ComponentLayoutDTO> layoutDTOList) 111 @PathVariable("boardId") String boardId, @RequestBody List<ComponentLayoutDTO> layoutDTOList)
103 throws ThingsboardException { 112 throws ThingsboardException {
104 return ResponseResult.success( 113 return ResponseResult.success(
105 - ytDataBoardService.saveComponentLayout( 114 + tkDataBoardService.saveComponentLayout(
106 layoutDTOList, boardId, getCurrentUser().getCurrentTenantId())); 115 layoutDTOList, boardId, getCurrentUser().getCurrentTenantId()));
107 } 116 }
108 117
  118 + @PostMapping("share/{id}")
  119 + @ApiOperation("分享")
  120 + @PreAuthorize("@check.checkPermissions({'TENANT_ADMIN'},{'api:yt:data_board:share'})")
  121 + public ResponseEntity<Boolean> share(
  122 + @PathVariable("id") String id,
  123 + @RequestParam(value = "accessCredentials", required = false) String accessCredentials,
  124 + @RequestParam(value = "isShare") boolean isShare)
  125 + throws ThingsboardException {
  126 + if (StringUtils.isEmpty(id)) {
  127 + throw new TkDataValidationException(ErrorMessage.INVALID_PARAMETER.getMessage());
  128 + }
  129 + return ResponseEntity.ok(
  130 + tkDataBoardService.shareOrMonopolyDataBoard(
  131 + isShare, id, accessCredentials, getCurrentUser().getCurrentTenantId()));
  132 + }
  133 +
109 private ResponseResult<DataBoardDTO> saveOrUpdate(DataBoardDTO dataBoard) 134 private ResponseResult<DataBoardDTO> saveOrUpdate(DataBoardDTO dataBoard)
110 throws ThingsboardException { 135 throws ThingsboardException {
111 dataBoard.setTenantId(getCurrentUser().getCurrentTenantId()); 136 dataBoard.setTenantId(getCurrentUser().getCurrentTenantId());
112 - return ResponseResult.success(ytDataBoardService.saveOrUpdateDataBoard(dataBoard)); 137 + return ResponseResult.success(tkDataBoardService.saveOrUpdateDataBoard(dataBoard));
113 } 138 }
114 } 139 }
@@ -12,6 +12,8 @@ import org.thingsboard.server.common.data.exception.ThingsboardException; @@ -12,6 +12,8 @@ import org.thingsboard.server.common.data.exception.ThingsboardException;
12 import org.thingsboard.server.common.data.yunteng.common.AddGroup; 12 import org.thingsboard.server.common.data.yunteng.common.AddGroup;
13 import org.thingsboard.server.common.data.yunteng.common.DeleteGroup; 13 import org.thingsboard.server.common.data.yunteng.common.DeleteGroup;
14 import org.thingsboard.server.common.data.yunteng.common.UpdateGroup; 14 import org.thingsboard.server.common.data.yunteng.common.UpdateGroup;
  15 +import org.thingsboard.server.common.data.yunteng.core.exception.TkDataValidationException;
  16 +import org.thingsboard.server.common.data.yunteng.core.message.ErrorMessage;
15 import org.thingsboard.server.common.data.yunteng.dto.TkDataViewDTO; 17 import org.thingsboard.server.common.data.yunteng.dto.TkDataViewDTO;
16 import org.thingsboard.server.common.data.yunteng.dto.DeleteDTO; 18 import org.thingsboard.server.common.data.yunteng.dto.DeleteDTO;
17 import org.thingsboard.server.common.data.yunteng.dto.request.TkDataViewContentInfoDTO; 19 import org.thingsboard.server.common.data.yunteng.dto.request.TkDataViewContentInfoDTO;
@@ -31,103 +33,125 @@ import static org.thingsboard.server.common.data.yunteng.constant.QueryConstant. @@ -31,103 +33,125 @@ import static org.thingsboard.server.common.data.yunteng.constant.QueryConstant.
31 @RequestMapping("/api/yt/data_view") 33 @RequestMapping("/api/yt/data_view")
32 @RequiredArgsConstructor 34 @RequiredArgsConstructor
33 @Api(tags = "大屏设计器") 35 @Api(tags = "大屏设计器")
34 -@PreAuthorize("@check.checkPermissions({},{})") 36 +@PreAuthorize("@check.checkPermissions({'TENANT_ADMIN','CUSTOMER_USER'},{})")
35 public class TkDataViewController extends BaseController { 37 public class TkDataViewController extends BaseController {
36 38
37 - private final TkDataViewService tkDataViewService; 39 + private final TkDataViewService tkDataViewService;
38 40
39 - @GetMapping(params = {PAGE_SIZE, PAGE})  
40 - @ApiOperation("分页")  
41 - public TkPageData<TkDataViewDTO> page(  
42 - @RequestParam(PAGE_SIZE) int pageSize,  
43 - @RequestParam(PAGE) int page,  
44 - @RequestParam(value = "name", required = false) String name,  
45 - @RequestParam(value = "state", required = false) String state,  
46 - @RequestParam(value = "organizationId", required = false) String organizationId,  
47 - @RequestParam(value = ORDER_FILED, required = false) String orderBy,  
48 - @RequestParam(value = ORDER_TYPE, required = false) OrderTypeEnum orderType)  
49 - throws ThingsboardException { 41 + @GetMapping(params = {PAGE_SIZE, PAGE})
  42 + @ApiOperation("分页")
  43 + public TkPageData<TkDataViewDTO> page(
  44 + @RequestParam(PAGE_SIZE) int pageSize,
  45 + @RequestParam(PAGE) int page,
  46 + @RequestParam(value = "name", required = false) String name,
  47 + @RequestParam(value = "state", required = false) String state,
  48 + @RequestParam(value = "organizationId", required = false) String organizationId,
  49 + @RequestParam(value = ORDER_FILED, required = false) String orderBy,
  50 + @RequestParam(value = ORDER_TYPE, required = false) OrderTypeEnum orderType)
  51 + throws ThingsboardException {
50 52
51 - HashMap<String, Object> queryMap = new HashMap<>();  
52 - queryMap.put(PAGE_SIZE, pageSize);  
53 - queryMap.put(PAGE, page);  
54 - queryMap.put(ORDER_FILED, orderBy);  
55 - queryMap.put("tenantId", getCurrentUser().getCurrentTenantId());  
56 - if (StringUtils.isNotBlank(name)) {  
57 - queryMap.put("name", name);  
58 - }  
59 - if (StringUtils.isNotBlank(organizationId)) {  
60 - queryMap.put("organizationId", organizationId);  
61 - }  
62 - if (StringUtils.isNotBlank(state)) {  
63 - queryMap.put("state", state);  
64 - }  
65 - if (null != orderType) {  
66 - queryMap.put(ORDER_TYPE, orderType.name());  
67 - }  
68 - queryMap.put("userId", getCurrentUser().getCurrentUserId());  
69 - return tkDataViewService.page(queryMap, getCurrentUser().isTenantAdmin()); 53 + HashMap<String, Object> queryMap = new HashMap<>();
  54 + queryMap.put(PAGE_SIZE, pageSize);
  55 + queryMap.put(PAGE, page);
  56 + queryMap.put(ORDER_FILED, orderBy);
  57 + queryMap.put("tenantId", getCurrentUser().getCurrentTenantId());
  58 + if (StringUtils.isNotBlank(name)) {
  59 + queryMap.put("name", name);
70 } 60 }
71 -  
72 - @PostMapping  
73 - @ApiOperation("新增")  
74 - @PreAuthorize(  
75 - "@check.checkPermissions({'TENANT_ADMIN','CUSTOMER_USER'},{'api:yt:dataview:center:post'})")  
76 - public ResponseEntity<TkDataViewDTO> save(  
77 - @Validated({AddGroup.class}) @RequestBody TkDataViewDTO TkDataViewDTO)  
78 - throws ThingsboardException {  
79 - TkDataViewDTO.setTenantId(getCurrentUser().getCurrentTenantId());  
80 - return ResponseEntity.ok(  
81 - tkDataViewService.saveDataView(TkDataViewDTO)); 61 + if (StringUtils.isNotBlank(organizationId)) {
  62 + queryMap.put("organizationId", organizationId);
82 } 63 }
83 -  
84 - @PutMapping  
85 - @ApiOperation("修改")  
86 - @PreAuthorize(  
87 - "@check.checkPermissions({'TENANT_ADMIN','CUSTOMER_USER'},{'api:yt:dataview:center:update'})")  
88 - public ResponseEntity<TkDataViewDTO> update(  
89 - @Validated({UpdateGroup.class}) @RequestBody TkDataViewDTO TkDataViewDTO)  
90 - throws ThingsboardException {  
91 - TkDataViewDTO.setTenantId(getCurrentUser().getCurrentTenantId());  
92 - return ResponseEntity.ok(  
93 - tkDataViewService.updateDataView(TkDataViewDTO)); 64 + if (StringUtils.isNotBlank(state)) {
  65 + queryMap.put("state", state);
94 } 66 }
95 -  
96 - @DeleteMapping  
97 - @ApiOperation("删除")  
98 - @PreAuthorize(  
99 - "@check.checkPermissions({'TENANT_ADMIN','CUSTOMER_USER'},{'api:yt:dataview:center:delete'})")  
100 - public ResponseEntity<Boolean> delete(  
101 - @Validated({DeleteGroup.class}) @RequestBody DeleteDTO deleteDTO)  
102 - throws ThingsboardException {  
103 - deleteDTO.setTenantId(getCurrentUser().getCurrentTenantId());  
104 - return ResponseEntity.ok(tkDataViewService.deleteDataView(deleteDTO)); 67 + if (null != orderType) {
  68 + queryMap.put(ORDER_TYPE, orderType.name());
105 } 69 }
106 -  
107 - @GetMapping("/get_configuration_info/{id}")  
108 - @ApiOperation("获取大屏信息")  
109 - @PreAuthorize(  
110 - "@check.checkPermissions({'TENANT_ADMIN','CUSTOMER_USER'},{'api:yt:dataview:center:get_dataview_info:design','api:yt:dataview:center:get_dataview_info:preview'})")  
111 - public ResponseEntity<TkDataViewContentInfoDTO> getConfigurationInfos(  
112 - @PathVariable("id") String id) throws ThingsboardException {  
113 - return ResponseEntity.ok(  
114 - tkDataViewService.getDataViewInfos(  
115 - id, getCurrentUser().getCurrentTenantId())); 70 + queryMap.put("userId", getCurrentUser().getCurrentUserId());
  71 + TkPageData<TkDataViewDTO> pageData = tkDataViewService.page(queryMap, getCurrentUser().isTenantAdmin());
  72 + if(!pageData.getItems().isEmpty()){
  73 + for(TkDataViewDTO dto : pageData.getItems()){
  74 + setPublicCustomerIdToCache(dto);
  75 + }
116 } 76 }
  77 + return pageData;
  78 + }
117 79
118 - @GetMapping("/publish/{id}")  
119 - @ApiOperation("发布")  
120 - @PreAuthorize("@check.checkPermissions({},{})")  
121 - public ResponseEntity<Boolean> publishDataView(@PathVariable("id") String id) throws ThingsboardException {  
122 - return ResponseEntity.ok(  
123 - tkDataViewService.publishDataView(id, getCurrentUser().getCurrentTenantId()));  
124 - } 80 + @PostMapping
  81 + @ApiOperation("新增")
  82 + @PreAuthorize(
  83 + "@check.checkPermissions({'TENANT_ADMIN','CUSTOMER_USER'},{'api:yt:dataview:center:post'})")
  84 + public ResponseEntity<TkDataViewDTO> save(
  85 + @Validated({AddGroup.class}) @RequestBody TkDataViewDTO TkDataViewDTO)
  86 + throws ThingsboardException {
  87 + TkDataViewDTO.setTenantId(getCurrentUser().getCurrentTenantId());
  88 + return ResponseEntity.ok(tkDataViewService.saveDataView(TkDataViewDTO));
  89 + }
  90 +
  91 + @PutMapping
  92 + @ApiOperation("修改")
  93 + @PreAuthorize(
  94 + "@check.checkPermissions({'TENANT_ADMIN','CUSTOMER_USER'},{'api:yt:dataview:center:update'})")
  95 + public ResponseEntity<TkDataViewDTO> update(
  96 + @Validated({UpdateGroup.class}) @RequestBody TkDataViewDTO TkDataViewDTO)
  97 + throws ThingsboardException {
  98 + TkDataViewDTO.setTenantId(getCurrentUser().getCurrentTenantId());
  99 + return ResponseEntity.ok(tkDataViewService.updateDataView(TkDataViewDTO));
  100 + }
  101 +
  102 + @DeleteMapping
  103 + @ApiOperation("删除")
  104 + @PreAuthorize(
  105 + "@check.checkPermissions({'TENANT_ADMIN','CUSTOMER_USER'},{'api:yt:dataview:center:delete'})")
  106 + public ResponseEntity<Boolean> delete(
  107 + @Validated({DeleteGroup.class}) @RequestBody DeleteDTO deleteDTO)
  108 + throws ThingsboardException {
  109 + deleteDTO.setTenantId(getCurrentUser().getCurrentTenantId());
  110 + return ResponseEntity.ok(tkDataViewService.deleteDataView(deleteDTO));
  111 + }
  112 +
  113 + @GetMapping("/get_configuration_info/{id}")
  114 + @ApiOperation("获取大屏信息")
  115 + @PreAuthorize(
  116 + "@check.checkPermissions({'TENANT_ADMIN','CUSTOMER_USER'},{'api:yt:dataview:center:get_dataview_info:design',"
  117 + + "'api:yt:dataview:center:get_dataview_info:preview'})")
  118 + public ResponseEntity<TkDataViewContentInfoDTO> getConfigurationInfos(
  119 + @PathVariable("id") String id) throws ThingsboardException {
  120 + return ResponseEntity.ok(
  121 + tkDataViewService.getDataViewInfos(id, getCurrentUser().getCurrentTenantId()));
  122 + }
  123 +
  124 + @GetMapping("/publish/{id}")
  125 + @ApiOperation("发布")
  126 + @PreAuthorize("@check.checkPermissions({},{})")
  127 + public ResponseEntity<Boolean> publishDataView(@PathVariable("id") String id)
  128 + throws ThingsboardException {
  129 + return ResponseEntity.ok(
  130 + tkDataViewService.publishDataView(id, getCurrentUser().getCurrentTenantId()));
  131 + }
  132 +
  133 + @GetMapping("/cancel_publish/{id}")
  134 + @ApiOperation("取消发布")
  135 + @PreAuthorize("@check.checkPermissions({},{})")
  136 + public ResponseEntity<Boolean> cancelPublishDataView(@PathVariable("id") String id)
  137 + throws ThingsboardException {
  138 + return ResponseEntity.ok(
  139 + tkDataViewService.cancelPublishDataView(id, getCurrentUser().getCurrentTenantId()));
  140 + }
125 141
126 - @GetMapping("/cancel_publish/{id}")  
127 - @ApiOperation("取消发布")  
128 - @PreAuthorize("@check.checkPermissions({},{})")  
129 - public ResponseEntity<Boolean> cancelPublishDataView(@PathVariable("id") String id) throws ThingsboardException {  
130 - return ResponseEntity.ok(  
131 - tkDataViewService.cancelPublishDataView(id, getCurrentUser().getCurrentTenantId())); 142 + @PostMapping("share/{id}")
  143 + @ApiOperation("分享")
  144 + @PreAuthorize("@check.checkPermissions({'TENANT_ADMIN'},{'api:yt:dataview:center:share'})")
  145 + public ResponseEntity<Boolean> share(
  146 + @PathVariable("id") String id,
  147 + @RequestParam(value = "accessCredentials", required = false) String accessCredentials,
  148 + @RequestParam(value = "isShare") boolean isShare)
  149 + throws ThingsboardException {
  150 + if (StringUtils.isEmpty(id)) {
  151 + throw new TkDataValidationException(ErrorMessage.INVALID_PARAMETER.getMessage());
132 } 152 }
  153 + return ResponseEntity.ok(
  154 + tkDataViewService.shareOrMonopolyDataViewCenter(
  155 + isShare, id, accessCredentials, getCurrentUser().getCurrentTenantId()));
  156 + }
133 } 157 }
  1 +package org.thingsboard.server.controller.yunteng;
  2 +
  3 +import io.swagger.annotations.Api;
  4 +import io.swagger.annotations.ApiOperation;
  5 +import lombok.RequiredArgsConstructor;
  6 +import org.springframework.web.bind.annotation.*;
  7 +import org.thingsboard.server.common.data.StringUtils;
  8 +import org.thingsboard.server.common.data.exception.ThingsboardException;
  9 +import org.thingsboard.server.common.data.yunteng.core.exception.TkDataValidationException;
  10 +import org.thingsboard.server.common.data.yunteng.core.message.ErrorMessage;
  11 +import org.thingsboard.server.common.data.yunteng.enums.ShareViewType;
  12 +import org.thingsboard.server.common.data.yunteng.utils.tools.ResponseResult;
  13 +import org.thingsboard.server.controller.BaseController;
  14 +import org.thingsboard.server.dao.yunteng.service.TkShareViewService;
  15 +
  16 +@RestController
  17 +@RequiredArgsConstructor
  18 +@RequestMapping("api/yt/share")
  19 +@Api(tags = {"分享的视图"})
  20 +public class TkShareViewController extends BaseController {
  21 + private final TkShareViewService tkShareViewService;
  22 +
  23 + @GetMapping("/check/{type}/{viewId}")
  24 + @ApiOperation(value = "检查分享视图是否需要访问凭证")
  25 + public ResponseResult<Boolean> checkPublicViewNeedCredentials(
  26 + @PathVariable("type") ShareViewType type, @PathVariable("viewId") String viewId)
  27 + throws ThingsboardException {
  28 + if (StringUtils.isEmpty(viewId)) {
  29 + throw new TkDataValidationException(ErrorMessage.INVALID_PARAMETER.getMessage());
  30 + }
  31 + return ResponseResult.success(
  32 + tkShareViewService.checkPublicViewNeedCredentials(
  33 + type, viewId, getCurrentUser().getCurrentTenantId()));
  34 + }
  35 +
  36 + @GetMapping("/{share_view_type}/share_data/{id}")
  37 + @ApiOperation(value = "查看分享的数据")
  38 + public ResponseResult<Object> viewDataComponentsByBoardId(
  39 + @PathVariable("id") String id,
  40 + @PathVariable("share_view_type") ShareViewType shareViewType,
  41 + @RequestParam(value = "accessCredentials",required = false) String accessCredentials)
  42 + throws ThingsboardException {
  43 + if (StringUtils.isEmpty(id) || null == shareViewType) {
  44 + throw new TkDataValidationException(ErrorMessage.INVALID_PARAMETER.getMessage());
  45 + }
  46 + return ResponseResult.success(
  47 + tkShareViewService.viewShareDataById(
  48 + shareViewType, id, accessCredentials, getCurrentUser().getCurrentTenantId()));
  49 + }
  50 +}
  1 +package org.thingsboard.server.controller.yunteng;
  2 +
  3 +import io.swagger.annotations.Api;
  4 +import io.swagger.annotations.ApiOperation;
  5 +import lombok.RequiredArgsConstructor;
  6 +import org.apache.commons.lang3.StringUtils;
  7 +import org.quartz.SchedulerException;
  8 +import org.springframework.security.access.prepost.PreAuthorize;
  9 +import org.springframework.validation.annotation.Validated;
  10 +import org.springframework.web.bind.annotation.*;
  11 +import org.thingsboard.server.common.data.exception.ThingsboardException;
  12 +import org.thingsboard.server.common.data.yunteng.common.AddGroup;
  13 +import org.thingsboard.server.common.data.yunteng.common.UpdateGroup;
  14 +import org.thingsboard.server.common.data.yunteng.core.exception.TkDataValidationException;
  15 +import org.thingsboard.server.common.data.yunteng.core.message.ErrorMessage;
  16 +import org.thingsboard.server.common.data.yunteng.dto.DeleteDTO;
  17 +import org.thingsboard.server.common.data.yunteng.dto.task.TkTaskCenterDTO;
  18 +import org.thingsboard.server.common.data.yunteng.enums.OrderTypeEnum;
  19 +import org.thingsboard.server.common.data.yunteng.enums.TargetTypeEnum;
  20 +import org.thingsboard.server.common.data.yunteng.utils.tools.ResponseResult;
  21 +import org.thingsboard.server.common.data.yunteng.utils.tools.TkPageData;
  22 +import org.thingsboard.server.controller.BaseController;
  23 +import org.thingsboard.server.dao.yunteng.service.TkTaskCenterService;
  24 +
  25 +import java.util.HashMap;
  26 +
  27 +import static org.thingsboard.server.common.data.yunteng.constant.QueryConstant.*;
  28 +import static org.thingsboard.server.common.data.yunteng.constant.QueryConstant.ORDER_TYPE;
  29 +
  30 +@RestController
  31 +@RequestMapping("api/yt/task_center")
  32 +@Api(tags = {"任务中心"})
  33 +@RequiredArgsConstructor
  34 +public class TkTaskCenterController extends BaseController {
  35 + private final TkTaskCenterService tkTaskCenterService;
  36 +
  37 + @GetMapping(
  38 + name = "page",
  39 + params = {PAGE_SIZE, PAGE})
  40 + public TkPageData<TkTaskCenterDTO> pageDevice(
  41 + @RequestParam(PAGE_SIZE) int pageSize,
  42 + @RequestParam(PAGE) int page,
  43 + @RequestParam(value = "state", required = false) Integer state,
  44 + @RequestParam(value = "targetType", required = false) TargetTypeEnum targetType,
  45 + @RequestParam(value = ORDER_FILED, required = false) String orderBy,
  46 + @RequestParam(value = ORDER_TYPE, required = false) OrderTypeEnum orderType)
  47 + throws ThingsboardException {
  48 + HashMap<String, Object> queryMap = new HashMap<>();
  49 + queryMap.put(PAGE_SIZE, pageSize);
  50 + queryMap.put(PAGE, page);
  51 + queryMap.put(ORDER_FILED, orderBy);
  52 + queryMap.put(ORDER_TYPE, orderType);
  53 + queryMap.put("state", state);
  54 + queryMap.put("targetType", targetType);
  55 + return tkTaskCenterService.taskCenterPage(queryMap, getCurrentUser().getCurrentTenantId());
  56 + }
  57 +
  58 + @PostMapping("/add")
  59 + @ApiOperation(value = "新增任务中心")
  60 +// @PreAuthorize(
  61 +// "@check.checkPermissions({'TENANT_ADMIN','CUSTOMER_USER'},{'api:yt:task_center:add:post'})")
  62 + public ResponseResult<TkTaskCenterDTO> save(
  63 + @RequestBody @Validated(AddGroup.class) TkTaskCenterDTO taskCenter)
  64 + throws ThingsboardException, SchedulerException {
  65 + if (StringUtils.isNotEmpty(taskCenter.getId())) {
  66 + throw new TkDataValidationException(ErrorMessage.INVALID_PARAMETER.getMessage());
  67 + }
  68 + return ResponseResult.success(saveOrUpdate(taskCenter));
  69 + }
  70 +
  71 + @PutMapping("/update")
  72 +// @PreAuthorize(
  73 +// "@check.checkPermissions({'TENANT_ADMIN','CUSTOMER_USER'},{'api:yt:task_center:update:update'})")
  74 + @ApiOperation(value = "编辑任务中心")
  75 + public ResponseResult<TkTaskCenterDTO> update(
  76 + @RequestBody @Validated(UpdateGroup.class) TkTaskCenterDTO taskCenter)
  77 + throws ThingsboardException, SchedulerException {
  78 + if (StringUtils.isEmpty(taskCenter.getId())) {
  79 + throw new TkDataValidationException(ErrorMessage.INVALID_PARAMETER.getMessage());
  80 + }
  81 + return ResponseResult.success(saveOrUpdate(taskCenter));
  82 + }
  83 +
  84 + @PutMapping("/{id}/update/{state}")
  85 +// @PreAuthorize(
  86 +// "@check.checkPermissions({'TENANT_ADMIN','CUSTOMER_USER'},{'api:yt:task_center:update:update'})")
  87 + @ApiOperation(value = "更新状态")
  88 + public ResponseResult<Boolean> updateState(
  89 + @PathVariable("id") String id, @PathVariable("state") Integer state)
  90 + throws ThingsboardException, SchedulerException {
  91 + if (StringUtils.isEmpty(id) || null == state) {
  92 + throw new TkDataValidationException(ErrorMessage.INVALID_PARAMETER.getMessage());
  93 + }
  94 + return ResponseResult.success(
  95 + tkTaskCenterService.updateState(id, state, getCurrentUser().getCurrentTenantId()));
  96 + }
  97 +
  98 + @DeleteMapping
  99 +// @PreAuthorize(
  100 +// "@check.checkPermissions({'TENANT_ADMIN','CUSTOMER_USER'},{'api:yt:task_center:delete'})")
  101 + @ApiOperation(value = "删除任务中心")
  102 + public ResponseResult<Boolean> deleteTaskCenter(@RequestBody DeleteDTO deleteDTO)
  103 + throws ThingsboardException, SchedulerException {
  104 + deleteDTO.setTenantId(getCurrentUser().getCurrentTenantId());
  105 + return ResponseResult.success(tkTaskCenterService.deleteTaskCenter(deleteDTO));
  106 + }
  107 +
  108 + @PutMapping("/{id}/cancel/{tbDeviceId}")
  109 +// @PreAuthorize(
  110 +// "@check.checkPermissions({'TENANT_ADMIN','CUSTOMER_USER'},{'api:yt:task_center:cancel'})")
  111 + @ApiOperation(value = "设备取消任务执行")
  112 + public ResponseResult<Boolean> cancelExecute(
  113 + @PathVariable("id") String taskId, @PathVariable("tbDeviceId") String tbDeviceId)throws ThingsboardException {
  114 + if(StringUtils.isEmpty(taskId) || StringUtils.isEmpty(tbDeviceId)){
  115 + throw new TkDataValidationException(ErrorMessage.INVALID_PARAMETER.getMessage());
  116 + }
  117 + return ResponseResult.success(
  118 + tkTaskCenterService.cancelExecute(
  119 + taskId, tbDeviceId, getCurrentUser().getCurrentTenantId()));
  120 + }
  121 +
  122 + private TkTaskCenterDTO saveOrUpdate(TkTaskCenterDTO tkTaskCenterDTO)
  123 + throws ThingsboardException, SchedulerException {
  124 + tkTaskCenterDTO.setTenantId(getCurrentUser().getCurrentTenantId());
  125 + return tkTaskCenterService.saveOrUpdateTaskCenter(tkTaskCenterDTO);
  126 + }
  127 +}
  1 +package org.thingsboard.server.utils.yunteng;
  2 +
  3 +import com.fasterxml.jackson.databind.JsonNode;
  4 +import com.google.common.util.concurrent.FutureCallback;
  5 +import com.google.common.util.concurrent.Futures;
  6 +import com.google.common.util.concurrent.ListenableFuture;
  7 +import com.google.common.util.concurrent.MoreExecutors;
  8 +import lombok.RequiredArgsConstructor;
  9 +import lombok.extern.slf4j.Slf4j;
  10 +import org.checkerframework.checker.nullness.qual.Nullable;
  11 +import org.jetbrains.annotations.NotNull;
  12 +import org.springframework.beans.factory.annotation.Value;
  13 +import org.springframework.stereotype.Component;
  14 +import org.thingsboard.common.util.JacksonUtil;
  15 +import org.thingsboard.server.common.data.id.DeviceId;
  16 +import org.thingsboard.server.common.data.id.TenantId;
  17 +import org.thingsboard.server.common.data.rpc.ToDeviceRpcRequestBody;
  18 +import org.thingsboard.server.common.data.yunteng.constant.FastIotConstants;
  19 +import org.thingsboard.server.common.data.yunteng.dto.DeviceDTO;
  20 +import org.thingsboard.server.common.data.yunteng.dto.task.TargetContentDTO;
  21 +import org.thingsboard.server.common.data.yunteng.dto.task.TkTaskCenterDTO;
  22 +import org.thingsboard.server.common.data.yunteng.enums.TargetTypeEnum;
  23 +import org.thingsboard.server.common.msg.rpc.ToDeviceRpcRequest;
  24 +import org.thingsboard.server.dao.yunteng.service.TkDeviceService;
  25 +import org.thingsboard.server.dao.yunteng.service.TkTaskCenterService;
  26 +import org.thingsboard.server.service.rpc.TbCoreDeviceRpcService;
  27 +import org.thingsboard.server.service.security.model.SecurityUser;
  28 +import java.util.*;
  29 +
  30 +@Component("rpcCommandTask")
  31 +@RequiredArgsConstructor
  32 +@Slf4j
  33 +public class RpcCommandTask {
  34 + @Value("${server.rest.server_side_rpc.default_timeout:10000}")
  35 + protected long defaultTimeout;
  36 +
  37 + @Value("${server.rest.server_side_rpc.min_timeout:5000}")
  38 + protected long minTimeout;
  39 +
  40 + private final TkTaskCenterService tkTaskCenterService;
  41 + private final TbCoreDeviceRpcService tbCoreDeviceRpcService;
  42 + private final TkDeviceService tkDeviceService;
  43 + public void process(String taskCenterId) {
  44 + // 通过任务中心ID查询执行命令及执行对象
  45 + ListenableFuture<TkTaskCenterDTO> future =
  46 + tkTaskCenterService.getTaskCenterInfoById(taskCenterId);
  47 + Futures.addCallback(
  48 + future,
  49 + new FutureCallback<>() {
  50 + @Override
  51 + public void onSuccess(@Nullable TkTaskCenterDTO tkTaskCenterDTO) {
  52 + if (null != tkTaskCenterDTO) {
  53 + TargetTypeEnum targetType = tkTaskCenterDTO.getTargetType();
  54 + TargetContentDTO targetContent = tkTaskCenterDTO.getExecuteTarget();
  55 + JsonNode cmdJsonNode = tkTaskCenterDTO.getExecuteContent().getPushContent();
  56 + SecurityUser securityUser = new SecurityUser();
  57 + // send cmd
  58 + if (targetContent.getData() != null && null != cmdJsonNode) {
  59 + String tenantId = tkTaskCenterDTO.getTenantId();
  60 + if (targetType.equals(TargetTypeEnum.DEVICES)) {
  61 + for (String deviceId : targetContent.getData()) {
  62 + sendRpcCommand(cmdJsonNode, tenantId, deviceId, securityUser);
  63 + }
  64 + } else {
  65 + sendRpcCommandByProducts(targetContent, cmdJsonNode, tenantId, securityUser);
  66 + }
  67 + }
  68 + }
  69 + }
  70 +
  71 + @Override
  72 + public void onFailure(@NotNull Throwable throwable) {}
  73 + },
  74 + MoreExecutors.directExecutor());
  75 + }
  76 +
  77 + private void sendRpcCommandByProducts(
  78 + TargetContentDTO targetContent,
  79 + JsonNode cmdJsonNode,
  80 + String tenantId,
  81 + SecurityUser securityUser) {
  82 + for (String deviceProfileId : targetContent.getData()) {
  83 + Futures.addCallback(
  84 + tkDeviceService.findDeviceListByDeviceProfileId(deviceProfileId, tenantId),
  85 + new FutureCallback<List<DeviceDTO>>() {
  86 + @Override
  87 + public void onSuccess(@Nullable List<DeviceDTO> deviceDTOS) {
  88 + if (null != deviceDTOS && !deviceDTOS.isEmpty()) {
  89 + for (DeviceDTO dto : deviceDTOS) {
  90 + Map<String, List<String>> map = targetContent.getCancelExecuteDevices();
  91 + boolean needSendCommand = true;
  92 + if (null != map && !map.isEmpty() && !map.get(deviceProfileId).isEmpty()) {
  93 + for (String deviceId : map.get(deviceProfileId)) {
  94 + if (Objects.equals(deviceId, dto.getTbDeviceId())) {
  95 + needSendCommand = false;
  96 + break;
  97 + }
  98 + }
  99 + }
  100 + if (needSendCommand) {
  101 + sendRpcCommand(cmdJsonNode, tenantId, dto.getTbDeviceId(), securityUser);
  102 + }
  103 + }
  104 + }
  105 + }
  106 +
  107 + @Override
  108 + public void onFailure(@NotNull Throwable throwable) {}
  109 + },
  110 + MoreExecutors.directExecutor());
  111 + }
  112 + }
  113 +
  114 + private void sendRpcCommand(
  115 + JsonNode cmdJsonNode, String tenantId, String originateId, SecurityUser securityUser) {
  116 + JsonNode rpcCommand = cmdJsonNode.get(FastIotConstants.RPC_COMMAND);
  117 + ToDeviceRpcRequestBody body =
  118 + new ToDeviceRpcRequestBody("methodThingskit", JacksonUtil.toString(rpcCommand));
  119 + DeviceId deviceId = new DeviceId(UUID.fromString(originateId));
  120 + ToDeviceRpcRequest request =
  121 + new ToDeviceRpcRequest(
  122 + UUID.randomUUID(),
  123 + new TenantId(UUID.fromString(tenantId)),
  124 + deviceId,
  125 + true,
  126 + System.currentTimeMillis() + Math.max(minTimeout, defaultTimeout),
  127 + body,
  128 + false,
  129 + null,
  130 + null);
  131 + tbCoreDeviceRpcService.processRestApiRpcRequest(
  132 + request,
  133 + fromDeviceRpcResponse -> {
  134 + log.trace("Device renamed RPC with id: [{}] ", request.getId());
  135 + },
  136 + securityUser);
  137 + }
  138 +}
@@ -431,18 +431,20 @@ caffeine: @@ -431,18 +431,20 @@ caffeine:
431 timeToLiveInMinutes: "${CACHE_SPECS_EDGES_TTL:1440}" 431 timeToLiveInMinutes: "${CACHE_SPECS_EDGES_TTL:1440}"
432 maxSize: "${CACHE_SPECS_EDGES_MAX_SIZE:10000}" 432 maxSize: "${CACHE_SPECS_EDGES_MAX_SIZE:10000}"
433 yunTengIotCache: 433 yunTengIotCache:
434 - timeToLiveInMinutes: 1440  
435 - maxSize: 10000 434 + timeToLiveInMinutes: "${CACHE_SPECS_YUN_TENG_IOT_CACHE_TTL:1440}"
  435 + maxSize: "${CACHE_SPECS_YUN_TENG_IOT_CACHE_MAX_SIZE:10000}"
436 userPermissionFor: 436 userPermissionFor:
437 - timeToLiveInMinutes: 1440  
438 - maxSize: 10000 437 + timeToLiveInMinutes: "${CACHE_SPECS_USER_PERMISSION_FOR_TTL:1440}"
  438 + maxSize: "${CACHE_SPECS_USER_PERMISSION_FOR_MAX_SIZE:10000}"
439 mobileLoginSmsCode: 439 mobileLoginSmsCode:
440 - timeToLiveInMinutes: 2  
441 - maxSize: 10000 440 + timeToLiveInMinutes: "${CACHE_SPECS_MOBILE_LOGIN_SMS_CODE_TTL:2}"
  441 + maxSize: "${CACHE_SPECS_MOBILE_LOGIN_SMS_CODE_MAX_SIZE:10000}"
442 thingsArea: 442 thingsArea:
443 - timeToLiveInMinutes: 1440  
444 - maxSize: 500  
445 - 443 + timeToLiveInMinutes: "${CACHE_SPECS_THINGS_AREA_TTL:1440}"
  444 + maxSize: "${CACHE_SPECS_THINGS_AREA_MAX_SIZE:500}"
  445 + taskCenterInfos:
  446 + timeToLiveInMinutes: "${CACHE_SPECS_TASK_CENTER_TTL:1440}"
  447 + maxSize: "${CACHE_SPECS_TASK_CENTER_MAX_SIZE:10000}"
446 redis: 448 redis:
447 # standalone or cluster 449 # standalone or cluster
448 connection: 450 connection:
@@ -905,8 +907,8 @@ transport: @@ -905,8 +907,8 @@ transport:
905 psm_activity_timer: "${LWM2M_PSM_ACTIVITY_TIMER:10000}" 907 psm_activity_timer: "${LWM2M_PSM_ACTIVITY_TIMER:10000}"
906 paging_transmission_window: "${LWM2M_PAGING_TRANSMISSION_WINDOW:10000}" 908 paging_transmission_window: "${LWM2M_PAGING_TRANSMISSION_WINDOW:10000}"
907 network_config: # In this section you can specify custom parameters for LwM2M network configuration and expose the env variables to configure outside 909 network_config: # In this section you can specify custom parameters for LwM2M network configuration and expose the env variables to configure outside
908 -# - key: "PROTOCOL_STAGE_THREAD_COUNT"  
909 -# value: "${LWM2M_PROTOCOL_STAGE_THREAD_COUNT:4}" 910 + # - key: "PROTOCOL_STAGE_THREAD_COUNT"
  911 + # value: "${LWM2M_PROTOCOL_STAGE_THREAD_COUNT:4}"
910 snmp: 912 snmp:
911 enabled: "${SNMP_ENABLED:true}" 913 enabled: "${SNMP_ENABLED:true}"
912 response_processing: 914 response_processing:
@@ -989,9 +991,9 @@ queue: @@ -989,9 +991,9 @@ queue:
989 tb_ota_package: 991 tb_ota_package:
990 - key: max.poll.records 992 - key: max.poll.records
991 value: "${TB_QUEUE_KAFKA_OTA_MAX_POLL_RECORDS:10}" 993 value: "${TB_QUEUE_KAFKA_OTA_MAX_POLL_RECORDS:10}"
992 -# tb_rule_engine.sq:  
993 -# - key: max.poll.records  
994 -# value: "${TB_QUEUE_KAFKA_SQ_MAX_POLL_RECORDS:1024}" 994 + # tb_rule_engine.sq:
  995 + # - key: max.poll.records
  996 + # value: "${TB_QUEUE_KAFKA_SQ_MAX_POLL_RECORDS:1024}"
995 other: # In this section you can specify custom parameters for Kafka consumer/producer and expose the env variables to configure outside 997 other: # In this section you can specify custom parameters for Kafka consumer/producer and expose the env variables to configure outside
996 - key: "request.timeout.ms" # refer to https://docs.confluent.io/platform/current/installation/configuration/producer-configs.html#producerconfigs_request.timeout.ms 998 - key: "request.timeout.ms" # refer to https://docs.confluent.io/platform/current/installation/configuration/producer-configs.html#producerconfigs_request.timeout.ms
997 value: "${TB_QUEUE_KAFKA_REQUEST_TIMEOUT_MS:30000}" # (30 seconds) 999 value: "${TB_QUEUE_KAFKA_REQUEST_TIMEOUT_MS:30000}" # (30 seconds)
@@ -1193,14 +1195,14 @@ file: @@ -1193,14 +1195,14 @@ file:
1193 staticUrl: /static/files/** #oss静态访问路径 只有type = local需要 1195 staticUrl: /static/files/** #oss静态访问路径 只有type = local需要
1194 randomFileName: ${file.storage.randomFileName} 1196 randomFileName: ${file.storage.randomFileName}
1195 minio: 1197 minio:
1196 - minioUrl: ${MINIO_URL:https://dev.thingskit.com:9000} #minio储存地址  
1197 - minioName: ${MINIO_NAME:test} #minio账户  
1198 - minioPass: ${MINIO_PWD:test} #minio访问密码  
1199 - bucketName: yunteng #minio储存桶名称 1198 + minioUrl: ${MINIO_URL:http://localhost:9000} #minio储存地址
  1199 + minioName: ${MINIO_NAME:thingskit} #minio账户
  1200 + minioPass: ${MINIO_PWD:thingskit} #minio访问密码
  1201 + bucketName: yunteng #minio储存桶名称
1200 randomFileName: ${file.storage.randomFileName} 1202 randomFileName: ${file.storage.randomFileName}
1201 account: 1203 account:
1202 info: 1204 info:
1203 - emailSuffix: ${ACCOUNT_EMAIL_SUFFIX:yunteng.com} 1205 + emailSuffix: ${ACCOUNT_EMAIL_SUFFIX:thingskit.com}
1204 defaultPassword: 123456 1206 defaultPassword: 123456
1205 reset: ${ACCOUNT_PASSWORD_FORCE_RESET:true} 1207 reset: ${ACCOUNT_PASSWORD_FORCE_RESET:true}
1206 third: 1208 third:
@@ -19,13 +19,17 @@ public interface FastIotConstants { @@ -19,13 +19,17 @@ public interface FastIotConstants {
19 Pattern EMAIL_PATTERN = Pattern.compile(EMAIL, Pattern.CASE_INSENSITIVE); 19 Pattern EMAIL_PATTERN = Pattern.compile(EMAIL, Pattern.CASE_INSENSITIVE);
20 Pattern CHINA_MOBILE_PATTERN = Pattern.compile(MOBILE); 20 Pattern CHINA_MOBILE_PATTERN = Pattern.compile(MOBILE);
21 String DEFAULT_DELIMITER = "#"; 21 String DEFAULT_DELIMITER = "#";
  22 + String RPC_COMMAND = "rpcCommand";
  23 +
22 interface CacheConfigKey { 24 interface CacheConfigKey {
23 String CACHE_CONFIG_KEY = "yunTengIotCache"; 25 String CACHE_CONFIG_KEY = "yunTengIotCache";
24 String USER_PERMISSION_PREFIX = "userPermissionFor_"; 26 String USER_PERMISSION_PREFIX = "userPermissionFor_";
25 String MOBILE_LOGIN_SMS_CODE = "mobileLoginSmsCode"; 27 String MOBILE_LOGIN_SMS_CODE = "mobileLoginSmsCode";
26 -  
27 String AREA = "thingsArea"; 28 String AREA = "thingsArea";
  29 + String PUBLIC_ID = "publicId_";
  30 + String TASK_CENTER_INFOS = "taskCenterInfos_";
28 } 31 }
  32 +
29 interface TBCacheConfig { 33 interface TBCacheConfig {
30 String TB_CACHE_CONFIG_KEY = "TB_CONNECT_CACHE"; 34 String TB_CACHE_CONFIG_KEY = "TB_CONNECT_CACHE";
31 String EXISTING_TENANT = "EXISTING_TENANT"; 35 String EXISTING_TENANT = "EXISTING_TENANT";
@@ -48,7 +52,6 @@ public interface FastIotConstants { @@ -48,7 +52,6 @@ public interface FastIotConstants {
48 int DRAFT = 0; 52 int DRAFT = 0;
49 } 53 }
50 54
51 -  
52 interface ConfigureLevel { 55 interface ConfigureLevel {
53 String CONFIGURE = "CONFIGURE"; 56 String CONFIGURE = "CONFIGURE";
54 String CONTENT = "CONTENT"; 57 String CONTENT = "CONTENT";
@@ -130,6 +133,12 @@ public interface FastIotConstants { @@ -130,6 +133,12 @@ public interface FastIotConstants {
130 /** 在线 */ 133 /** 在线 */
131 public static final int ONLINE = 1; 134 public static final int ONLINE = 1;
132 135
  136 + /** 发布 */
  137 + public static final int PUBLISH = 1;
  138 +
  139 + /** 取消发布 */
  140 + public static final int CANCEL_PUBLISH = 0;
  141 +
133 /** 删除成功 */ 142 /** 删除成功 */
134 public static final String DELETE_SUCCESS = "删除成功"; 143 public static final String DELETE_SUCCESS = "删除成功";
135 144
@@ -118,6 +118,8 @@ public final class ModelConstants { @@ -118,6 +118,8 @@ public final class ModelConstants {
118 public static final String TK_CUSTOMER_DEVICE_NAME = "tk_customer_device"; 118 public static final String TK_CUSTOMER_DEVICE_NAME = "tk_customer_device";
119 /** 设备上下线记录表 */ 119 /** 设备上下线记录表 */
120 public static final String TK_DEVICE_STATE_LOG = "tk_device_state_log"; 120 public static final String TK_DEVICE_STATE_LOG = "tk_device_state_log";
  121 + /** 任务中心表 */
  122 + public static final String TK_TASK_CENTER_NAME = "tk_task_center";
121 } 123 }
122 124
123 public static class TableFields { 125 public static class TableFields {
@@ -2,13 +2,14 @@ package org.thingsboard.server.common.data.yunteng.core.cache; @@ -2,13 +2,14 @@ package org.thingsboard.server.common.data.yunteng.core.cache;
2 import org.springframework.cache.Cache; 2 import org.springframework.cache.Cache;
3 import org.springframework.cache.CacheManager; 3 import org.springframework.cache.CacheManager;
4 import org.springframework.stereotype.Component; 4 import org.springframework.stereotype.Component;
  5 +import org.thingsboard.server.common.data.yunteng.constant.FastIotConstants;
5 import java.util.Objects; 6 import java.util.Objects;
6 import java.util.Optional; 7 import java.util.Optional;
7 8
8 @Component 9 @Component
9 public class CacheUtils { 10 public class CacheUtils {
10 11
11 - private final String COMMON_STORE_AREA = "yun-teng-iot-common"; 12 + private final String COMMON_STORE_AREA = FastIotConstants.CacheConfigKey.CACHE_CONFIG_KEY;
12 13
13 private final CacheManager cacheManager; 14 private final CacheManager cacheManager;
14 15
@@ -89,6 +89,11 @@ public enum ErrorMessage { @@ -89,6 +89,11 @@ public enum ErrorMessage {
89 INVALID_TOPIC(400065,"无效Topic。"), 89 INVALID_TOPIC(400065,"无效Topic。"),
90 BUCKET_NOT_CONFORM_RENAME_RULE(400066,"存储桶不符合命名规范!!"), 90 BUCKET_NOT_CONFORM_RENAME_RULE(400066,"存储桶不符合命名规范!!"),
91 MINIO_KEY_AND_SIGNATURE_ERROR(400067,"Minio签名不匹配!!"), 91 MINIO_KEY_AND_SIGNATURE_ERROR(400067,"Minio签名不匹配!!"),
  92 + CURRENT_VIEW_IS_PRIVATE(400068,"当前视图为私有视图,拒绝访问!"),
  93 + CURRENT_URL_REQUIRES_PERMISSION(400069,"当前视图需要访问凭证或凭证验证失败!"),
  94 + SHARE_VIEW_TYPE_NOT_EXIST(400070,"分享视图类型不存在"),
  95 + DATA_STATE_ENABLE_NOT_DELETE(400071,"【%s】数据为启用状态不能删除!!"),
  96 + EXECUTE_COMMAND_IS_NULL(400072,"执行命令不能为空"),
92 HAVE_NO_PERMISSION(500002,"没有修改权限"); 97 HAVE_NO_PERMISSION(500002,"没有修改权限");
93 private final int code; 98 private final int code;
94 private String message; 99 private String message;
@@ -10,7 +10,7 @@ import javax.validation.constraints.NotEmpty; @@ -10,7 +10,7 @@ import javax.validation.constraints.NotEmpty;
10 10
11 @EqualsAndHashCode(callSuper = true) 11 @EqualsAndHashCode(callSuper = true)
12 @Data 12 @Data
13 -public class ConfigurationCenterDTO extends TenantDTO { 13 +public class ConfigurationCenterDTO extends PublicCustomerDTO {
14 @ApiModelProperty(value = "组态名称", required = true) 14 @ApiModelProperty(value = "组态名称", required = true)
15 @NotEmpty( 15 @NotEmpty(
16 message = "组态名称不能为空或空字符串", 16 message = "组态名称不能为空或空字符串",
@@ -5,14 +5,13 @@ import lombok.Data; @@ -5,14 +5,13 @@ import lombok.Data;
5 import lombok.EqualsAndHashCode; 5 import lombok.EqualsAndHashCode;
6 import org.thingsboard.server.common.data.yunteng.common.AddGroup; 6 import org.thingsboard.server.common.data.yunteng.common.AddGroup;
7 import org.thingsboard.server.common.data.yunteng.dto.board.ComponentLayoutDTO; 7 import org.thingsboard.server.common.data.yunteng.dto.board.ComponentLayoutDTO;
8 -import org.thingsboard.server.common.data.yunteng.enums.ViewType;  
9 8
10 import javax.validation.constraints.NotEmpty; 9 import javax.validation.constraints.NotEmpty;
11 import java.util.List; 10 import java.util.List;
12 11
13 @EqualsAndHashCode(callSuper = true) 12 @EqualsAndHashCode(callSuper = true)
14 @Data 13 @Data
15 -public class DataBoardDTO extends TenantDTO { 14 +public class DataBoardDTO extends PublicCustomerDTO {
16 @ApiModelProperty(value = "数据看板名称", required = true) 15 @ApiModelProperty(value = "数据看板名称", required = true)
17 @NotEmpty(message = "数据看板名称不能为空或者空字符串", groups = AddGroup.class) 16 @NotEmpty(message = "数据看板名称不能为空或者空字符串", groups = AddGroup.class)
18 private String name; 17 private String name;
@@ -21,9 +20,6 @@ public class DataBoardDTO extends TenantDTO { @@ -21,9 +20,6 @@ public class DataBoardDTO extends TenantDTO {
21 @NotEmpty(message = "组织ID不能为空或者空字符串", groups = AddGroup.class) 20 @NotEmpty(message = "组织ID不能为空或者空字符串", groups = AddGroup.class)
22 private String organizationId; 21 private String organizationId;
23 22
24 - @ApiModelProperty(value = "视图类型")  
25 - private ViewType viewType = ViewType.PRIVATE_VIEW;  
26 -  
27 @ApiModelProperty(value = "组件布局") 23 @ApiModelProperty(value = "组件布局")
28 private List<ComponentLayoutDTO> layout; 24 private List<ComponentLayoutDTO> layout;
29 25
@@ -121,6 +121,8 @@ public class DeviceDTO extends TenantDTO { @@ -121,6 +121,8 @@ public class DeviceDTO extends TenantDTO {
121 @ApiModelProperty(value = "启用/禁用") 121 @ApiModelProperty(value = "启用/禁用")
122 private boolean enable; 122 private boolean enable;
123 123
  124 + private JsonNode customerAdditionalInfo;
  125 +
124 public DeviceState getDeviceState() { 126 public DeviceState getDeviceState() {
125 if (lastOnlineTime == null) { 127 if (lastOnlineTime == null) {
126 return DeviceState.INACTIVE; 128 return DeviceState.INACTIVE;
  1 +package org.thingsboard.server.common.data.yunteng.dto;
  2 +
  3 +import io.swagger.annotations.ApiModelProperty;
  4 +import lombok.Data;
  5 +import org.thingsboard.server.common.data.yunteng.enums.ViewType;
  6 +
  7 +@Data
  8 +public class PublicCustomerDTO extends TenantDTO {
  9 + @ApiModelProperty(value = "分享公共ID")
  10 + private String publicId;
  11 +
  12 + @ApiModelProperty(value = "视图类型")
  13 + private ViewType viewType = ViewType.PRIVATE_VIEW;
  14 +
  15 + @ApiModelProperty(value = "访问凭证")
  16 + private String accessCredentials;
  17 +}
@@ -11,33 +11,27 @@ import javax.validation.constraints.NotEmpty; @@ -11,33 +11,27 @@ import javax.validation.constraints.NotEmpty;
11 11
12 @EqualsAndHashCode(callSuper = true) 12 @EqualsAndHashCode(callSuper = true)
13 @Data 13 @Data
14 -public class TkDataViewDTO extends TenantDTO {  
15 - @ApiModelProperty(value = "大屏名称", required = true)  
16 - @NotEmpty(  
17 - message = "大屏名称不能为空或空字符串",  
18 - groups = {UpdateGroup.class, AddGroup.class})  
19 - private String name; 14 +public class TkDataViewDTO extends PublicCustomerDTO {
  15 + @ApiModelProperty(value = "大屏名称", required = true)
  16 + @NotEmpty(
  17 + message = "大屏名称不能为空或空字符串",
  18 + groups = {UpdateGroup.class, AddGroup.class})
  19 + private String name;
20 20
21 - @ApiModelProperty(value = "状态:0待发布 1发布")  
22 - private Integer state; 21 + @ApiModelProperty(value = "状态:0待发布 1发布")
  22 + private Integer state;
23 23
24 - @ApiModelProperty(value = "大屏描述")  
25 - private String remark; 24 + @ApiModelProperty(value = "大屏描述")
  25 + private String remark;
26 26
27 - @ApiModelProperty(value = "组织ID", required = true)  
28 - @NotEmpty(  
29 - message = "组织ID不能为空或空字符串",  
30 - groups = {UpdateGroup.class, AddGroup.class})  
31 - private String organizationId; 27 + @ApiModelProperty(value = "组织ID", required = true)
  28 + @NotEmpty(
  29 + message = "组织ID不能为空或空字符串",
  30 + groups = {UpdateGroup.class, AddGroup.class})
  31 + private String organizationId;
32 32
33 - @ApiModelProperty(value = "组态缩略图")  
34 - private String thumbnail; 33 + @ApiModelProperty(value = "组态缩略图")
  34 + private String thumbnail;
35 35
36 - private OrganizationDTO organizationDTO;  
37 -  
38 - @ApiModelProperty(value = "视图类型")  
39 - private ViewType viewType;  
40 -  
41 - @ApiModelProperty(value = "访问凭证")  
42 - private String accessCredentials; 36 + private OrganizationDTO organizationDTO;
43 } 37 }
  1 +package org.thingsboard.server.common.data.yunteng.dto.task;
  2 +
  3 +import io.swagger.annotations.ApiModelProperty;
  4 +import lombok.Data;
  5 +import java.util.List;
  6 +import java.util.Map;
  7 +
  8 +@Data
  9 +public class TargetContentDTO {
  10 + @ApiModelProperty(value = "执行的数据:目标类型如果是产品则为deviceProfileId,如果是设备则为tbDeviceId")
  11 + List<String> data;
  12 +
  13 + @ApiModelProperty(value = "设备类型")
  14 + String deviceType;
  15 +
  16 + @ApiModelProperty(value = "组织ID")
  17 + String organizationId;
  18 +
  19 + @ApiModelProperty(value = "设备配置ID")
  20 + String deviceProfileId;
  21 +
  22 + @ApiModelProperty(value = "取消执行的数据:只有目标类型是产品时才会有值,且List<String>里面为tbDeviceId")
  23 + Map<String, List<String>> cancelExecuteDevices;
  24 +}
  1 +package org.thingsboard.server.common.data.yunteng.dto.task;
  2 +
  3 +import io.swagger.annotations.ApiModelProperty;
  4 +import lombok.Data;
  5 +import org.thingsboard.server.common.data.yunteng.enums.ExecuteTypeEnum;
  6 +
  7 +@Data
  8 +public class TaskExecuteTimeDTO {
  9 +
  10 + @ApiModelProperty(value = "执行类型")
  11 + private ExecuteTypeEnum type = ExecuteTypeEnum.CUSTOM;
  12 +
  13 + @ApiModelProperty(value = "周期类型")
  14 + private String periodType;
  15 +
  16 + @ApiModelProperty(value = "周期")
  17 + private String period;
  18 +
  19 + @ApiModelProperty(value = "时间")
  20 + private String time;
  21 +
  22 + @ApiModelProperty(value = "轮询单位:秒 分 时")
  23 + private String pollUnit;
  24 +
  25 + @ApiModelProperty(value = "cron表达式")
  26 + private String cron;
  27 +}
  1 +package org.thingsboard.server.common.data.yunteng.dto.task;
  2 +
  3 +import com.fasterxml.jackson.databind.JsonNode;
  4 +import io.swagger.annotations.ApiModelProperty;
  5 +import lombok.Data;
  6 +import org.thingsboard.server.common.data.yunteng.enums.TaskTypeEnum;
  7 +
  8 +@Data
  9 +public class TaskTypeDTO {
  10 + @ApiModelProperty(value = "类型")
  11 + private TaskTypeEnum type = TaskTypeEnum.CUSTOM;
  12 +
  13 + @ApiModelProperty(value = "推送方式:MQTT TCP")
  14 + private String pushWay;
  15 +
  16 + @ApiModelProperty(value = "推送内容:即下发的命令内容")
  17 + private JsonNode pushContent;
  18 +}
  1 +package org.thingsboard.server.common.data.yunteng.dto.task;
  2 +
  3 +import io.swagger.annotations.ApiModelProperty;
  4 +import lombok.Data;
  5 +import lombok.EqualsAndHashCode;
  6 +import org.thingsboard.server.common.data.yunteng.common.AddGroup;
  7 +import org.thingsboard.server.common.data.yunteng.constant.FastIotConstants;
  8 +import org.thingsboard.server.common.data.yunteng.dto.TenantDTO;
  9 +import org.thingsboard.server.common.data.yunteng.enums.TargetTypeEnum;
  10 +
  11 +import javax.validation.constraints.NotEmpty;
  12 +import javax.validation.constraints.NotNull;
  13 +
  14 +@Data
  15 +@EqualsAndHashCode(callSuper = true)
  16 +public class TkTaskCenterDTO extends TenantDTO {
  17 + @NotEmpty(message = "任务名称不能为空或空字符串", groups = AddGroup.class)
  18 + @ApiModelProperty(value = "任务名称")
  19 + private String name;
  20 +
  21 + @ApiModelProperty(value = "目标类型")
  22 + private TargetTypeEnum targetType = TargetTypeEnum.DEVICES;
  23 +
  24 + @NotNull(message = "执行目标不能为空", groups = AddGroup.class)
  25 + @ApiModelProperty(value = "执行目标")
  26 + private TargetContentDTO executeTarget;
  27 +
  28 + @NotNull(message = "执行内容不能为空", groups = AddGroup.class)
  29 + @ApiModelProperty(value = "执行内容")
  30 + private TaskTypeDTO executeContent;
  31 +
  32 + @ApiModelProperty(value = "执行时间")
  33 + @NotNull(message = "执行时间不能为空", groups = AddGroup.class)
  34 + private TaskExecuteTimeDTO executeTime;
  35 +
  36 + @ApiModelProperty(value = "0禁用 1启用")
  37 + private Integer state = FastIotConstants.StateValue.DISABLE;
  38 +
  39 + @ApiModelProperty(value = "备注")
  40 + private String remark;
  41 +}
  1 +package org.thingsboard.server.common.data.yunteng.enums;
  2 +
  3 +public enum ExecuteTypeEnum {
  4 + CUSTOM,
  5 + POLL
  6 +}
@@ -3,5 +3,6 @@ package org.thingsboard.server.common.data.yunteng.enums; @@ -3,5 +3,6 @@ package org.thingsboard.server.common.data.yunteng.enums;
3 public enum JobGroupEnum { 3 public enum JobGroupEnum {
4 DEFAULT, 4 DEFAULT,
5 SYSTEM, 5 SYSTEM,
6 - REPORT 6 + REPORT,
  7 + TASK_CENTER
7 } 8 }
  1 +package org.thingsboard.server.common.data.yunteng.enums;
  2 +
  3 +public enum ShareViewType {
  4 + DATA_BOARD,
  5 + SCADA,
  6 + LARGE_SCREEN
  7 +}
  1 +package org.thingsboard.server.common.data.yunteng.enums;
  2 +
  3 +public enum TargetTypeEnum {
  4 + PRODUCTS,
  5 + DEVICES
  6 +}
  1 +package org.thingsboard.server.common.data.yunteng.enums;
  2 +
  3 +public enum TaskTypeEnum {
  4 + CUSTOM,
  5 + MODBUS_RTU
  6 +}
1 /** 1 /**
2 * Copyright © 2016-2022 The Thingsboard Authors 2 * Copyright © 2016-2022 The Thingsboard Authors
3 - * <p> 3 + *
4 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License. 5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at 6 * You may obtain a copy of the License at
7 - * <p>  
8 - * http://www.apache.org/licenses/LICENSE-2.0  
9 - * <p> 7 + *
  8 + * http://www.apache.org/licenses/LICENSE-2.0
  9 + *
10 * Unless required by applicable law or agreed to in writing, software 10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS, 11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -40,6 +40,8 @@ import org.thingsboard.server.common.data.DeviceProfile; @@ -40,6 +40,8 @@ import org.thingsboard.server.common.data.DeviceProfile;
40 import org.thingsboard.server.common.data.DeviceTransportType; 40 import org.thingsboard.server.common.data.DeviceTransportType;
41 import org.thingsboard.server.common.data.device.profile.TkTcpDeviceProfileTransportConfiguration; 41 import org.thingsboard.server.common.data.device.profile.TkTcpDeviceProfileTransportConfiguration;
42 import org.thingsboard.server.common.data.id.DeviceId; 42 import org.thingsboard.server.common.data.id.DeviceId;
  43 +import org.thingsboard.server.common.data.id.OtaPackageId;
  44 +import org.thingsboard.server.common.data.ota.OtaPackageType;
43 import org.thingsboard.server.common.data.rpc.RpcStatus; 45 import org.thingsboard.server.common.data.rpc.RpcStatus;
44 import org.thingsboard.server.common.data.yunteng.enums.TkScriptFunctionType; 46 import org.thingsboard.server.common.data.yunteng.enums.TkScriptFunctionType;
45 import org.thingsboard.server.common.msg.tools.TbRateLimitsException; 47 import org.thingsboard.server.common.msg.tools.TbRateLimitsException;
@@ -63,7 +65,6 @@ import org.thingsboard.server.transport.tcp.session.TcpGatewaySessionHandler; @@ -63,7 +65,6 @@ import org.thingsboard.server.transport.tcp.session.TcpGatewaySessionHandler;
63 import org.thingsboard.server.transport.tcp.util.ByteUtils; 65 import org.thingsboard.server.transport.tcp.util.ByteUtils;
64 66
65 import java.io.IOException; 67 import java.io.IOException;
66 -import java.io.UnsupportedEncodingException;  
67 import java.net.InetSocketAddress; 68 import java.net.InetSocketAddress;
68 import java.util.List; 69 import java.util.List;
69 import java.util.Map; 70 import java.util.Map;
@@ -612,5 +613,4 @@ public class TcpTransportHandler extends ChannelInboundHandlerAdapter implements @@ -612,5 +613,4 @@ public class TcpTransportHandler extends ChannelInboundHandlerAdapter implements
612 ChannelHandlerContext ctx = deviceSessionCtx.getChannel(); 613 ChannelHandlerContext ctx = deviceSessionCtx.getChannel();
613 ctx.close(); 614 ctx.close();
614 } 615 }
615 -  
616 } 616 }
@@ -44,6 +44,8 @@ public class ByteUtils { @@ -44,6 +44,8 @@ public class ByteUtils {
44 '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'}; 44 '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
45 45
46 public static final String UTF_8 = "UTF-8"; 46 public static final String UTF_8 = "UTF-8";
  47 +
  48 + private static String hexString="0123456789ABCDEF";
47 /** 49 /**
48 * 将short整型数值转换为字节数组 50 * 将short整型数值转换为字节数组
49 * 51 *
@@ -802,4 +804,64 @@ public class ByteUtils { @@ -802,4 +804,64 @@ public class ByteUtils {
802 int highByte = (src & 0x00FF) << 8; 804 int highByte = (src & 0x00FF) << 8;
803 return lowByte | highByte; 805 return lowByte | highByte;
804 } 806 }
  807 +
  808 + /**
  809 + * 将字符串编码成16进制数字,适用于所有字符(包括中文)
  810 + * @param str 字符串
  811 + * @return
  812 + */
  813 + public static String stringEncodeToHex(String str) {
  814 + //根据默认编码获取字节数组
  815 + byte[] bytes=str.getBytes();
  816 + StringBuilder sb=new StringBuilder(bytes.length*2);
  817 + //将字节数组中每个字节拆解成2位16进制整数
  818 + for(int i=0;i<bytes.length;i++)
  819 + {
  820 + sb.append(hexString.charAt((bytes[i]&0xf0)>>4));
  821 + sb.append(hexString.charAt((bytes[i]&0x0f)>>0));
  822 + }
  823 + return sb.toString();
  824 +
  825 + }
  826 +
  827 + /**
  828 + * 将16进制数字解码成字符串,适用于所有字符(包括中文)
  829 + * @param hex 16进制
  830 + * @return
  831 + */
  832 + public static String hexDecodeToString(String hex) {
  833 + try{
  834 + byte[] baKeyword = new byte[hex.length()/2];
  835 + for(int i = 0; i < baKeyword.length; i++) {
  836 + baKeyword[i] = (byte)(0xff & Integer.parseInt(hex.substring(i*2, i*2+2),16));
  837 + }
  838 + return new String(baKeyword,"UTF-8");
  839 + }catch (UnsupportedEncodingException e){
  840 + return null;
  841 + }
  842 + }
  843 +
  844 + public static byte[] hexToByteArray(String inHex){
  845 + inHex.replace(" ","");
  846 + int hexlen = inHex.length();
  847 + byte[] result;
  848 + if (hexlen % 2 == 1){
  849 + //奇数
  850 + hexlen++;
  851 + result = new byte[(hexlen/2)];
  852 + inHex="0"+inHex;
  853 + }else {
  854 + //偶数
  855 + result = new byte[(hexlen/2)];
  856 + }
  857 + int j=0;
  858 + for (int i = 0; i < hexlen; i+=2){
  859 + result[j]=hexToByte(inHex.substring(i,i+2));
  860 + j++;
  861 + }
  862 + return result;
  863 + }
  864 + public static byte hexToByte(String inHex){
  865 + return (byte)Integer.parseInt(inHex,16);
  866 + }
805 } 867 }
@@ -5,7 +5,9 @@ import com.baomidou.mybatisplus.annotation.TableField; @@ -5,7 +5,9 @@ import com.baomidou.mybatisplus.annotation.TableField;
5 import com.baomidou.mybatisplus.annotation.TableName; 5 import com.baomidou.mybatisplus.annotation.TableName;
6 import lombok.Data; 6 import lombok.Data;
7 import lombok.EqualsAndHashCode; 7 import lombok.EqualsAndHashCode;
  8 +import org.apache.ibatis.type.EnumTypeHandler;
8 import org.thingsboard.server.common.data.yunteng.constant.ModelConstants; 9 import org.thingsboard.server.common.data.yunteng.constant.ModelConstants;
  10 +import org.thingsboard.server.common.data.yunteng.enums.ViewType;
9 11
10 @EqualsAndHashCode(callSuper = true) 12 @EqualsAndHashCode(callSuper = true)
11 @TableName(ModelConstants.Table.TK_CONFIGURATION_CENTER_NAME) 13 @TableName(ModelConstants.Table.TK_CONFIGURATION_CENTER_NAME)
@@ -16,6 +18,13 @@ public class TkConfigurationCenterEntity extends TenantBaseEntity { @@ -16,6 +18,13 @@ public class TkConfigurationCenterEntity extends TenantBaseEntity {
16 private String remark; 18 private String remark;
17 private String organizationId; 19 private String organizationId;
18 private String platform; 20 private String platform;
  21 +
19 @TableField(updateStrategy = FieldStrategy.IGNORED) 22 @TableField(updateStrategy = FieldStrategy.IGNORED)
20 private String thumbnail; 23 private String thumbnail;
  24 +
  25 + @TableField(typeHandler = EnumTypeHandler.class)
  26 + private ViewType viewType;
  27 +
  28 + @TableField(updateStrategy = FieldStrategy.IGNORED)
  29 + private String accessCredentials;
21 } 30 }
1 package org.thingsboard.server.dao.yunteng.entities; 1 package org.thingsboard.server.dao.yunteng.entities;
2 2
  3 +import com.baomidou.mybatisplus.annotation.FieldStrategy;
3 import com.baomidou.mybatisplus.annotation.TableField; 4 import com.baomidou.mybatisplus.annotation.TableField;
4 import com.baomidou.mybatisplus.annotation.TableName; 5 import com.baomidou.mybatisplus.annotation.TableName;
5 import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler; 6 import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
@@ -30,4 +31,7 @@ public class TkDataBoardEntity extends TenantBaseEntity { @@ -30,4 +31,7 @@ public class TkDataBoardEntity extends TenantBaseEntity {
30 private Integer componentNum; 31 private Integer componentNum;
31 32
32 private String organizationId; 33 private String organizationId;
  34 +
  35 + @TableField(updateStrategy = FieldStrategy.IGNORED)
  36 + private String accessCredentials;
33 } 37 }
@@ -25,5 +25,6 @@ public class TkDataViewEntity extends TenantBaseEntity { @@ -25,5 +25,6 @@ public class TkDataViewEntity extends TenantBaseEntity {
25 @TableField(typeHandler = EnumTypeHandler.class) 25 @TableField(typeHandler = EnumTypeHandler.class)
26 private ViewType viewType; 26 private ViewType viewType;
27 27
  28 + @TableField(updateStrategy = FieldStrategy.IGNORED)
28 private String accessCredentials; 29 private String accessCredentials;
29 } 30 }
  1 +package org.thingsboard.server.dao.yunteng.entities;
  2 +
  3 +import com.baomidou.mybatisplus.annotation.TableField;
  4 +import com.baomidou.mybatisplus.annotation.TableName;
  5 +import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
  6 +import com.fasterxml.jackson.databind.JsonNode;
  7 +import lombok.Data;
  8 +import lombok.EqualsAndHashCode;
  9 +import org.apache.ibatis.type.EnumTypeHandler;
  10 +import org.thingsboard.server.common.data.yunteng.constant.ModelConstants;
  11 +import org.thingsboard.server.common.data.yunteng.enums.TargetTypeEnum;
  12 +
  13 +@Data
  14 +@EqualsAndHashCode(callSuper = true)
  15 +@TableName(value = ModelConstants.Table.TK_TASK_CENTER_NAME, autoResultMap = true)
  16 +public class TkTaskCenterEntity extends TenantBaseEntity {
  17 + private String name;
  18 +
  19 + @TableField(typeHandler = EnumTypeHandler.class)
  20 + private TargetTypeEnum targetType;
  21 +
  22 + @TableField(typeHandler = JacksonTypeHandler.class)
  23 + private JsonNode executeTarget;
  24 +
  25 + @TableField(typeHandler = JacksonTypeHandler.class)
  26 + private JsonNode executeContent;
  27 +
  28 + @TableField(typeHandler = JacksonTypeHandler.class)
  29 + private JsonNode executeTime;
  30 +
  31 + private Integer state;
  32 +
  33 + private String remark;
  34 +}
@@ -8,6 +8,7 @@ import org.springframework.cache.CacheManager; @@ -8,6 +8,7 @@ import org.springframework.cache.CacheManager;
8 import org.springframework.stereotype.Service; 8 import org.springframework.stereotype.Service;
9 import org.thingsboard.server.common.data.yunteng.constant.FastIotConstants; 9 import org.thingsboard.server.common.data.yunteng.constant.FastIotConstants;
10 import org.thingsboard.server.common.data.yunteng.dto.SysAreaDTO; 10 import org.thingsboard.server.common.data.yunteng.dto.SysAreaDTO;
  11 +import org.thingsboard.server.common.data.yunteng.enums.AreaLevelEnum;
11 import org.thingsboard.server.common.data.yunteng.utils.ReflectUtils; 12 import org.thingsboard.server.common.data.yunteng.utils.ReflectUtils;
12 import org.thingsboard.server.dao.yunteng.entities.SysAreaEntity; 13 import org.thingsboard.server.dao.yunteng.entities.SysAreaEntity;
13 import org.thingsboard.server.dao.yunteng.mapper.SysAreaMapper; 14 import org.thingsboard.server.dao.yunteng.mapper.SysAreaMapper;
@@ -30,37 +31,47 @@ public class SysAreaServiceImpl implements SysAreaService { @@ -30,37 +31,47 @@ public class SysAreaServiceImpl implements SysAreaService {
30 @Override 31 @Override
31 public List<SysAreaDTO> list(SysAreaDTO sysAreaDTO) { 32 public List<SysAreaDTO> list(SysAreaDTO sysAreaDTO) {
32 String areaKey = sysAreaDTO.getParentId() + "-" + sysAreaDTO.getLevel(); 33 String areaKey = sysAreaDTO.getParentId() + "-" + sysAreaDTO.getLevel();
33 - List<SysAreaDTO> result = cacheManager.getCache(FastIotConstants.CacheConfigKey.AREA).get(areaKey,List.class);  
34 - if(result == null || result.isEmpty()){  
35 - result = ReflectUtils.sourceToTarget( 34 + List<SysAreaDTO> result =
  35 + cacheManager.getCache(FastIotConstants.CacheConfigKey.AREA).get(areaKey, List.class);
  36 + if (result == null || result.isEmpty()) {
  37 + result =
  38 + ReflectUtils.sourceToTarget(
36 sysAreaMapper.selectList( 39 sysAreaMapper.selectList(
37 - new LambdaQueryWrapper<SysAreaEntity>()  
38 - .eq(sysAreaDTO.getLevel() != null, SysAreaEntity::getLevel, sysAreaDTO.getLevel())  
39 - .eq(  
40 - sysAreaDTO.getParentId() != null,  
41 - SysAreaEntity::getParentId,  
42 - sysAreaDTO.getParentId())  
43 - .eq(sysAreaDTO.getCode() != null, SysAreaEntity::getCode, sysAreaDTO.getCode())  
44 - .like(  
45 - StringUtils.isNotEmpty(sysAreaDTO.getName()),  
46 - SysAreaEntity::getName,  
47 - sysAreaDTO.getName())), 40 + new LambdaQueryWrapper<SysAreaEntity>()
  41 + .eq(
  42 + sysAreaDTO.getLevel() != null,
  43 + SysAreaEntity::getLevel,
  44 + sysAreaDTO.getLevel())
  45 + .eq(
  46 + sysAreaDTO.getParentId() != null,
  47 + SysAreaEntity::getParentId,
  48 + sysAreaDTO.getParentId())
  49 + .eq(
  50 + sysAreaDTO.getCode() != null,
  51 + SysAreaEntity::getCode,
  52 + sysAreaDTO.getCode())
  53 + .like(
  54 + StringUtils.isNotEmpty(sysAreaDTO.getName()),
  55 + SysAreaEntity::getName,
  56 + sysAreaDTO.getName())),
48 SysAreaDTO.class); 57 SysAreaDTO.class);
49 - cacheManager.getCache(FastIotConstants.CacheConfigKey.AREA).put(areaKey,result); 58 + cacheManager.getCache(FastIotConstants.CacheConfigKey.AREA).put(areaKey, result);
50 } 59 }
51 60
52 -  
53 return result; 61 return result;
54 } 62 }
55 63
56 @Override 64 @Override
57 - public SysAreaDTO getSysAreaInfoByCode(Long code) { 65 + public SysAreaDTO getSysAreaInfoByCode(Long code, AreaLevelEnum levelEnum) {
58 if (null == code) { 66 if (null == code) {
59 return null; 67 return null;
60 } 68 }
61 SysAreaDTO target = new SysAreaDTO(); 69 SysAreaDTO target = new SysAreaDTO();
62 SysAreaEntity source = 70 SysAreaEntity source =
63 - sysAreaMapper.selectOne(new LambdaQueryWrapper<SysAreaEntity>().eq(SysAreaEntity::getCode, code)); 71 + sysAreaMapper.selectOne(
  72 + new LambdaQueryWrapper<SysAreaEntity>()
  73 + .eq(SysAreaEntity::getCode, code)
  74 + .eq(SysAreaEntity::getLevel, levelEnum));
64 if (null != source) { 75 if (null != source) {
65 BeanUtils.copyProperties(source, target); 76 BeanUtils.copyProperties(source, target);
66 } 77 }
@@ -10,6 +10,7 @@ import org.thingsboard.server.common.data.yunteng.core.message.ErrorMessage; @@ -10,6 +10,7 @@ import org.thingsboard.server.common.data.yunteng.core.message.ErrorMessage;
10 import org.thingsboard.server.common.data.yunteng.dto.SysAreaDTO; 10 import org.thingsboard.server.common.data.yunteng.dto.SysAreaDTO;
11 import org.thingsboard.server.common.data.yunteng.dto.SysEnterpriseDTO; 11 import org.thingsboard.server.common.data.yunteng.dto.SysEnterpriseDTO;
12 import org.thingsboard.server.common.data.yunteng.dto.AreaInfoDTO; 12 import org.thingsboard.server.common.data.yunteng.dto.AreaInfoDTO;
  13 +import org.thingsboard.server.common.data.yunteng.enums.AreaLevelEnum;
13 import org.thingsboard.server.dao.yunteng.entities.SysEnterpriseEntity; 14 import org.thingsboard.server.dao.yunteng.entities.SysEnterpriseEntity;
14 import org.thingsboard.server.dao.yunteng.mapper.SysEnterpriseMapper; 15 import org.thingsboard.server.dao.yunteng.mapper.SysEnterpriseMapper;
15 import org.thingsboard.server.dao.yunteng.service.AbstractBaseService; 16 import org.thingsboard.server.dao.yunteng.service.AbstractBaseService;
@@ -34,7 +35,8 @@ public class SysEnterpriseServiceImpl @@ -34,7 +35,8 @@ public class SysEnterpriseServiceImpl
34 public boolean save(SysEnterpriseDTO sysAppDesignDTO, String tenantId) { 35 public boolean save(SysEnterpriseDTO sysAppDesignDTO, String tenantId) {
35 SysEnterpriseEntity checkSysEnterprise = 36 SysEnterpriseEntity checkSysEnterprise =
36 baseMapper.selectOne( 37 baseMapper.selectOne(
37 - new LambdaQueryWrapper<SysEnterpriseEntity>().eq(SysEnterpriseEntity::getTenantId, tenantId)); 38 + new LambdaQueryWrapper<SysEnterpriseEntity>()
  39 + .eq(SysEnterpriseEntity::getTenantId, tenantId));
38 if (null != checkSysEnterprise) { 40 if (null != checkSysEnterprise) {
39 throw new TkDataValidationException(ErrorMessage.DATA_ALREADY_EXISTS.getMessage()); 41 throw new TkDataValidationException(ErrorMessage.DATA_ALREADY_EXISTS.getMessage());
40 } 42 }
@@ -51,19 +53,24 @@ public class SysEnterpriseServiceImpl @@ -51,19 +53,24 @@ public class SysEnterpriseServiceImpl
51 } 53 }
52 if (null != sysEnterpriseDTO.getCodeTown()) { 54 if (null != sysEnterpriseDTO.getCodeTown()) {
53 AreaInfoDTO sourceArea = new AreaInfoDTO(); 55 AreaInfoDTO sourceArea = new AreaInfoDTO();
54 - SysAreaDTO town = sysAreaService.getSysAreaInfoByCode(sysEnterpriseDTO.getCodeTown()); 56 + SysAreaDTO town =
  57 + sysAreaService.getSysAreaInfoByCode(sysEnterpriseDTO.getCodeTown(), AreaLevelEnum.TOWN);
55 sourceArea.setNameTown(town.getName()); 58 sourceArea.setNameTown(town.getName());
56 sourceArea.setCodeTown(town.getCode()); 59 sourceArea.setCodeTown(town.getCode());
57 - SysAreaDTO county = sysAreaService.getSysAreaInfoByCode(town.getParentId()); 60 + SysAreaDTO county =
  61 + sysAreaService.getSysAreaInfoByCode(town.getParentId(), AreaLevelEnum.COUNTY);
58 sourceArea.setNameCoun(county.getName()); 62 sourceArea.setNameCoun(county.getName());
59 sourceArea.setCodeCoun(county.getCode()); 63 sourceArea.setCodeCoun(county.getCode());
60 - SysAreaDTO city = sysAreaService.getSysAreaInfoByCode(county.getParentId()); 64 + SysAreaDTO city =
  65 + sysAreaService.getSysAreaInfoByCode(county.getParentId(), AreaLevelEnum.CITY);
61 sourceArea.setNameCity(city.getName()); 66 sourceArea.setNameCity(city.getName());
62 sourceArea.setCodeCity(city.getCode()); 67 sourceArea.setCodeCity(city.getCode());
63 - SysAreaDTO province = sysAreaService.getSysAreaInfoByCode(city.getParentId()); 68 + SysAreaDTO province =
  69 + sysAreaService.getSysAreaInfoByCode(city.getParentId(), AreaLevelEnum.PROVINCE);
64 sourceArea.setNameProv(province.getName()); 70 sourceArea.setNameProv(province.getName());
65 sourceArea.setCodeProv(province.getCode()); 71 sourceArea.setCodeProv(province.getCode());
66 - SysAreaDTO country = sysAreaService.getSysAreaInfoByCode(province.getParentId()); 72 + SysAreaDTO country =
  73 + sysAreaService.getSysAreaInfoByCode(province.getParentId(), AreaLevelEnum.COUNTRY);
67 sourceArea.setNameCountry(country.getName()); 74 sourceArea.setNameCountry(country.getName());
68 sourceArea.setCodeCountry(country.getCode()); 75 sourceArea.setCodeCountry(country.getCode());
69 76
@@ -98,7 +105,8 @@ public class SysEnterpriseServiceImpl @@ -98,7 +105,8 @@ public class SysEnterpriseServiceImpl
98 if (sysAppDesignDTO.getId() != null) { 105 if (sysAppDesignDTO.getId() != null) {
99 return baseMapper.update( 106 return baseMapper.update(
100 sysAppDesignDTO.getEntity(SysEnterpriseEntity.class), 107 sysAppDesignDTO.getEntity(SysEnterpriseEntity.class),
101 - new LambdaQueryWrapper<SysEnterpriseEntity>().eq(SysEnterpriseEntity::getTenantId, tenantId)) 108 + new LambdaQueryWrapper<SysEnterpriseEntity>()
  109 + .eq(SysEnterpriseEntity::getTenantId, tenantId))
102 > 0; 110 > 0;
103 } else { 111 } else {
104 return save(sysAppDesignDTO, tenantId); 112 return save(sysAppDesignDTO, tenantId);
@@ -2,6 +2,8 @@ package org.thingsboard.server.dao.yunteng.impl; @@ -2,6 +2,8 @@ package org.thingsboard.server.dao.yunteng.impl;
2 2
3 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; 3 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
4 import com.baomidou.mybatisplus.core.metadata.IPage; 4 import com.baomidou.mybatisplus.core.metadata.IPage;
  5 +import com.google.common.util.concurrent.Futures;
  6 +import com.google.common.util.concurrent.ListenableFuture;
5 import lombok.RequiredArgsConstructor; 7 import lombok.RequiredArgsConstructor;
6 import org.apache.commons.lang3.StringUtils; 8 import org.apache.commons.lang3.StringUtils;
7 import org.quartz.*; 9 import org.quartz.*;
@@ -15,12 +17,14 @@ import org.thingsboard.server.common.data.yunteng.enums.StatusEnum; @@ -15,12 +17,14 @@ import org.thingsboard.server.common.data.yunteng.enums.StatusEnum;
15 import org.thingsboard.server.common.data.yunteng.utils.tools.TkPageData; 17 import org.thingsboard.server.common.data.yunteng.utils.tools.TkPageData;
16 import org.thingsboard.server.dao.util.yunteng.CronUtils; 18 import org.thingsboard.server.dao.util.yunteng.CronUtils;
17 import org.thingsboard.server.dao.util.yunteng.ScheduleUtils; 19 import org.thingsboard.server.dao.util.yunteng.ScheduleUtils;
  20 +import org.thingsboard.server.dao.yunteng.entities.BaseEntity;
18 import org.thingsboard.server.dao.yunteng.entities.SysJobEntity; 21 import org.thingsboard.server.dao.yunteng.entities.SysJobEntity;
19 import org.thingsboard.server.dao.yunteng.mapper.SysJobMapper; 22 import org.thingsboard.server.dao.yunteng.mapper.SysJobMapper;
20 import org.thingsboard.server.dao.yunteng.service.*; 23 import org.thingsboard.server.dao.yunteng.service.*;
21 24
22 import javax.annotation.PostConstruct; 25 import javax.annotation.PostConstruct;
23 import java.util.*; 26 import java.util.*;
  27 +import java.util.stream.Collectors;
24 28
25 /** 定时任务调度信息 服务层 */ 29 /** 定时任务调度信息 服务层 */
26 @Service 30 @Service
@@ -35,10 +39,12 @@ public class SysJobServiceImpl extends AbstractBaseService<SysJobMapper, SysJobE @@ -35,10 +39,12 @@ public class SysJobServiceImpl extends AbstractBaseService<SysJobMapper, SysJobE
35 scheduler.clear(); 39 scheduler.clear();
36 List<SysJobEntity> jobList = new ArrayList<>(); 40 List<SysJobEntity> jobList = new ArrayList<>();
37 try { 41 try {
38 - jobList.addAll(baseMapper.selectList(  
39 - new LambdaQueryWrapper<SysJobEntity>().eq(SysJobEntity::getStatus, StatusEnum.ENABLE.getIndex())));  
40 - }catch (Exception e){  
41 - //TODO: 兼容ThingsboardInstallApplication。执行数据库脚本前,会跑表不存在异常。 42 + jobList.addAll(
  43 + baseMapper.selectList(
  44 + new LambdaQueryWrapper<SysJobEntity>()
  45 + .eq(SysJobEntity::getStatus, StatusEnum.ENABLE.getIndex())));
  46 + } catch (Exception e) {
  47 + // TODO: 兼容ThingsboardInstallApplication。执行数据库脚本前,会跑表不存在异常。
42 } 48 }
43 49
44 for (SysJobEntity job : jobList) { 50 for (SysJobEntity job : jobList) {
@@ -72,15 +78,22 @@ public class SysJobServiceImpl extends AbstractBaseService<SysJobMapper, SysJobE @@ -72,15 +78,22 @@ public class SysJobServiceImpl extends AbstractBaseService<SysJobMapper, SysJobE
72 public SysJobDTO selectJobById(String id) { 78 public SysJobDTO selectJobById(String id) {
73 79
74 return Optional.ofNullable( 80 return Optional.ofNullable(
75 - baseMapper.selectOne(new LambdaQueryWrapper<SysJobEntity>().eq(SysJobEntity::getId, id))) 81 + baseMapper.selectOne(
  82 + new LambdaQueryWrapper<SysJobEntity>().eq(SysJobEntity::getId, id)))
76 .map(obj -> obj.getDTO(SysJobDTO.class)) 83 .map(obj -> obj.getDTO(SysJobDTO.class))
77 .orElseThrow( 84 .orElseThrow(
78 - () -> {  
79 - throw new TkDataValidationException(  
80 - ErrorMessage.NOT_BELONG_CURRENT_TENANT.getMessage());  
81 - }); 85 + () ->
  86 + new TkDataValidationException(ErrorMessage.NOT_BELONG_CURRENT_TENANT.getMessage()));
82 } 87 }
83 88
  89 + @Override
  90 + public ListenableFuture<SysJobDTO> selectJobInfoById(String id) {
  91 + return Optional.ofNullable(
  92 + baseMapper.selectOne(
  93 + new LambdaQueryWrapper<SysJobEntity>().eq(SysJobEntity::getId, id)))
  94 + .map(obj -> Futures.immediateFuture(obj.getDTO(SysJobDTO.class)))
  95 + .orElse(Futures.immediateFuture(null));
  96 + }
84 /** 97 /**
85 * 暂停任务 98 * 暂停任务
86 * 99 *
@@ -130,6 +143,40 @@ public class SysJobServiceImpl extends AbstractBaseService<SysJobMapper, SysJobE @@ -130,6 +143,40 @@ public class SysJobServiceImpl extends AbstractBaseService<SysJobMapper, SysJobE
130 } 143 }
131 return rows > 0; 144 return rows > 0;
132 } 145 }
  146 + /**
  147 + * 批量删除任务后,所对应的trigger也将被删除
  148 + *
  149 + * @param sourceIds 源ID
  150 + * @param jobGroup 分组
  151 + * @param tenantId 租户ID
  152 + */
  153 + @Override
  154 + @Transactional(rollbackFor = Exception.class)
  155 + public boolean deleteJobs(List<String> sourceIds, String jobGroup, String tenantId)
  156 + throws SchedulerException {
  157 + List<String> jobIds =
  158 + Optional.ofNullable(
  159 + baseMapper.selectList(
  160 + new LambdaQueryWrapper<SysJobEntity>()
  161 + .eq(SysJobEntity::getTenantId, tenantId)
  162 + .eq(SysJobEntity::getJobGroup, jobGroup)
  163 + .in(SysJobEntity::getSourceId, sourceIds)))
  164 + .map(list -> list.stream().map(BaseEntity::getId).collect(Collectors.toList()))
  165 + .orElse(null);
  166 + if (null != jobIds && !jobIds.isEmpty()) {
  167 + int rows = baseMapper.deleteBatchIds(jobIds);
  168 + if (rows > 0) {
  169 + List<JobKey> jobKeys = new ArrayList<>();
  170 + for (String jobId : jobIds) {
  171 + jobKeys.add(ScheduleUtils.getJobKey(jobId, jobGroup));
  172 + }
  173 + if (!jobKeys.isEmpty()) {
  174 + return scheduler.deleteJobs(jobKeys);
  175 + }
  176 + }
  177 + }
  178 + return false;
  179 + }
133 180
134 /** 181 /**
135 * 批量删除调度信息 182 * 批量删除调度信息
@@ -12,6 +12,7 @@ import org.thingsboard.server.common.data.yunteng.core.exception.TkDataValidatio @@ -12,6 +12,7 @@ import org.thingsboard.server.common.data.yunteng.core.exception.TkDataValidatio
12 import org.thingsboard.server.common.data.yunteng.core.message.ErrorMessage; 12 import org.thingsboard.server.common.data.yunteng.core.message.ErrorMessage;
13 import org.thingsboard.server.common.data.yunteng.dto.*; 13 import org.thingsboard.server.common.data.yunteng.dto.*;
14 import org.thingsboard.server.common.data.yunteng.dto.request.ConfigurationContentInfoDTO; 14 import org.thingsboard.server.common.data.yunteng.dto.request.ConfigurationContentInfoDTO;
  15 +import org.thingsboard.server.common.data.yunteng.enums.ViewType;
15 import org.thingsboard.server.common.data.yunteng.utils.tools.TkPageData; 16 import org.thingsboard.server.common.data.yunteng.utils.tools.TkPageData;
16 import org.thingsboard.server.dao.yunteng.entities.TkConfigurationCenterEntity; 17 import org.thingsboard.server.dao.yunteng.entities.TkConfigurationCenterEntity;
17 import org.thingsboard.server.dao.yunteng.mapper.ConfigurationCenterMapper; 18 import org.thingsboard.server.dao.yunteng.mapper.ConfigurationCenterMapper;
@@ -128,4 +129,52 @@ public class TkConfigurationCenterServiceImpl @@ -128,4 +129,52 @@ public class TkConfigurationCenterServiceImpl
128 ? list.get(FastIotConstants.MagicNumber.ZERO) 129 ? list.get(FastIotConstants.MagicNumber.ZERO)
129 : null; 130 : null;
130 } 131 }
  132 +
  133 + @Override
  134 + public ConfigurationCenterDTO getConfigurationCenterInfoById(String id, String tenantId) {
  135 + TkConfigurationCenterEntity entity =
  136 + baseMapper.selectOne(
  137 + new LambdaQueryWrapper<TkConfigurationCenterEntity>()
  138 + .eq(TkConfigurationCenterEntity::getTenantId, tenantId)
  139 + .eq(TkConfigurationCenterEntity::getId, id));
  140 + if (null == entity) {
  141 + throw new TkDataValidationException(ErrorMessage.INVALID_PARAMETER.getMessage());
  142 + }
  143 + return entity.getDTO(ConfigurationCenterDTO.class);
  144 + }
  145 +
  146 + @Override
  147 + public boolean isNeedCredentialsForPublicView(String id, String tenantId) {
  148 + TkConfigurationCenterEntity entity =
  149 + baseMapper.selectOne(
  150 + new LambdaQueryWrapper<TkConfigurationCenterEntity>()
  151 + .eq(TkConfigurationCenterEntity::getTenantId, tenantId)
  152 + .eq(TkConfigurationCenterEntity::getId, id));
  153 + if (null == entity) {
  154 + throw new TkDataValidationException(ErrorMessage.INVALID_PARAMETER.getMessage());
  155 + }
  156 + return StringUtils.isNotEmpty(entity.getAccessCredentials());
  157 + }
  158 +
  159 + @Override
  160 + @Transactional
  161 + public boolean shareOrMonopolyConfigurationCenter(
  162 + boolean isShare, String id, String accessCredentials, String tenantId) {
  163 + TkConfigurationCenterEntity entity =
  164 + baseMapper.selectOne(
  165 + new LambdaQueryWrapper<TkConfigurationCenterEntity>()
  166 + .eq(TkConfigurationCenterEntity::getTenantId, tenantId)
  167 + .eq(TkConfigurationCenterEntity::getId, id));
  168 + if (null == entity) {
  169 + throw new TkDataValidationException(ErrorMessage.INVALID_PARAMETER.getMessage());
  170 + }
  171 + if (isShare) {
  172 + entity.setViewType(ViewType.PUBLIC_VIEW);
  173 + entity.setAccessCredentials(accessCredentials);
  174 + } else {
  175 + entity.setViewType(ViewType.PRIVATE_VIEW);
  176 + entity.setAccessCredentials(null);
  177 + }
  178 + return baseMapper.updateById(entity) > FastIotConstants.MagicNumber.ZERO;
  179 + }
131 } 180 }
@@ -12,6 +12,7 @@ import org.thingsboard.server.common.data.yunteng.core.exception.TkDataValidatio @@ -12,6 +12,7 @@ import org.thingsboard.server.common.data.yunteng.core.exception.TkDataValidatio
12 import org.thingsboard.server.common.data.yunteng.core.message.ErrorMessage; 12 import org.thingsboard.server.common.data.yunteng.core.message.ErrorMessage;
13 import org.thingsboard.server.common.data.yunteng.dto.*; 13 import org.thingsboard.server.common.data.yunteng.dto.*;
14 import org.thingsboard.server.common.data.yunteng.dto.board.ComponentLayoutDTO; 14 import org.thingsboard.server.common.data.yunteng.dto.board.ComponentLayoutDTO;
  15 +import org.thingsboard.server.common.data.yunteng.enums.ViewType;
15 import org.thingsboard.server.common.data.yunteng.utils.JacksonUtil; 16 import org.thingsboard.server.common.data.yunteng.utils.JacksonUtil;
16 import org.thingsboard.server.common.data.yunteng.utils.tools.TkPageData; 17 import org.thingsboard.server.common.data.yunteng.utils.tools.TkPageData;
17 import org.thingsboard.server.dao.yunteng.entities.TkDataBoardEntity; 18 import org.thingsboard.server.dao.yunteng.entities.TkDataBoardEntity;
@@ -82,12 +83,11 @@ public class TkDataBoardServiceImpl extends AbstractBaseService<DataBoardMapper, @@ -82,12 +83,11 @@ public class TkDataBoardServiceImpl extends AbstractBaseService<DataBoardMapper,
82 @Transactional 83 @Transactional
83 public DataBoardDTO saveOrUpdateDataBoard(DataBoardDTO dataBoardDTO) { 84 public DataBoardDTO saveOrUpdateDataBoard(DataBoardDTO dataBoardDTO) {
84 TkDataBoardEntity dataBoard = dataBoardDTO.getEntity(TkDataBoardEntity.class); 85 TkDataBoardEntity dataBoard = dataBoardDTO.getEntity(TkDataBoardEntity.class);
  86 + if(dataBoardDTO.getViewType().equals(ViewType.PRIVATE_VIEW)){
  87 + dataBoard.setAccessCredentials(null);
  88 + }
85 if (StringUtils.isEmpty(dataBoardDTO.getId())) { 89 if (StringUtils.isEmpty(dataBoardDTO.getId())) {
86 - try {  
87 - baseMapper.insert(dataBoard);  
88 - } catch (Exception e) {  
89 - e.printStackTrace();  
90 - } 90 + baseMapper.insert(dataBoard);
91 } else { 91 } else {
92 if (null != dataBoardDTO.getLayout() && !dataBoardDTO.getLayout().isEmpty()) { 92 if (null != dataBoardDTO.getLayout() && !dataBoardDTO.getLayout().isEmpty()) {
93 dataBoard.setLayout(JacksonUtil.convertValue(dataBoardDTO.getLayout(), JsonNode.class)); 93 dataBoard.setLayout(JacksonUtil.convertValue(dataBoardDTO.getLayout(), JsonNode.class));
@@ -111,9 +111,9 @@ public class TkDataBoardServiceImpl extends AbstractBaseService<DataBoardMapper, @@ -111,9 +111,9 @@ public class TkDataBoardServiceImpl extends AbstractBaseService<DataBoardMapper,
111 @Transactional 111 @Transactional
112 public boolean deleteDataBoard(DeleteDTO deleteDTO) { 112 public boolean deleteDataBoard(DeleteDTO deleteDTO) {
113 dataComponentMapper.delete( 113 dataComponentMapper.delete(
114 - new LambdaQueryWrapper<TkDataComponentEntity>()  
115 - .eq(TkDataComponentEntity::getTenantId, deleteDTO.getTenantId())  
116 - .in(TkDataComponentEntity::getDataBoardId, deleteDTO.getIds())); 114 + new LambdaQueryWrapper<TkDataComponentEntity>()
  115 + .eq(TkDataComponentEntity::getTenantId, deleteDTO.getTenantId())
  116 + .in(TkDataComponentEntity::getDataBoardId, deleteDTO.getIds()));
117 return baseMapper.delete( 117 return baseMapper.delete(
118 new LambdaQueryWrapper<TkDataBoardEntity>() 118 new LambdaQueryWrapper<TkDataBoardEntity>()
119 .eq(TkDataBoardEntity::getTenantId, deleteDTO.getTenantId()) 119 .eq(TkDataBoardEntity::getTenantId, deleteDTO.getTenantId())
@@ -170,4 +170,38 @@ public class TkDataBoardServiceImpl extends AbstractBaseService<DataBoardMapper, @@ -170,4 +170,38 @@ public class TkDataBoardServiceImpl extends AbstractBaseService<DataBoardMapper,
170 public boolean updateDataBoardComponentNum(String id, String tenantId, int count) { 170 public boolean updateDataBoardComponentNum(String id, String tenantId, int count) {
171 return baseMapper.updateDataBoardComponentNum(id, tenantId, count); 171 return baseMapper.updateDataBoardComponentNum(id, tenantId, count);
172 } 172 }
  173 +
  174 + @Override
  175 + public boolean isNeedCredentialsForPublicView(String id, String tenantId) {
  176 + TkDataBoardEntity entity =
  177 + baseMapper.selectOne(
  178 + new LambdaQueryWrapper<TkDataBoardEntity>()
  179 + .eq(TkDataBoardEntity::getTenantId, tenantId)
  180 + .eq(TkDataBoardEntity::getId, id));
  181 + if (null == entity) {
  182 + throw new TkDataValidationException(ErrorMessage.INVALID_PARAMETER.getMessage());
  183 + }
  184 + return StringUtils.isNotEmpty(entity.getAccessCredentials());
  185 + }
  186 +
  187 + @Override
  188 + public boolean shareOrMonopolyDataBoard(
  189 + boolean isShare, String id, String accessCredentials, String tenantId) {
  190 + TkDataBoardEntity entity =
  191 + baseMapper.selectOne(
  192 + new LambdaQueryWrapper<TkDataBoardEntity>()
  193 + .eq(TkDataBoardEntity::getTenantId, tenantId)
  194 + .eq(TkDataBoardEntity::getId, id));
  195 + if (null == entity) {
  196 + throw new TkDataValidationException(ErrorMessage.INVALID_PARAMETER.getMessage());
  197 + }
  198 + if (isShare) {
  199 + entity.setViewType(ViewType.PUBLIC_VIEW);
  200 + entity.setAccessCredentials(accessCredentials);
  201 + } else {
  202 + entity.setViewType(ViewType.PRIVATE_VIEW);
  203 + entity.setAccessCredentials(null);
  204 + }
  205 + return baseMapper.updateById(entity) > FastIotConstants.MagicNumber.ZERO;
  206 + }
173 } 207 }
@@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; @@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
4 import com.baomidou.mybatisplus.core.metadata.IPage; 4 import com.baomidou.mybatisplus.core.metadata.IPage;
5 import lombok.RequiredArgsConstructor; 5 import lombok.RequiredArgsConstructor;
6 import lombok.extern.slf4j.Slf4j; 6 import lombok.extern.slf4j.Slf4j;
  7 +import org.apache.commons.lang3.StringUtils;
7 import org.springframework.stereotype.Service; 8 import org.springframework.stereotype.Service;
8 import org.springframework.transaction.annotation.Transactional; 9 import org.springframework.transaction.annotation.Transactional;
9 import org.thingsboard.server.common.data.yunteng.constant.FastIotConstants; 10 import org.thingsboard.server.common.data.yunteng.constant.FastIotConstants;
@@ -11,9 +12,9 @@ import org.thingsboard.server.common.data.yunteng.core.exception.TkDataValidatio @@ -11,9 +12,9 @@ import org.thingsboard.server.common.data.yunteng.core.exception.TkDataValidatio
11 import org.thingsboard.server.common.data.yunteng.core.message.ErrorMessage; 12 import org.thingsboard.server.common.data.yunteng.core.message.ErrorMessage;
12 import org.thingsboard.server.common.data.yunteng.dto.*; 13 import org.thingsboard.server.common.data.yunteng.dto.*;
13 import org.thingsboard.server.common.data.yunteng.dto.request.TkDataViewContentInfoDTO; 14 import org.thingsboard.server.common.data.yunteng.dto.request.TkDataViewContentInfoDTO;
  15 +import org.thingsboard.server.common.data.yunteng.enums.ViewType;
14 import org.thingsboard.server.common.data.yunteng.utils.tools.TkPageData; 16 import org.thingsboard.server.common.data.yunteng.utils.tools.TkPageData;
15 import org.thingsboard.server.dao.yunteng.entities.TkDataViewEntity; 17 import org.thingsboard.server.dao.yunteng.entities.TkDataViewEntity;
16 -import org.thingsboard.server.dao.yunteng.entities.TkDataViewInterfaceEntity;  
17 import org.thingsboard.server.dao.yunteng.mapper.TkDataViewMapper; 18 import org.thingsboard.server.dao.yunteng.mapper.TkDataViewMapper;
18 import org.thingsboard.server.dao.yunteng.mapper.OrganizationMapper; 19 import org.thingsboard.server.dao.yunteng.mapper.OrganizationMapper;
19 import org.thingsboard.server.dao.yunteng.service.AbstractBaseService; 20 import org.thingsboard.server.dao.yunteng.service.AbstractBaseService;
@@ -31,116 +32,161 @@ import java.util.stream.Collectors; @@ -31,116 +32,161 @@ import java.util.stream.Collectors;
31 @Slf4j 32 @Slf4j
32 @Service 33 @Service
33 @RequiredArgsConstructor 34 @RequiredArgsConstructor
34 -public class TkDataViewServiceImpl  
35 - extends AbstractBaseService<TkDataViewMapper, TkDataViewEntity>  
36 - implements TkDataViewService {  
37 - private final OrganizationMapper organizationMapper;  
38 - private final TkDataViewContentService ytDataViewContentService;  
39 - private final UserOrganizationMappingService userOrganizationMappingService; 35 +public class TkDataViewServiceImpl extends AbstractBaseService<TkDataViewMapper, TkDataViewEntity>
  36 + implements TkDataViewService {
  37 + private final OrganizationMapper organizationMapper;
  38 + private final TkDataViewContentService ytDataViewContentService;
  39 + private final UserOrganizationMappingService userOrganizationMappingService;
40 40
41 - @Override  
42 - public TkPageData<TkDataViewDTO> page(  
43 - Map<String, Object> queryMap, boolean tenantAdmin) {  
44 - List<String> organizationIds = null;  
45 - if (null != queryMap.get("organizationId")) {  
46 - String organizationId = (String) queryMap.get("organizationId");  
47 - List<OrganizationDTO> organizationList =  
48 - organizationMapper.findOrganizationTreeList(  
49 - (String) queryMap.get("tenantId"), new HashSet<>(List.of(organizationId)));  
50 - if (organizationList.size() == FastIotConstants.MagicNumber.ZERO) {  
51 - throw new TkDataValidationException(ErrorMessage.INVALID_PARAMETER.getMessage());  
52 - }  
53 - organizationIds =  
54 - organizationList.stream().map(BaseDTO::getId).distinct().collect(Collectors.toList());  
55 - }  
56 - if (!tenantAdmin && null != queryMap.get("userId")) {  
57 - // 获取客户的组织关系  
58 - String userId = (String) queryMap.get("userId");  
59 - organizationIds = userOrganizationMappingService.compareOrganizationIdsByCustomerId(organizationIds, userId);  
60 - }  
61 - if (null != organizationIds && organizationIds.size() > FastIotConstants.MagicNumber.ZERO) {  
62 - queryMap.put("organizationIds", organizationIds);  
63 - }  
64 - IPage<TkDataViewEntity> page =  
65 - getPage(queryMap, FastIotConstants.DefaultOrder.CREATE_TIME, false);  
66 - IPage<TkDataViewDTO> DataViewIPage =  
67 - baseMapper.getDataViewPage(page, queryMap);  
68 - return getPageData(DataViewIPage, TkDataViewDTO.class); 41 + @Override
  42 + public TkPageData<TkDataViewDTO> page(Map<String, Object> queryMap, boolean tenantAdmin) {
  43 + List<String> organizationIds = null;
  44 + if (null != queryMap.get("organizationId")) {
  45 + String organizationId = (String) queryMap.get("organizationId");
  46 + List<OrganizationDTO> organizationList =
  47 + organizationMapper.findOrganizationTreeList(
  48 + (String) queryMap.get("tenantId"), new HashSet<>(List.of(organizationId)));
  49 + if (organizationList.size() == FastIotConstants.MagicNumber.ZERO) {
  50 + throw new TkDataValidationException(ErrorMessage.INVALID_PARAMETER.getMessage());
  51 + }
  52 + organizationIds =
  53 + organizationList.stream().map(BaseDTO::getId).distinct().collect(Collectors.toList());
69 } 54 }
  55 + if (!tenantAdmin && null != queryMap.get("userId")) {
  56 + // 获取客户的组织关系
  57 + String userId = (String) queryMap.get("userId");
  58 + organizationIds =
  59 + userOrganizationMappingService.compareOrganizationIdsByCustomerId(
  60 + organizationIds, userId);
  61 + }
  62 + if (null != organizationIds && organizationIds.size() > FastIotConstants.MagicNumber.ZERO) {
  63 + queryMap.put("organizationIds", organizationIds);
  64 + }
  65 + IPage<TkDataViewEntity> page =
  66 + getPage(queryMap, FastIotConstants.DefaultOrder.CREATE_TIME, false);
  67 + IPage<TkDataViewDTO> DataViewIPage = baseMapper.getDataViewPage(page, queryMap);
  68 + return getPageData(DataViewIPage, TkDataViewDTO.class);
  69 + }
  70 +
  71 + @Override
  72 + @Transactional
  73 + public TkDataViewDTO saveDataView(TkDataViewDTO tkDataViewDTO) {
  74 + TkDataViewEntity dataView = tkDataViewDTO.getEntity(TkDataViewEntity.class);
  75 + dataView.setState(0);
  76 + baseMapper.insert(dataView);
  77 + TkDataViewContentDTO contentDTO = new TkDataViewContentDTO();
  78 + contentDTO.setTenantId(dataView.getTenantId());
  79 + contentDTO.setViewId(dataView.getId());
  80 + ytDataViewContentService.saveDataViewContent(contentDTO);
  81 + return tkDataViewDTO;
  82 + }
70 83
71 - @Override  
72 - @Transactional  
73 - public TkDataViewDTO saveDataView(TkDataViewDTO TkDataViewDTO) {  
74 - TkDataViewEntity dataView =  
75 - TkDataViewDTO.getEntity(TkDataViewEntity.class);  
76 - dataView.setState(0);  
77 - baseMapper.insert(dataView);  
78 - TkDataViewContentDTO contentDTO = new TkDataViewContentDTO();  
79 - contentDTO.setTenantId(dataView.getTenantId());  
80 - contentDTO.setViewId(dataView.getId());  
81 - contentDTO.setContent(  
82 - "<mxGraphModel><root><mxCell id=\"0\"/><mxCell id=\"1\" parent=\"0\"/></root></mxGraphModel>");  
83 - ytDataViewContentService.saveDataViewContent(contentDTO);  
84 - return TkDataViewDTO; 84 + @Override
  85 + @Transactional
  86 + public TkDataViewDTO updateDataView(TkDataViewDTO tkDataViewDTO) {
  87 + TkDataViewEntity dataView = baseMapper.selectById(tkDataViewDTO.getId());
  88 + if (!dataView.getTenantId().equals(tkDataViewDTO.getTenantId())) {
  89 + throw new TkDataValidationException(ErrorMessage.TENANT_MISMATCHING.getMessage());
85 } 90 }
  91 + //设计不修改状态
  92 + tkDataViewDTO.setViewType(null);
  93 + baseMapper.updateById(tkDataViewDTO.getEntity(TkDataViewEntity.class));
  94 + return tkDataViewDTO;
  95 + }
86 96
87 - @Override  
88 - @Transactional  
89 - public TkDataViewDTO updateDataView(TkDataViewDTO TkDataViewDTO) {  
90 - TkDataViewEntity DataView = baseMapper.selectById(TkDataViewDTO.getId());  
91 - if (!DataView.getTenantId().equals(TkDataViewDTO.getTenantId())) {  
92 - throw new TkDataValidationException(ErrorMessage.TENANT_MISMATCHING.getMessage());  
93 - }  
94 - baseMapper.updateById(TkDataViewDTO.getEntity(TkDataViewEntity.class));  
95 - return TkDataViewDTO; 97 + @Override
  98 + @Transactional
  99 + public boolean deleteDataView(DeleteDTO deleteDTO) {
  100 + List<TkDataViewEntity> centerList =
  101 + baseMapper.selectList(
  102 + new LambdaQueryWrapper<TkDataViewEntity>()
  103 + .in(TkDataViewEntity::getId, deleteDTO.getIds()));
  104 + for (TkDataViewEntity center : centerList) {
  105 + if (!center.getTenantId().equals(deleteDTO.getTenantId())) {
  106 + throw new TkDataValidationException(ErrorMessage.TENANT_MISMATCHING.getMessage());
  107 + }
96 } 108 }
  109 + ytDataViewContentService.deleteDataViewContentByCenterId(deleteDTO.getIds());
  110 + return baseMapper.deleteBatchIds(deleteDTO.getIds()) > FastIotConstants.MagicNumber.ZERO;
  111 + }
97 112
98 - @Override  
99 - @Transactional  
100 - public boolean deleteDataView(DeleteDTO deleteDTO) {  
101 - List<TkDataViewEntity> centerList =  
102 - baseMapper.selectList(  
103 - new LambdaQueryWrapper<TkDataViewEntity>()  
104 - .in(TkDataViewEntity::getId, deleteDTO.getIds()));  
105 - for (TkDataViewEntity center : centerList) {  
106 - if (!center.getTenantId().equals(deleteDTO.getTenantId())) {  
107 - throw new TkDataValidationException(ErrorMessage.TENANT_MISMATCHING.getMessage());  
108 - }  
109 - }  
110 - ytDataViewContentService.deleteDataViewContentByCenterId(deleteDTO.getIds());  
111 - return baseMapper.deleteBatchIds(deleteDTO.getIds()) > FastIotConstants.MagicNumber.ZERO; 113 + @Override
  114 + public TkDataViewContentInfoDTO getDataViewInfos(String id, String tenantId) {
  115 + List<TkDataViewContentInfoDTO> list = baseMapper.getDataViewInfoById(id, tenantId);
  116 + return list.size() > FastIotConstants.MagicNumber.ZERO
  117 + ? list.get(FastIotConstants.MagicNumber.ZERO)
  118 + : null;
  119 + }
  120 +
  121 + @Override
  122 + public TkDataViewDTO getDataViewById(String id, String tenantId) {
  123 + TkDataViewEntity entity =
  124 + baseMapper.selectOne(
  125 + new LambdaQueryWrapper<TkDataViewEntity>()
  126 + .eq(TkDataViewEntity::getTenantId, tenantId)
  127 + .eq(TkDataViewEntity::getId, id));
  128 + if (null == entity) {
  129 + throw new TkDataValidationException(ErrorMessage.INVALID_PARAMETER.getMessage());
112 } 130 }
  131 + return entity.getDTO(TkDataViewDTO.class);
  132 + }
113 133
114 - @Override  
115 - public TkDataViewContentInfoDTO getDataViewInfos(String id, String tenantId) {  
116 - List<TkDataViewContentInfoDTO> list = baseMapper.getDataViewInfoById(id, tenantId);  
117 - return list.size() > FastIotConstants.MagicNumber.ZERO  
118 - ? list.get(FastIotConstants.MagicNumber.ZERO)  
119 - : null; 134 + @Override
  135 + public boolean isNeedCredentialsForPublicView(String id, String tenantId) {
  136 + TkDataViewEntity entity =
  137 + baseMapper.selectOne(
  138 + new LambdaQueryWrapper<TkDataViewEntity>()
  139 + .eq(TkDataViewEntity::getTenantId, tenantId)
  140 + .eq(TkDataViewEntity::getId, id));
  141 + if (null == entity) {
  142 + throw new TkDataValidationException(ErrorMessage.INVALID_PARAMETER.getMessage());
120 } 143 }
  144 + return StringUtils.isNotEmpty(entity.getAccessCredentials());
  145 + }
121 146
  147 + @Override
  148 + @Transactional
  149 + public boolean shareOrMonopolyDataViewCenter(
  150 + boolean isShare, String id, String accessCredentials, String tenantId) {
  151 + TkDataViewEntity entity =
  152 + baseMapper.selectOne(
  153 + new LambdaQueryWrapper<TkDataViewEntity>()
  154 + .eq(TkDataViewEntity::getTenantId, tenantId)
  155 + .eq(TkDataViewEntity::getId, id));
  156 + if (null == entity) {
  157 + throw new TkDataValidationException(ErrorMessage.INVALID_PARAMETER.getMessage());
  158 + }
  159 + if (isShare) {
  160 + entity.setViewType(ViewType.PUBLIC_VIEW);
  161 + entity.setAccessCredentials(accessCredentials);
  162 + } else {
  163 + entity.setViewType(ViewType.PRIVATE_VIEW);
  164 + entity.setAccessCredentials(null);
  165 + }
  166 + return baseMapper.updateById(entity) > FastIotConstants.MagicNumber.ZERO;
  167 + }
122 168
123 - @Override  
124 - public boolean publishDataView(String id, String tenantId) {  
125 - TkDataViewEntity dataView = baseMapper.selectById(id);  
126 - if (!dataView.getTenantId().equals(tenantId)) {  
127 - throw new TkDataValidationException(ErrorMessage.TENANT_MISMATCHING.getMessage());  
128 - }  
129 - //Modify dataView state is publish  
130 - dataView.setState(1);  
131 - int resultInt = baseMapper.updateById(dataView);  
132 - return resultInt > 0 ? true : false; 169 + @Override
  170 + public boolean publishDataView(String id, String tenantId) {
  171 + TkDataViewEntity dataView = baseMapper.selectById(id);
  172 + if (!dataView.getTenantId().equals(tenantId)) {
  173 + throw new TkDataValidationException(ErrorMessage.TENANT_MISMATCHING.getMessage());
133 } 174 }
  175 + // Modify dataView state is publish
  176 + dataView.setState(FastIotConstants.StateValue.PUBLISH);
  177 + int resultInt = baseMapper.updateById(dataView);
  178 + return resultInt > FastIotConstants.MagicNumber.ZERO;
  179 + }
134 180
135 - @Override  
136 - public boolean cancelPublishDataView(String id, String tenantId) {  
137 - TkDataViewEntity dataView = baseMapper.selectById(id);  
138 - if (!dataView.getTenantId().equals(tenantId)) {  
139 - throw new TkDataValidationException(ErrorMessage.TENANT_MISMATCHING.getMessage());  
140 - }  
141 - //Modify dataView state is cancelPublish  
142 - dataView.setState(0);  
143 - int resultInt = baseMapper.updateById(dataView);  
144 - return resultInt > 0 ? true : false; 181 + @Override
  182 + public boolean cancelPublishDataView(String id, String tenantId) {
  183 + TkDataViewEntity dataView = baseMapper.selectById(id);
  184 + if (!dataView.getTenantId().equals(tenantId)) {
  185 + throw new TkDataValidationException(ErrorMessage.TENANT_MISMATCHING.getMessage());
145 } 186 }
  187 + // Modify dataView state is cancelPublish
  188 + dataView.setState(FastIotConstants.StateValue.CANCEL_PUBLISH);
  189 + int resultInt = baseMapper.updateById(dataView);
  190 + return resultInt > FastIotConstants.MagicNumber.ZERO;
  191 + }
146 } 192 }
@@ -4,6 +4,8 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; @@ -4,6 +4,8 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
4 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; 4 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
5 import com.baomidou.mybatisplus.core.metadata.IPage; 5 import com.baomidou.mybatisplus.core.metadata.IPage;
6 import com.fasterxml.jackson.databind.JsonNode; 6 import com.fasterxml.jackson.databind.JsonNode;
  7 +import com.google.common.util.concurrent.Futures;
  8 +import com.google.common.util.concurrent.ListenableFuture;
7 import lombok.RequiredArgsConstructor; 9 import lombok.RequiredArgsConstructor;
8 import lombok.extern.slf4j.Slf4j; 10 import lombok.extern.slf4j.Slf4j;
9 import org.apache.commons.lang3.StringUtils; 11 import org.apache.commons.lang3.StringUtils;
@@ -365,7 +367,7 @@ public class TkDeviceServiceImpl extends AbstractBaseService<DeviceMapper, TkDev @@ -365,7 +367,7 @@ public class TkDeviceServiceImpl extends AbstractBaseService<DeviceMapper, TkDev
365 List<String> queryOrganizationIds = organizationAllIds(tenantId, organizationId); 367 List<String> queryOrganizationIds = organizationAllIds(tenantId, organizationId);
366 queryMap.put("organizationIds", queryOrganizationIds); 368 queryMap.put("organizationIds", queryOrganizationIds);
367 } 369 }
368 - //用于数据流转已选,待选过滤============开始 370 + // 用于数据流转已选,待选过滤============开始
369 if (StringUtils.isNotEmpty(convertConfigId)) { 371 if (StringUtils.isNotEmpty(convertConfigId)) {
370 ConvertConfigDTO configDTO = 372 ConvertConfigDTO configDTO =
371 convertConfigService.findConvertConfigDTOById(tenantId, convertConfigId); 373 convertConfigService.findConvertConfigDTOById(tenantId, convertConfigId);
@@ -382,7 +384,7 @@ public class TkDeviceServiceImpl extends AbstractBaseService<DeviceMapper, TkDev @@ -382,7 +384,7 @@ public class TkDeviceServiceImpl extends AbstractBaseService<DeviceMapper, TkDev
382 } 384 }
383 } 385 }
384 } 386 }
385 - //用于数据流转已选,待选过滤============结束 387 + // 用于数据流转已选,待选过滤============结束
386 IPage<TkDeviceEntity> page = 388 IPage<TkDeviceEntity> page =
387 getPage(queryMap, FastIotConstants.DefaultOrder.CREATE_TIME, false); 389 getPage(queryMap, FastIotConstants.DefaultOrder.CREATE_TIME, false);
388 IPage<DeviceDTO> deviceIPage = baseMapper.getDevicePage(page, queryMap); 390 IPage<DeviceDTO> deviceIPage = baseMapper.getDevicePage(page, queryMap);
@@ -668,12 +670,16 @@ public class TkDeviceServiceImpl extends AbstractBaseService<DeviceMapper, TkDev @@ -668,12 +670,16 @@ public class TkDeviceServiceImpl extends AbstractBaseService<DeviceMapper, TkDev
668 public List<String> rpcDevices(String tenantId, String organizationId, String projectId) { 670 public List<String> rpcDevices(String tenantId, String organizationId, String projectId) {
669 List<String> orgIds = organizationAllIds(tenantId, organizationId); 671 List<String> orgIds = organizationAllIds(tenantId, organizationId);
670 672
671 - List<TkDeviceEntity> organizationDevices = baseMapper.selectList(new LambdaQueryWrapper<TkDeviceEntity>().eq(TkDeviceEntity::getDeviceProfileId, projectId).in(TkDeviceEntity::getOrganizationId,orgIds)); 673 + List<TkDeviceEntity> organizationDevices =
  674 + baseMapper.selectList(
  675 + new LambdaQueryWrapper<TkDeviceEntity>()
  676 + .eq(TkDeviceEntity::getDeviceProfileId, projectId)
  677 + .in(TkDeviceEntity::getOrganizationId, orgIds));
672 List<String> allDevices = new ArrayList<>(); 678 List<String> allDevices = new ArrayList<>();
673 - if(organizationDevices != null && !organizationDevices.isEmpty()){ 679 + if (organizationDevices != null && !organizationDevices.isEmpty()) {
674 for (TkDeviceEntity item : organizationDevices) { 680 for (TkDeviceEntity item : organizationDevices) {
675 DeviceTypeEnum deviceType = item.getDeviceType(); 681 DeviceTypeEnum deviceType = item.getDeviceType();
676 - if(DeviceTypeEnum.SENSOR.equals(deviceType)){ 682 + if (DeviceTypeEnum.SENSOR.equals(deviceType)) {
677 allDevices.add(item.getGatewayId()); 683 allDevices.add(item.getGatewayId());
678 continue; 684 continue;
679 } 685 }
@@ -682,4 +688,26 @@ public class TkDeviceServiceImpl extends AbstractBaseService<DeviceMapper, TkDev @@ -682,4 +688,26 @@ public class TkDeviceServiceImpl extends AbstractBaseService<DeviceMapper, TkDev
682 } 688 }
683 return allDevices; 689 return allDevices;
684 } 690 }
  691 +
  692 + @Override
  693 + public ListenableFuture<List<DeviceDTO>> findDeviceListByDeviceProfileId(
  694 + String deviceProfileId, String tenantId) {
  695 + if (StringUtils.isEmpty(deviceProfileId) || StringUtils.isEmpty(tenantId)) {
  696 + throw new TkDataValidationException(ErrorMessage.INVALID_PARAMETER.getMessage());
  697 + }
  698 + List<DeviceDTO> devices = new ArrayList<>();
  699 + List<TkDeviceEntity> entityList =
  700 + baseMapper.selectList(
  701 + new LambdaQueryWrapper<TkDeviceEntity>()
  702 + .eq(TkDeviceEntity::getTenantId, tenantId)
  703 + .eq(TkDeviceEntity::getDeviceProfileId, deviceProfileId));
  704 + return Optional.ofNullable(entityList)
  705 + .map(
  706 + list ->
  707 + Futures.immediateFuture(
  708 + list.stream()
  709 + .map(obj -> obj.getDTO(DeviceDTO.class))
  710 + .collect(Collectors.toList())))
  711 + .orElse(Futures.immediateFuture(devices));
  712 + }
685 } 713 }
  1 +package org.thingsboard.server.dao.yunteng.impl;
  2 +
  3 +import com.google.common.base.Objects;
  4 +import lombok.RequiredArgsConstructor;
  5 +import org.springframework.stereotype.Service;
  6 +import org.thingsboard.server.common.data.StringUtils;
  7 +import org.thingsboard.server.common.data.yunteng.core.exception.TkDataValidationException;
  8 +import org.thingsboard.server.common.data.yunteng.core.message.ErrorMessage;
  9 +import org.thingsboard.server.common.data.yunteng.dto.ConfigurationCenterDTO;
  10 +import org.thingsboard.server.common.data.yunteng.dto.DataBoardDTO;
  11 +import org.thingsboard.server.common.data.yunteng.dto.DataComponentDTO;
  12 +import org.thingsboard.server.common.data.yunteng.dto.TkDataViewDTO;
  13 +import org.thingsboard.server.common.data.yunteng.dto.board.MoreDataComponentInfoDTO;
  14 +import org.thingsboard.server.common.data.yunteng.dto.request.ConfigurationContentInfoDTO;
  15 +import org.thingsboard.server.common.data.yunteng.dto.request.TkDataViewContentInfoDTO;
  16 +import org.thingsboard.server.common.data.yunteng.enums.ShareViewType;
  17 +import org.thingsboard.server.common.data.yunteng.enums.ViewType;
  18 +import org.thingsboard.server.dao.yunteng.service.*;
  19 +
  20 +import java.util.List;
  21 +
  22 +@Service
  23 +@RequiredArgsConstructor
  24 +public class TkShareViewServiceImpl implements TkShareViewService {
  25 +
  26 + private final TkDataComponentService tkDataComponentService;
  27 + private final TkDataBoardService tkDataBoardService;
  28 + private final TkDataViewService tkDataViewService;
  29 + private final TkConfigurationCenterService tkConfigurationCenterService;
  30 +
  31 + private MoreDataComponentInfoDTO viewDataComponentsByBoardId(
  32 + String boardId, String accessCredentials, String tenantId) {
  33 + DataBoardDTO dto = tkDataBoardService.findDataBoardInfoById(boardId, tenantId);
  34 + checkParams(dto, dto.getViewType(), dto.getAccessCredentials(), accessCredentials);
  35 + MoreDataComponentInfoDTO moreDataComponentInfoDTO = new MoreDataComponentInfoDTO();
  36 + List<DataComponentDTO> data =
  37 + tkDataComponentService.getDataComponentsByBoardId(tenantId, boardId);
  38 + moreDataComponentInfoDTO.setComponentLayout(dto.getLayout());
  39 + moreDataComponentInfoDTO.setComponentData(data);
  40 + return moreDataComponentInfoDTO;
  41 + }
  42 +
  43 + private ConfigurationContentInfoDTO viewConfigurationById(
  44 + String id, String accessCredentials, String tenantId) {
  45 + ConfigurationCenterDTO centerDTO =
  46 + tkConfigurationCenterService.getConfigurationCenterInfoById(id, tenantId);
  47 + checkParams(
  48 + centerDTO, centerDTO.getViewType(), centerDTO.getAccessCredentials(), accessCredentials);
  49 + return tkConfigurationCenterService.getConfigurationInfos(id, tenantId);
  50 + }
  51 +
  52 + private TkDataViewContentInfoDTO viewDataViewInfosById(
  53 + String id, String accessCredentials, String tenantId) {
  54 + TkDataViewDTO dto = tkDataViewService.getDataViewById(id, tenantId);
  55 + checkParams(dto, dto.getViewType(), dto.getAccessCredentials(), accessCredentials);
  56 + return tkDataViewService.getDataViewInfos(id, tenantId);
  57 + }
  58 +
  59 + private void checkParams(
  60 + Object dto, ViewType viewType, String targetCredentials, String sourceCredentials) {
  61 + if (null == dto) {
  62 + throw new TkDataValidationException(ErrorMessage.NOT_BELONG_CURRENT_TENANT.getMessage());
  63 + }
  64 + if (!Objects.equal(viewType, ViewType.PUBLIC_VIEW)) {
  65 + throw new TkDataValidationException(ErrorMessage.CURRENT_VIEW_IS_PRIVATE.getMessage());
  66 + }
  67 + if (StringUtils.isNotEmpty(targetCredentials)) {
  68 + if (!Objects.equal(targetCredentials, sourceCredentials)) {
  69 + throw new TkDataValidationException(
  70 + ErrorMessage.CURRENT_URL_REQUIRES_PERMISSION.getMessage());
  71 + }
  72 + }
  73 + }
  74 +
  75 + @Override
  76 + public Object viewShareDataById(
  77 + ShareViewType shareViewType, String id, String accessCredentials, String tenantId) {
  78 + Object result;
  79 + switch (shareViewType) {
  80 + case DATA_BOARD:
  81 + result = viewDataComponentsByBoardId(id, accessCredentials, tenantId);
  82 + break;
  83 + case SCADA:
  84 + result = viewConfigurationById(id, accessCredentials, tenantId);
  85 + break;
  86 + case LARGE_SCREEN:
  87 + result = viewDataViewInfosById(id, accessCredentials, tenantId);
  88 + break;
  89 + default:
  90 + throw new TkDataValidationException(ErrorMessage.SHARE_VIEW_TYPE_NOT_EXIST.getMessage());
  91 + }
  92 + return result;
  93 + }
  94 +
  95 + @Override
  96 + public boolean checkPublicViewNeedCredentials(
  97 + ShareViewType type, String viewId, String tenantId) {
  98 + boolean result;
  99 + switch (type) {
  100 + case SCADA:
  101 + result = tkConfigurationCenterService.isNeedCredentialsForPublicView(viewId, tenantId);
  102 + break;
  103 + case DATA_BOARD:
  104 + result = tkDataBoardService.isNeedCredentialsForPublicView(viewId, tenantId);
  105 + break;
  106 + case LARGE_SCREEN:
  107 + result = tkDataViewService.isNeedCredentialsForPublicView(viewId, tenantId);
  108 + break;
  109 + default:
  110 + throw new TkDataValidationException(ErrorMessage.SHARE_VIEW_TYPE_NOT_EXIST.getMessage());
  111 + }
  112 + return result;
  113 + }
  114 +}
  1 +package org.thingsboard.server.dao.yunteng.impl;
  2 +
  3 +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
  4 +import com.baomidou.mybatisplus.core.metadata.IPage;
  5 +import com.fasterxml.jackson.databind.JsonNode;
  6 +import com.google.common.util.concurrent.Futures;
  7 +import com.google.common.util.concurrent.ListenableFuture;
  8 +import lombok.RequiredArgsConstructor;
  9 +import lombok.extern.slf4j.Slf4j;
  10 +import org.apache.commons.lang3.StringUtils;
  11 +import org.quartz.SchedulerException;
  12 +import org.springframework.stereotype.Service;
  13 +import org.thingsboard.server.common.data.yunteng.constant.FastIotConstants;
  14 +import org.thingsboard.server.common.data.yunteng.core.cache.CacheUtils;
  15 +import org.thingsboard.server.common.data.yunteng.core.exception.TkDataValidationException;
  16 +import org.thingsboard.server.common.data.yunteng.core.message.ErrorMessage;
  17 +import org.thingsboard.server.common.data.yunteng.dto.DeleteDTO;
  18 +import org.thingsboard.server.common.data.yunteng.dto.DeviceDTO;
  19 +import org.thingsboard.server.common.data.yunteng.dto.SysJobDTO;
  20 +import org.thingsboard.server.common.data.yunteng.dto.task.TargetContentDTO;
  21 +import org.thingsboard.server.common.data.yunteng.dto.task.TaskExecuteTimeDTO;
  22 +import org.thingsboard.server.common.data.yunteng.dto.task.TaskTypeDTO;
  23 +import org.thingsboard.server.common.data.yunteng.dto.task.TkTaskCenterDTO;
  24 +import org.thingsboard.server.common.data.yunteng.enums.JobGroupEnum;
  25 +import org.thingsboard.server.common.data.yunteng.enums.TargetTypeEnum;
  26 +import org.thingsboard.server.common.data.yunteng.utils.JacksonUtil;
  27 +import org.thingsboard.server.common.data.yunteng.utils.tools.TkPageData;
  28 +import org.thingsboard.server.dao.yunteng.entities.TkTaskCenterEntity;
  29 +import org.thingsboard.server.dao.yunteng.mapper.TaskCenterMapper;
  30 +import org.thingsboard.server.dao.yunteng.service.AbstractBaseService;
  31 +import org.thingsboard.server.dao.yunteng.service.TkDeviceService;
  32 +import org.thingsboard.server.dao.yunteng.service.TkSysJobService;
  33 +import org.thingsboard.server.dao.yunteng.service.TkTaskCenterService;
  34 +
  35 +import javax.transaction.Transactional;
  36 +import java.util.*;
  37 +import java.util.stream.Collectors;
  38 +
  39 +@Service
  40 +@RequiredArgsConstructor
  41 +@Slf4j
  42 +public class TkTaskCenterServiceImpl
  43 + extends AbstractBaseService<TaskCenterMapper, TkTaskCenterEntity>
  44 + implements TkTaskCenterService {
  45 + private final TkSysJobService tkSysJobService;
  46 + private final TkDeviceService tkDeviceService;
  47 + private final CacheUtils cacheUtils;
  48 +
  49 + @Override
  50 + public TkPageData<TkTaskCenterDTO> taskCenterPage(Map<String, Object> queryMap, String tenantId) {
  51 + Integer state = (Integer) queryMap.get("state");
  52 + TargetTypeEnum targetTypeEnum = (TargetTypeEnum) queryMap.get("targetType");
  53 + IPage<TkTaskCenterEntity> page =
  54 + getPage(queryMap, FastIotConstants.DefaultOrder.CREATE_TIME, false);
  55 + IPage<TkTaskCenterEntity> taskCenterIPage =
  56 + baseMapper.selectPage(
  57 + page,
  58 + new LambdaQueryWrapper<TkTaskCenterEntity>()
  59 + .eq(TkTaskCenterEntity::getTenantId, tenantId)
  60 + .eq(null != state, TkTaskCenterEntity::getState, state)
  61 + .eq(null != targetTypeEnum, TkTaskCenterEntity::getTargetType, targetTypeEnum));
  62 + if (!taskCenterIPage.getRecords().isEmpty()) {
  63 + List<TkTaskCenterDTO> listRecords =
  64 + taskCenterIPage.getRecords().stream()
  65 + .map(
  66 + entity -> {
  67 + TkTaskCenterDTO dto = entity.getDTO(TkTaskCenterDTO.class);
  68 + dto.setExecuteContent(
  69 + JacksonUtil.convertValue(entity.getExecuteContent(), TaskTypeDTO.class));
  70 + dto.setExecuteTime(
  71 + JacksonUtil.convertValue(
  72 + entity.getExecuteTime(), TaskExecuteTimeDTO.class));
  73 + dto.setExecuteTarget(
  74 + JacksonUtil.convertValue(
  75 + entity.getExecuteTarget(), TargetContentDTO.class));
  76 + return dto;
  77 + })
  78 + .collect(Collectors.toList());
  79 + return new TkPageData<>(listRecords, taskCenterIPage.getTotal());
  80 + }
  81 + return getPageData(taskCenterIPage, TkTaskCenterDTO.class);
  82 + }
  83 +
  84 + @Override
  85 + @Transactional
  86 + public TkTaskCenterDTO saveOrUpdateTaskCenter(TkTaskCenterDTO tkTaskCenterDTO) {
  87 + TkTaskCenterEntity entity = tkTaskCenterDTO.getEntity(TkTaskCenterEntity.class);
  88 + JsonNode jsonNode = tkTaskCenterDTO.getExecuteContent().getPushContent();
  89 + if (null == jsonNode || null == jsonNode.get(FastIotConstants.RPC_COMMAND)) {
  90 + throw new TkDataValidationException(ErrorMessage.EXECUTE_COMMAND_IS_NULL.getMessage());
  91 + }
  92 + TaskExecuteTimeDTO executeTime = tkTaskCenterDTO.getExecuteTime();
  93 + if (null == executeTime || StringUtils.isEmpty(executeTime.getCron())) {
  94 + throw new TkDataValidationException(ErrorMessage.CRON_INVALID.getMessage());
  95 + }
  96 + entity.setExecuteContent(
  97 + JacksonUtil.convertValue(tkTaskCenterDTO.getExecuteContent(), JsonNode.class));
  98 + entity.setExecuteTarget(
  99 + JacksonUtil.convertValue(tkTaskCenterDTO.getExecuteTarget(), JsonNode.class));
  100 + entity.setExecuteTime(
  101 + JacksonUtil.convertValue(tkTaskCenterDTO.getExecuteTime(), JsonNode.class));
  102 + if (StringUtils.isEmpty(tkTaskCenterDTO.getId())) {
  103 + entity.setState(FastIotConstants.StateValue.DISABLE);
  104 + baseMapper.insert(entity);
  105 + } else {
  106 + TkTaskCenterDTO queryDTO =
  107 + findTaskCenterInfoById(tkTaskCenterDTO.getId(), tkTaskCenterDTO.getTenantId());
  108 + if (null == queryDTO) {
  109 + throw new TkDataValidationException(ErrorMessage.NOT_BELONG_CURRENT_TENANT.getMessage());
  110 + }
  111 + // 只有通过修改状态接口,才可以修改状态
  112 + entity.setState(null);
  113 + baseMapper.updateById(entity);
  114 + updateTaskCenterCache(entity);
  115 + }
  116 + return tkTaskCenterDTO;
  117 + }
  118 +
  119 + @Override
  120 + @Transactional
  121 + public boolean deleteTaskCenter(DeleteDTO deleteDTO) throws SchedulerException {
  122 + List<TkTaskCenterEntity> list =
  123 + baseMapper.selectList(
  124 + new LambdaQueryWrapper<TkTaskCenterEntity>()
  125 + .eq(TkTaskCenterEntity::getTenantId, deleteDTO.getTenantId())
  126 + .in(TkTaskCenterEntity::getId, deleteDTO.getIds()));
  127 + if (null == list || list.isEmpty()) {
  128 + throw new TkDataValidationException(ErrorMessage.INVALID_PARAMETER.getMessage());
  129 + }
  130 + List<String> sourceIds = new ArrayList<>();
  131 + for (TkTaskCenterEntity entity : list) {
  132 + // 任务中心,是启用状态不能删除
  133 + if (entity.getState() == FastIotConstants.StateValue.ENABLE) {
  134 + throw new TkDataValidationException(
  135 + String.format(
  136 + ErrorMessage.DATA_STATE_ENABLE_NOT_DELETE.getMessage(), entity.getName()));
  137 + }
  138 + sourceIds.add(entity.getId());
  139 + }
  140 + int result = baseMapper.deleteBatchIds(sourceIds);
  141 + if (result > FastIotConstants.MagicNumber.ZERO) {
  142 + return tkSysJobService.deleteJobs(
  143 + sourceIds, JobGroupEnum.TASK_CENTER.name(), deleteDTO.getTenantId());
  144 + }
  145 + // 移除任务中心缓存
  146 + for (String taskCenterId : sourceIds) {
  147 + String key = FastIotConstants.CacheConfigKey.TASK_CENTER_INFOS + taskCenterId;
  148 + cacheUtils.invalidate(key);
  149 + }
  150 + return false;
  151 + }
  152 +
  153 + @Override
  154 + public TkTaskCenterDTO findTaskCenterInfoById(String id, String tenantId) {
  155 + if (StringUtils.isEmpty(id) || StringUtils.isEmpty(tenantId)) {
  156 + throw new TkDataValidationException(ErrorMessage.INVALID_PARAMETER.getMessage());
  157 + }
  158 + TkTaskCenterEntity entity =
  159 + baseMapper.selectOne(
  160 + new LambdaQueryWrapper<TkTaskCenterEntity>()
  161 + .eq(TkTaskCenterEntity::getTenantId, tenantId)
  162 + .eq(TkTaskCenterEntity::getId, id));
  163 + return Optional.ofNullable(entity)
  164 + .map(
  165 + object -> {
  166 + TkTaskCenterDTO tkTaskCenterDTO = object.getDTO(TkTaskCenterDTO.class);
  167 + tkTaskCenterDTO.setExecuteTarget(
  168 + JacksonUtil.convertValue(object.getExecuteTarget(), TargetContentDTO.class));
  169 + tkTaskCenterDTO.setExecuteContent(
  170 + JacksonUtil.convertValue(object.getExecuteContent(), TaskTypeDTO.class));
  171 + tkTaskCenterDTO.setExecuteTime(
  172 + JacksonUtil.convertValue(object.getExecuteTime(), TaskExecuteTimeDTO.class));
  173 + return tkTaskCenterDTO;
  174 + })
  175 + .orElse(null);
  176 + }
  177 +
  178 + @Override
  179 + public ListenableFuture<TkTaskCenterDTO> getTaskCenterInfoById(String id) {
  180 + if (StringUtils.isEmpty(id)) {
  181 + throw new TkDataValidationException(ErrorMessage.INVALID_PARAMETER.getMessage());
  182 + }
  183 + String key = FastIotConstants.CacheConfigKey.TASK_CENTER_INFOS + id;
  184 + Optional<TkTaskCenterEntity> entityCache = cacheUtils.get(key);
  185 + TkTaskCenterEntity entity =
  186 + entityCache.orElseGet(
  187 + () ->
  188 + baseMapper.selectOne(
  189 + new LambdaQueryWrapper<TkTaskCenterEntity>()
  190 + .eq(TkTaskCenterEntity::getId, id)));
  191 + return Optional.ofNullable(entity)
  192 + .map(
  193 + object -> {
  194 + TkTaskCenterDTO tkTaskCenterDTO = object.getDTO(TkTaskCenterDTO.class);
  195 + tkTaskCenterDTO.setExecuteTarget(
  196 + JacksonUtil.convertValue(object.getExecuteTarget(), TargetContentDTO.class));
  197 + tkTaskCenterDTO.setExecuteContent(
  198 + JacksonUtil.convertValue(object.getExecuteContent(), TaskTypeDTO.class));
  199 + tkTaskCenterDTO.setExecuteTime(
  200 + JacksonUtil.convertValue(object.getExecuteTime(), TaskExecuteTimeDTO.class));
  201 + return Futures.immediateFuture(tkTaskCenterDTO);
  202 + })
  203 + .orElse(null);
  204 + }
  205 +
  206 + @Override
  207 + @Transactional
  208 + public boolean updateState(String id, Integer state, String tenantId) throws SchedulerException {
  209 + TkTaskCenterEntity entity =
  210 + baseMapper.selectOne(
  211 + new LambdaQueryWrapper<TkTaskCenterEntity>().eq(TkTaskCenterEntity::getId, id));
  212 + boolean result = false;
  213 + if (null == entity) {
  214 + throw new TkDataValidationException(ErrorMessage.INVALID_PARAMETER.getMessage());
  215 + }
  216 + if (!Objects.equals(entity.getTenantId(), tenantId)) {
  217 + throw new TkDataValidationException(ErrorMessage.NOT_BELONG_CURRENT_TENANT.getMessage());
  218 + }
  219 + entity.setState(state);
  220 + if (baseMapper.updateById(entity) > FastIotConstants.MagicNumber.ZERO) {
  221 + String sourceId = entity.getId();
  222 + SysJobDTO queryJob = tkSysJobService.findSysJobBySourceId(sourceId);
  223 + if (null == queryJob) {
  224 + TaskExecuteTimeDTO executeTime =
  225 + JacksonUtil.convertValue(entity.getExecuteTime(), TaskExecuteTimeDTO.class);
  226 + if (null == executeTime || StringUtils.isEmpty(executeTime.getCron())) {
  227 + throw new TkDataValidationException(ErrorMessage.CRON_INVALID.getMessage());
  228 + }
  229 + queryJob = new SysJobDTO();
  230 + queryJob.setSourceId(sourceId);
  231 + queryJob.setJobName(entity.getName());
  232 + queryJob.setInvokeTarget("rpcCommandTask.process('" + sourceId + "')");
  233 + queryJob.setJobGroup(JobGroupEnum.TASK_CENTER.name());
  234 + queryJob.setCronExpression(executeTime.getCron());
  235 + queryJob.setTenantId(entity.getTenantId());
  236 + }
  237 + queryJob.setStatus(state);
  238 + tkSysJobService.saveOrUpdateJob(queryJob);
  239 + result = true;
  240 + }
  241 + return result;
  242 + }
  243 +
  244 + @Override
  245 + @Transactional
  246 + public boolean cancelExecute(String id, String tbDeviceId, String tenantId) {
  247 + boolean result = false;
  248 + TkTaskCenterEntity entity = baseMapper.selectById(id);
  249 + if (entity != null) {
  250 + if (!Objects.equals(entity.getTenantId(), tenantId)) {
  251 + throw new TkDataValidationException(ErrorMessage.NOT_BELONG_CURRENT_TENANT.getMessage());
  252 + }
  253 + TargetContentDTO targetContent =
  254 + JacksonUtil.convertValue(entity.getExecuteTarget(), TargetContentDTO.class);
  255 + if (null != targetContent) {
  256 + // 按设备执行
  257 + if (Objects.equals(entity.getTargetType(), TargetTypeEnum.DEVICES)) {
  258 + List<String> data = targetContent.getData();
  259 + List<String> removeResult = new ArrayList<>();
  260 + if (null != data && !data.isEmpty()) {
  261 + for (String deviceId : data) {
  262 + if (!Objects.equals(deviceId, tbDeviceId)) {
  263 + removeResult.add(deviceId);
  264 + }
  265 + }
  266 + targetContent.setData(removeResult);
  267 + }
  268 + } else {
  269 + // 按产品执行
  270 + Map<String, List<String>> map = targetContent.getCancelExecuteDevices();
  271 + DeviceDTO deviceDTO = tkDeviceService.findDeviceInfoByTbDeviceId(tenantId, tbDeviceId);
  272 + for (String key : map.keySet()) {
  273 + if (Objects.equals(key, deviceDTO.getDeviceProfileId())) {
  274 + map.get(key).add(tbDeviceId);
  275 + break;
  276 + }
  277 + }
  278 + }
  279 + entity.setExecuteTarget(JacksonUtil.convertValue(targetContent, JsonNode.class));
  280 + baseMapper.updateById(entity);
  281 + updateTaskCenterCache(entity);
  282 + }
  283 + }
  284 + return result;
  285 + }
  286 +
  287 + private void updateTaskCenterCache(TkTaskCenterEntity entity) {
  288 + String key = FastIotConstants.CacheConfigKey.TASK_CENTER_INFOS + entity.getId();
  289 + Optional<TkTaskCenterEntity> entityCache = cacheUtils.get(key);
  290 + if (entityCache.isPresent()) {
  291 + cacheUtils.put(key, entity);
  292 + }
  293 + }
  294 +}
  1 +package org.thingsboard.server.dao.yunteng.mapper;
  2 +
  3 +import com.baomidou.mybatisplus.core.mapper.BaseMapper;
  4 +import org.apache.ibatis.annotations.Mapper;
  5 +import org.thingsboard.server.dao.yunteng.entities.TkTaskCenterEntity;
  6 +
  7 +@Mapper
  8 +public interface TaskCenterMapper extends BaseMapper<TkTaskCenterEntity> {
  9 +}
1 package org.thingsboard.server.dao.yunteng.service; 1 package org.thingsboard.server.dao.yunteng.service;
2 import org.thingsboard.server.common.data.yunteng.dto.SysAreaDTO; 2 import org.thingsboard.server.common.data.yunteng.dto.SysAreaDTO;
  3 +import org.thingsboard.server.common.data.yunteng.enums.AreaLevelEnum;
  4 +
3 import java.util.List; 5 import java.util.List;
4 6
5 /** 7 /**
@@ -10,5 +12,5 @@ import java.util.List; @@ -10,5 +12,5 @@ import java.util.List;
10 public interface SysAreaService { 12 public interface SysAreaService {
11 List<SysAreaDTO> list(SysAreaDTO sysAreaDTO); 13 List<SysAreaDTO> list(SysAreaDTO sysAreaDTO);
12 14
13 - SysAreaDTO getSysAreaInfoByCode(Long code); 15 + SysAreaDTO getSysAreaInfoByCode(Long code, AreaLevelEnum levelEnum);
14 } 16 }
@@ -16,5 +16,28 @@ public interface TkConfigurationCenterService { @@ -16,5 +16,28 @@ public interface TkConfigurationCenterService {
16 16
17 boolean deleteConfigurationCenter(DeleteDTO deleteDTO); 17 boolean deleteConfigurationCenter(DeleteDTO deleteDTO);
18 18
19 - ConfigurationContentInfoDTO getConfigurationInfos(String id,String tenantId); 19 + ConfigurationContentInfoDTO getConfigurationInfos(String id, String tenantId);
  20 +
  21 + ConfigurationCenterDTO getConfigurationCenterInfoById(String id,String tenantId);
  22 +
  23 + /**
  24 + * 根据租户ID和数据看板ID,判断是否需要密码
  25 + *
  26 + * @param id 数据看板ID
  27 + * @param tenantId 租户ID
  28 + * @return 需要true,不需要false
  29 + */
  30 + boolean isNeedCredentialsForPublicView(String id, String tenantId);
  31 +
  32 + /**
  33 + * 分享或取消分享组态中心
  34 + *
  35 + * @param isShare true分享 false取消分享
  36 + * @param id 组态ID
  37 + * @param accessCredentials 分享的密码:不用密码则为null
  38 + * @param tenantId 租户ID
  39 + * @return true成功 false失败
  40 + */
  41 + boolean shareOrMonopolyConfigurationCenter(
  42 + boolean isShare, String id, String accessCredentials, String tenantId);
20 } 43 }
@@ -56,4 +56,23 @@ public interface TkDataBoardService { @@ -56,4 +56,23 @@ public interface TkDataBoardService {
56 * @return false失败 true成功 56 * @return false失败 true成功
57 */ 57 */
58 boolean updateDataBoardComponentNum(String id,String tenantId,int count); 58 boolean updateDataBoardComponentNum(String id,String tenantId,int count);
  59 +
  60 + /**
  61 + * 根据租户ID和数据看板ID,判断是否需要密码
  62 + * @param id 数据看板ID
  63 + * @param tenantId 租户ID
  64 + * @return 需要true,不需要false
  65 + */
  66 + boolean isNeedCredentialsForPublicView(String id,String tenantId);
  67 +
  68 + /**
  69 + * 分享或取消分享数据刊本
  70 + * @param isShare 分享
  71 + * @param id 数据看板ID
  72 + * @param accessCredentials 访问凭证
  73 + * @param tenantId 租户ID
  74 + * @return true成功 false失败
  75 + */
  76 + boolean shareOrMonopolyDataBoard(
  77 + boolean isShare, String id, String accessCredentials, String tenantId);
59 } 78 }
@@ -10,17 +10,40 @@ import java.util.Map; @@ -10,17 +10,40 @@ import java.util.Map;
10 * @author tianfuLei 10 * @author tianfuLei
11 */ 11 */
12 public interface TkDataViewService { 12 public interface TkDataViewService {
13 - TkPageData<TkDataViewDTO> page(Map<String, Object> queryMap, boolean tenantAdmin); 13 + TkPageData<TkDataViewDTO> page(Map<String, Object> queryMap, boolean tenantAdmin);
14 14
15 - TkDataViewDTO saveDataView(TkDataViewDTO TkDataViewDTO); 15 + TkDataViewDTO saveDataView(TkDataViewDTO TkDataViewDTO);
16 16
17 - TkDataViewDTO updateDataView(TkDataViewDTO TkDataViewDTO); 17 + TkDataViewDTO updateDataView(TkDataViewDTO TkDataViewDTO);
18 18
19 - boolean deleteDataView(DeleteDTO deleteDTO); 19 + boolean deleteDataView(DeleteDTO deleteDTO);
20 20
21 - TkDataViewContentInfoDTO getDataViewInfos(String id, String tenantId); 21 + TkDataViewContentInfoDTO getDataViewInfos(String id, String tenantId);
22 22
23 - boolean publishDataView(String id, String tenantId); 23 + TkDataViewDTO getDataViewById(String id, String tenantId);
24 24
25 - boolean cancelPublishDataView(String id, String tenantId); 25 + /**
  26 + * 根据租户ID和大屏ID,判断是否需要密码
  27 + *
  28 + * @param id 大屏ID
  29 + * @param tenantId 租户ID
  30 + * @return 需要true,不需要false
  31 + */
  32 + boolean isNeedCredentialsForPublicView(String id, String tenantId);
  33 +
  34 + /**
  35 + * 分享或取消分享大屏
  36 + *
  37 + * @param isShare true分享 false取消分享
  38 + * @param id 大屏ID
  39 + * @param accessCredentials 分享的密码:不用密码则为null
  40 + * @param tenantId 租户ID
  41 + * @return true成功 false失败
  42 + */
  43 + boolean shareOrMonopolyDataViewCenter(
  44 + boolean isShare, String id, String accessCredentials, String tenantId);
  45 +
  46 + boolean publishDataView(String id, String tenantId);
  47 +
  48 + boolean cancelPublishDataView(String id, String tenantId);
26 } 49 }
1 package org.thingsboard.server.dao.yunteng.service; 1 package org.thingsboard.server.dao.yunteng.service;
2 2
3 import com.fasterxml.jackson.databind.JsonNode; 3 import com.fasterxml.jackson.databind.JsonNode;
4 -import org.thingsboard.server.common.data.DeviceTransportType; 4 +import com.google.common.util.concurrent.ListenableFuture;import org.thingsboard.server.common.data.DeviceTransportType;
5 import org.thingsboard.server.common.data.id.EntityId; 5 import org.thingsboard.server.common.data.id.EntityId;
6 import org.thingsboard.server.common.data.yunteng.dto.DeviceDTO; 6 import org.thingsboard.server.common.data.yunteng.dto.DeviceDTO;
7 import org.thingsboard.server.common.data.yunteng.dto.RelationDeviceDTO; 7 import org.thingsboard.server.common.data.yunteng.dto.RelationDeviceDTO;
@@ -202,4 +202,6 @@ public interface TkDeviceService extends BaseService<TkDeviceEntity> { @@ -202,4 +202,6 @@ public interface TkDeviceService extends BaseService<TkDeviceEntity> {
202 * @return 需要接收RPC控制的网关设备或直连设备的ID 202 * @return 需要接收RPC控制的网关设备或直连设备的ID
203 */ 203 */
204 List<String> rpcDevices(String tenantId,String organizationId,String projectId); 204 List<String> rpcDevices(String tenantId,String organizationId,String projectId);
  205 +
  206 + ListenableFuture<List<DeviceDTO>> findDeviceListByDeviceProfileId(String deviceProfileId,String tenantId);
205 } 207 }
  1 +package org.thingsboard.server.dao.yunteng.service;
  2 +
  3 +import org.thingsboard.server.common.data.yunteng.enums.ShareViewType;
  4 +
  5 +public interface TkShareViewService {
  6 +
  7 + Object viewShareDataById(ShareViewType shareViewType,String id, String accessCredentials, String tenantId);
  8 +
  9 + boolean checkPublicViewNeedCredentials(ShareViewType type, String viewId, String tenantId);
  10 +}
1 package org.thingsboard.server.dao.yunteng.service; 1 package org.thingsboard.server.dao.yunteng.service;
  2 +
  3 +import com.google.common.util.concurrent.ListenableFuture;
2 import org.quartz.SchedulerException; 4 import org.quartz.SchedulerException;
3 import org.thingsboard.server.common.data.yunteng.dto.DeleteDTO; 5 import org.thingsboard.server.common.data.yunteng.dto.DeleteDTO;
4 import org.thingsboard.server.common.data.yunteng.dto.SysJobDTO; 6 import org.thingsboard.server.common.data.yunteng.dto.SysJobDTO;
5 import org.thingsboard.server.common.data.yunteng.utils.tools.TkPageData; 7 import org.thingsboard.server.common.data.yunteng.utils.tools.TkPageData;
  8 +import java.util.List;
6 import java.util.Map; 9 import java.util.Map;
7 10
8 -/**  
9 - * 定时任务调度信息信息 服务层  
10 - */  
11 -public interface TkSysJobService  
12 -{  
13 - /**  
14 - * 获取quartz调度器的计划任务  
15 - *  
16 - * @param queryMap 查询参数  
17 - * @return 分页数据  
18 - */  
19 - TkPageData<SysJobDTO> sysJobPage(Map<String, Object> queryMap);  
20 -  
21 - /**  
22 - * 通过调度任务ID查询调度信息  
23 - *  
24 - * @param id 调度任务ID  
25 - * @return 调度任务对象信息  
26 - */  
27 - SysJobDTO selectJobById(String id); 11 +/** 定时任务调度信息信息 服务层 */
  12 +public interface TkSysJobService {
  13 + /**
  14 + * 获取quartz调度器的计划任务
  15 + *
  16 + * @param queryMap 查询参数
  17 + * @return 分页数据
  18 + */
  19 + TkPageData<SysJobDTO> sysJobPage(Map<String, Object> queryMap);
28 20
29 - /**  
30 - * 暂停任务  
31 - *  
32 - * @param job 调度信息  
33 - * @return 结果  
34 - */  
35 - SysJobDTO pauseJob(SysJobDTO job) throws SchedulerException; 21 + /**
  22 + * 通过调度任务ID查询调度信息
  23 + *
  24 + * @param id 调度任务ID
  25 + * @return 调度任务对象信息
  26 + */
  27 + SysJobDTO selectJobById(String id);
  28 + /**
  29 + * 通过调度任务ID查询调度信息
  30 + *
  31 + * @param id 调度任务ID
  32 + * @return 调度任务对象信息
  33 + */
  34 + ListenableFuture<SysJobDTO> selectJobInfoById(String id);
  35 + /**
  36 + * 暂停任务
  37 + *
  38 + * @param job 调度信息
  39 + * @return 结果
  40 + */
  41 + SysJobDTO pauseJob(SysJobDTO job) throws SchedulerException;
36 42
37 - /**  
38 - * 恢复任务  
39 - *  
40 - * @param job 调度信息  
41 - * @return 结果  
42 - */  
43 - SysJobDTO resumeJob(SysJobDTO job) throws SchedulerException; 43 + /**
  44 + * 恢复任务
  45 + *
  46 + * @param job 调度信息
  47 + * @return 结果
  48 + */
  49 + SysJobDTO resumeJob(SysJobDTO job) throws SchedulerException;
44 50
45 - /**  
46 - * 删除任务后,所对应的trigger也将被删除  
47 - *  
48 - * @param job 调度信息  
49 - * @return 结果  
50 - */  
51 - boolean deleteJob(SysJobDTO job) throws SchedulerException; 51 + /**
  52 + * 删除任务后,所对应的trigger也将被删除
  53 + *
  54 + * @param job 调度信息
  55 + * @return 结果
  56 + */
  57 + boolean deleteJob(SysJobDTO job) throws SchedulerException;
52 58
53 - /**  
54 - * 批量删除调度信息  
55 - *  
56 - * @param deleteDTO 需要删除的数据ID  
57 - * @return 结果 true删除成功 false删除失败  
58 - */  
59 - boolean deleteJobByIds(DeleteDTO deleteDTO) throws SchedulerException; 59 + /**
  60 + * 批量删除定时任务
  61 + *
  62 + * @param sourceIds 来源ID即业务ID
  63 + * @param jobGroup 定时任务分组
  64 + * @param tenantId 租户ID
  65 + * @return true成功 false失败
  66 + */
  67 + boolean deleteJobs(List<String> sourceIds, String jobGroup, String tenantId)
  68 + throws SchedulerException;
60 69
61 - /**  
62 - * 任务调度状态修改  
63 - *  
64 - * @param job 调度信息  
65 - * @return 结果  
66 - */  
67 - SysJobDTO updateSysJobStatus(SysJobDTO job) throws SchedulerException; 70 + /**
  71 + * 批量删除调度信息
  72 + *
  73 + * @param deleteDTO 需要删除的数据ID
  74 + * @return 结果 true删除成功 false删除失败
  75 + */
  76 + boolean deleteJobByIds(DeleteDTO deleteDTO) throws SchedulerException;
68 77
69 - /**  
70 - * 立即运行任务  
71 - *  
72 - * @param job 调度信息  
73 - * @return 结果  
74 - */  
75 - boolean run(SysJobDTO job) throws SchedulerException; 78 + /**
  79 + * 任务调度状态修改
  80 + *
  81 + * @param job 调度信息
  82 + * @return 结果
  83 + */
  84 + SysJobDTO updateSysJobStatus(SysJobDTO job) throws SchedulerException;
76 85
77 - /**  
78 - * 新增或编辑任务  
79 - *  
80 - * @param job 调度信息  
81 - * @return 结果  
82 - */  
83 - SysJobDTO saveOrUpdateJob(SysJobDTO job) throws SchedulerException; 86 + /**
  87 + * 立即运行任务
  88 + *
  89 + * @param job 调度信息
  90 + * @return 结果
  91 + */
  92 + boolean run(SysJobDTO job) throws SchedulerException;
84 93
  94 + /**
  95 + * 新增或编辑任务
  96 + *
  97 + * @param job 调度信息
  98 + * @return 结果
  99 + */
  100 + SysJobDTO saveOrUpdateJob(SysJobDTO job) throws SchedulerException;
85 101
86 - /**  
87 - * 校验cron表达式是否有效  
88 - *  
89 - * @param cronExpression 表达式  
90 - * @return 结果  
91 - */  
92 - boolean checkCronExpressionIsValid(String cronExpression); 102 + /**
  103 + * 校验cron表达式是否有效
  104 + *
  105 + * @param cronExpression 表达式
  106 + * @return 结果
  107 + */
  108 + boolean checkCronExpressionIsValid(String cronExpression);
93 109
94 - /**  
95 - * 通过源ID找到定时任务信息  
96 - * @param sourceId 源ID  
97 - * @return 定时任务信息  
98 - */  
99 - SysJobDTO findSysJobBySourceId(String sourceId);  
100 -}  
  110 + /**
  111 + * 通过源ID找到定时任务信息
  112 + *
  113 + * @param sourceId 源ID
  114 + * @return 定时任务信息
  115 + */
  116 + SysJobDTO findSysJobBySourceId(String sourceId);
  117 +}
  1 +package org.thingsboard.server.dao.yunteng.service;
  2 +
  3 +import com.google.common.util.concurrent.ListenableFuture;import org.quartz.SchedulerException;
  4 +import org.thingsboard.server.common.data.yunteng.dto.DeleteDTO;
  5 +import org.thingsboard.server.common.data.yunteng.dto.task.TkTaskCenterDTO;
  6 +import org.thingsboard.server.common.data.yunteng.utils.tools.TkPageData;
  7 +import java.util.Map;
  8 +
  9 +public interface TkTaskCenterService {
  10 + /**
  11 + * 任务中心分页
  12 + *
  13 + * @param queryMap 分页查询条件
  14 + * @param tenantId 租户ID
  15 + * @return 分页数据
  16 + */
  17 + TkPageData<TkTaskCenterDTO> taskCenterPage(Map<String, Object> queryMap, String tenantId);
  18 +
  19 + /**
  20 + * 修改或保存任务中心
  21 + *
  22 + * @param tkTaskCenterDTO 任务中心信息
  23 + */
  24 + TkTaskCenterDTO saveOrUpdateTaskCenter(TkTaskCenterDTO tkTaskCenterDTO) throws SchedulerException;
  25 +
  26 + /**
  27 + * 删除任务中心
  28 + *
  29 + * @param deleteDTO 删除IDS
  30 + */
  31 + boolean deleteTaskCenter(DeleteDTO deleteDTO)throws SchedulerException;
  32 +
  33 + /**
  34 + * 根据任务中心ID,查询任务信息
  35 + * @param id 任务中心ID
  36 + * @param tenantId 租户ID
  37 + * @return 任务信息
  38 + */
  39 + TkTaskCenterDTO findTaskCenterInfoById(String id,String tenantId);
  40 +
  41 + /**
  42 + * 根据任务中心ID,异步查询任务信息
  43 + * @param id 任务中心ID
  44 + * @return 任务信息
  45 + */
  46 + ListenableFuture<TkTaskCenterDTO> getTaskCenterInfoById(String id);
  47 +
  48 + /**
  49 + * 启用禁用任务中心
  50 + * @param id 任务中心ID
  51 + * @param state 1启用 0禁用
  52 + * @param tenantId 租户ID
  53 + * @return true成功 false失败
  54 + */
  55 + boolean updateState(String id,Integer state,String tenantId)throws SchedulerException;
  56 +
  57 + /**
  58 + * 设备取消任务执行
  59 + * @param id 任务ID
  60 + * @param tbDeviceId 设备ID
  61 + * @param tenantId 租户ID
  62 + * @return true成功 false失败
  63 + */
  64 + boolean cancelExecute(String id,String tbDeviceId,String tenantId);
  65 +}
@@ -14,6 +14,8 @@ @@ -14,6 +14,8 @@
14 <result property="tenantId" column="tenant_id"/> 14 <result property="tenantId" column="tenant_id"/>
15 <result property="updater" column="updater"/> 15 <result property="updater" column="updater"/>
16 <result property="thumbnail" column="thumbnail"/> 16 <result property="thumbnail" column="thumbnail"/>
  17 + <result property="viewType" column="view_type" typeHandler="org.apache.ibatis.type.EnumTypeHandler"/>
  18 + <result property="accessCredentials" column="access_credentials"/>
17 <association property="organizationDTO" 19 <association property="organizationDTO"
18 javaType="org.thingsboard.server.common.data.yunteng.dto.OrganizationDTO"> 20 javaType="org.thingsboard.server.common.data.yunteng.dto.OrganizationDTO">
19 <result property="name" column="organization_name"/> 21 <result property="name" column="organization_name"/>
@@ -30,7 +32,8 @@ @@ -30,7 +32,8 @@
30 </resultMap> 32 </resultMap>
31 33
32 <sql id="columns"> 34 <sql id="columns">
33 - a.id,a.name,a.platform,a.organization_id,a.thumbnail, a.remark,a.update_time,a.create_time,a.creator,a.tenant_id,a.updater,io.name AS organization_name 35 + a.id,a.name,a.platform,a.organization_id,a.thumbnail, a.remark,a.update_time,a.create_time,a.creator,a.tenant_id,
  36 + a.updater,io.name AS organization_name,a.view_type,a.access_credentials
34 </sql> 37 </sql>
35 <select id="getConfigurationCenterPage" resultMap="configurationCenterMap"> 38 <select id="getConfigurationCenterPage" resultMap="configurationCenterMap">
36 SELECT 39 SELECT
@@ -35,7 +35,9 @@ @@ -35,7 +35,9 @@
35 <result property="updater" column="updater"/> 35 <result property="updater" column="updater"/>
36 <result property="description" column="description"/> 36 <result property="description" column="description"/>
37 <result property="customerId" column="customer_id"/> 37 <result property="customerId" column="customer_id"/>
38 - <result property="customerName" column="cusotomer_name"/> 38 + <result property="customerName" column="customer_name"/>
  39 + <result property="customerAdditionalInfo" column="customer_additional_info"
  40 + typeHandler="com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler"/>
39 <result property="organizationId" column="organization_id"/> 41 <result property="organizationId" column="organization_id"/>
40 <result property="gatewayId" column="gateway_id"/> 42 <result property="gatewayId" column="gateway_id"/>
41 <result property="gatewayName" column="gateway_name"/> 43 <result property="gatewayName" column="gateway_name"/>
@@ -83,7 +85,7 @@ @@ -83,7 +85,7 @@
83 </sql> 85 </sql>
84 <select id="getDevicePage" resultMap="deviceMap"> 86 <select id="getDevicePage" resultMap="deviceMap">
85 SELECT 87 SELECT
86 - <include refid="pageColumns"/>,d.customer_id::TEXT AS customer_id,cus.title AS cusotomer_name 88 + <include refid="pageColumns"/>,d.customer_id::TEXT AS customer_id,cus.title AS customer_name,cus.additional_info AS customer_additional_info
87 FROM tk_device ifd 89 FROM tk_device ifd
88 LEFT JOIN device_profile ifdp ON ifd.profile_id = ifdp.id::TEXT 90 LEFT JOIN device_profile ifdp ON ifd.profile_id = ifdp.id::TEXT
89 LEFT JOIN tk_organization io ON io.id = ifd.organization_id 91 LEFT JOIN tk_organization io ON io.id = ifd.organization_id
@@ -14,6 +14,8 @@ @@ -14,6 +14,8 @@
14 <result property="tenantId" column="tenant_id"/> 14 <result property="tenantId" column="tenant_id"/>
15 <result property="updater" column="updater"/> 15 <result property="updater" column="updater"/>
16 <result property="thumbnail" column="thumbnail"/> 16 <result property="thumbnail" column="thumbnail"/>
  17 + <result property="accessCredentials" column="access_credentials"/>
  18 + <result property="viewType" column="view_type" typeHandler="org.apache.ibatis.type.EnumTypeHandler"/>
17 <association property="organizationDTO" 19 <association property="organizationDTO"
18 javaType="org.thingsboard.server.common.data.yunteng.dto.OrganizationDTO"> 20 javaType="org.thingsboard.server.common.data.yunteng.dto.OrganizationDTO">
19 <result property="name" column="organization_name"/> 21 <result property="name" column="organization_name"/>
@@ -34,7 +36,8 @@ @@ -34,7 +36,8 @@
34 </resultMap> 36 </resultMap>
35 37
36 <sql id="columns"> 38 <sql id="columns">
37 - a.id,a.name, a.remark,a.state,a.tenant_id,a.organization_id,a.thumbnail,a.updater,a.update_time,a.create_time,a.creator,io.name AS organization_name 39 + a.id,a.name, a.remark,a.state,a.tenant_id,a.organization_id,a.thumbnail,a.updater,a.update_time,a.create_time,
  40 + a.creator,io.name AS organization_name,a.access_credentials,a.view_type
38 </sql> 41 </sql>
39 <select id="getDataViewPage" resultMap="dataViewMap"> 42 <select id="getDataViewPage" resultMap="dataViewMap">
40 SELECT 43 SELECT