Commit 39120fc9945d6e485b043e89d14d71f5d1801cf4

Authored by 黄 x
1 parent d9eb373a

feat: add convert data filter

Showing 14 changed files with 414 additions and 306 deletions
@@ -24,9 +24,9 @@ import org.thingsboard.server.common.data.yunteng.common.UpdateGroup; @@ -24,9 +24,9 @@ import org.thingsboard.server.common.data.yunteng.common.UpdateGroup;
24 import org.thingsboard.server.common.data.yunteng.constant.FastIotConstants; 24 import org.thingsboard.server.common.data.yunteng.constant.FastIotConstants;
25 import org.thingsboard.server.common.data.yunteng.core.exception.TkDataValidationException; 25 import org.thingsboard.server.common.data.yunteng.core.exception.TkDataValidationException;
26 import org.thingsboard.server.common.data.yunteng.core.message.ErrorMessage; 26 import org.thingsboard.server.common.data.yunteng.core.message.ErrorMessage;
27 -import org.thingsboard.server.common.data.yunteng.dto.ConvertConfigDTO;  
28 -import org.thingsboard.server.common.data.yunteng.dto.ConvertConfigReqDTO;  
29 -import org.thingsboard.server.common.data.yunteng.dto.ConvertReqDTO; 27 +import org.thingsboard.server.common.data.yunteng.dto.convert.ConvertConfigDTO;
  28 +import org.thingsboard.server.common.data.yunteng.dto.convert.ConvertConfigReqDTO;
  29 +import org.thingsboard.server.common.data.yunteng.dto.convert.ConvertReqDTO;
30 import org.thingsboard.server.common.data.yunteng.dto.DeleteDTO; 30 import org.thingsboard.server.common.data.yunteng.dto.DeleteDTO;
31 import org.thingsboard.server.common.data.yunteng.enums.OrderTypeEnum; 31 import org.thingsboard.server.common.data.yunteng.enums.OrderTypeEnum;
32 import org.thingsboard.server.common.data.yunteng.utils.tools.TkPageData; 32 import org.thingsboard.server.common.data.yunteng.utils.tools.TkPageData;
@@ -48,244 +48,276 @@ import static org.thingsboard.server.common.data.yunteng.constant.QueryConstant. @@ -48,244 +48,276 @@ import static org.thingsboard.server.common.data.yunteng.constant.QueryConstant.
48 @Api(tags = {"数据流转控制器"}) 48 @Api(tags = {"数据流转控制器"})
49 @PreAuthorize("@check.checkPermissions({'TENANT_ADMIN'},{})") 49 @PreAuthorize("@check.checkPermissions({'TENANT_ADMIN'},{})")
50 public class TkConvertDataToController extends BaseController { 50 public class TkConvertDataToController extends BaseController {
51 - private final TkRuleChainService tkRuleChainService; 51 + private final TkRuleChainService tkRuleChainService;
  52 + private final ConvertConfigService convertConfigService;
  53 + private final SceneLinkageService sceneLinkageService;
  54 + @Value("${actors.rule.chain.debug_mode_rate_limits_per_tenant.enabled}")
  55 + private boolean debugPerTenantEnabled;
  56 + @Autowired(required = false)
  57 + private ActorSystemContext actorContext;
  58 + @Autowired private TbRuleChainService tbRuleChainService;
52 59
53 - @Value("${actors.rule.chain.debug_mode_rate_limits_per_tenant.enabled}")  
54 - private boolean debugPerTenantEnabled; 60 + @GetMapping(params = {PAGE_SIZE, PAGE})
  61 + @ApiOperation("分页查询")
  62 + public TkPageData<ConvertConfigDTO> pageMessageConfig(
  63 + @RequestParam(PAGE_SIZE) int pageSize,
  64 + @RequestParam(PAGE) int page,
  65 + @ApiParam(value = "0:转换脚本 1:数据流转") @RequestParam(value = "nodeType") Integer nodeType,
  66 + @RequestParam(value = "name", required = false) String name,
  67 + @RequestParam(value = "status", required = false) Integer status,
  68 + @RequestParam(value = ORDER_FILED, required = false) String orderBy,
  69 + @RequestParam(value = ORDER_TYPE, required = false) OrderTypeEnum orderType)
  70 + throws ThingsboardException {
55 71
56 - @Autowired(required = false)  
57 - private ActorSystemContext actorContext; 72 + HashMap<String, Object> queryMap = new HashMap<>();
  73 + queryMap.put(PAGE_SIZE, pageSize);
  74 + queryMap.put(PAGE, page);
  75 + queryMap.put(ORDER_FILED, orderBy);
  76 + queryMap.put("nodeType", nodeType);
  77 + queryMap.put("name", name);
  78 + queryMap.put("status", status);
  79 + if (orderType != null) {
  80 + queryMap.put(ORDER_TYPE, orderType.name());
  81 + }
  82 + return convertConfigService.page(getCurrentUser().getCurrentTenantId(), queryMap);
  83 + }
58 84
59 - private final ConvertConfigService convertConfigService;  
60 - private final SceneLinkageService sceneLinkageService;  
61 - @Autowired  
62 - private TbRuleChainService tbRuleChainService; 85 + @GetMapping("{id}")
  86 + @ApiOperation("获取详情")
  87 + public ResponseEntity<ConvertConfigDTO> findConvertConfigDTOById(@PathVariable("id") String id)
  88 + throws ThingsboardException {
  89 + if(StringUtils.isEmpty(id)){
  90 + throw new TkDataValidationException(ErrorMessage.INVALID_PARAMETER.getMessage());
  91 + }
  92 + return ResponseEntity.ok(
  93 + convertConfigService.findConvertConfigDTOById(getCurrentUser().getCurrentTenantId(), id));
  94 + }
63 95
64 - @GetMapping(params = {PAGE_SIZE, PAGE})  
65 - @ApiOperation("分页查询")  
66 - public TkPageData<ConvertConfigDTO> pageMessageConfig(  
67 - @RequestParam(PAGE_SIZE) int pageSize,  
68 - @RequestParam(PAGE) int page,  
69 - @ApiParam(value = "0:转换脚本 1:数据流转") @RequestParam(value = "nodeType") Integer nodeType,  
70 - @RequestParam(value = "name", required = false) String name,  
71 - @RequestParam(value = "status", required = false) Integer status,  
72 - @RequestParam(value = ORDER_FILED, required = false) String orderBy,  
73 - @RequestParam(value = ORDER_TYPE, required = false) OrderTypeEnum orderType)  
74 - throws ThingsboardException { 96 + @PostMapping("config")
  97 + @ApiOperation("添加或修改转换配置")
  98 + @PreAuthorize(
  99 + "@check.checkPermissions({'TENANT_ADMIN'},{'api:yt:convert:config:post','api:yt:convert:config:update'})")
  100 + public ResponseEntity<ConvertConfigDTO> createOrUpdateConvertData(
  101 + @Validated @RequestBody ConvertConfigDTO convertConfigDTO) throws ThingsboardException {
  102 + convertConfigDTO.setTenantId(getCurrentUser().getCurrentTenantId());
  103 + convertConfigDTO.setNodeType(FastIotConstants.CONVERT_DATA);
  104 + return ResponseEntity.ok(convertConfigService.createOrUpdate(convertConfigDTO));
  105 + }
75 106
76 - HashMap<String, Object> queryMap = new HashMap<>();  
77 - queryMap.put(PAGE_SIZE, pageSize);  
78 - queryMap.put(PAGE, page);  
79 - queryMap.put(ORDER_FILED, orderBy);  
80 - queryMap.put("nodeType", nodeType);  
81 - queryMap.put("name", name);  
82 - queryMap.put("status", status);  
83 - if (orderType != null) {  
84 - queryMap.put(ORDER_TYPE, orderType.name());  
85 - }  
86 - return convertConfigService.page(getCurrentUser().getCurrentTenantId(), queryMap);  
87 - } 107 + @PostMapping("js")
  108 + @ApiOperation("添加或修改转换脚本")
  109 + @PreAuthorize(
  110 + "@check.checkPermissions({'TENANT_ADMIN'},{'api:yt:convert:js:post','api:yt:convert:js:update'})")
  111 + public ResponseEntity<ConvertConfigDTO> createOrUpdateConvertJS(
  112 + @Validated @RequestBody ConvertConfigDTO convertConfigDTO) throws ThingsboardException {
  113 + convertConfigDTO.setTenantId(getCurrentUser().getCurrentTenantId());
  114 + convertConfigDTO.setNodeType(FastIotConstants.JAVA_SCRIPT);
  115 + return ResponseEntity.ok(convertConfigService.createOrUpdate(convertConfigDTO));
  116 + }
88 117
89 - @PostMapping("config")  
90 - @ApiOperation("添加或修改转换配置")  
91 - @PreAuthorize("@check.checkPermissions({'TENANT_ADMIN'},{'api:yt:convert:config:post','api:yt:convert:config:update'})")  
92 - public ResponseEntity<ConvertConfigDTO> createOrUpdateConvertData(  
93 - @Validated @RequestBody ConvertConfigDTO convertConfigDTO) throws ThingsboardException {  
94 - convertConfigDTO.setTenantId(getCurrentUser().getCurrentTenantId());  
95 - convertConfigDTO.setNodeType(FastIotConstants.CONVERT_DATA);  
96 - return ResponseEntity.ok(convertConfigService.createOrUpdate(convertConfigDTO)); 118 + @PostMapping("/check/config")
  119 + @ApiOperation("检查配置名称是否存在")
  120 + public ResponseEntity<Boolean> checkConvertConfig(@RequestBody Map<String, String> checkParam)
  121 + throws ThingsboardException {
  122 + String type = checkParam.get("type");
  123 + String name = checkParam.get("name");
  124 + if (StringUtils.isEmpty(type) || StringUtils.isEmpty(name)) {
  125 + throw new TkDataValidationException(ErrorMessage.INVALID_PARAMETER.getMessage());
97 } 126 }
  127 + return ResponseEntity.ok(
  128 + convertConfigService.checkConvertConfigNameExist(
  129 + null, name, type, getCurrentUser().getCurrentTenantId()));
  130 + }
98 131
99 - @PostMapping("js")  
100 - @ApiOperation("添加或修改转换脚本")  
101 - @PreAuthorize("@check.checkPermissions({'TENANT_ADMIN'},{'api:yt:convert:js:post','api:yt:convert:js:update'})")  
102 - public ResponseEntity<ConvertConfigDTO> createOrUpdateConvertJS(  
103 - @Validated @RequestBody ConvertConfigDTO convertConfigDTO) throws ThingsboardException {  
104 - convertConfigDTO.setTenantId(getCurrentUser().getCurrentTenantId());  
105 - convertConfigDTO.setNodeType(FastIotConstants.JAVA_SCRIPT);  
106 - return ResponseEntity.ok(convertConfigService.createOrUpdate(convertConfigDTO));  
107 - } 132 + @DeleteMapping("config")
  133 + @ApiOperation("删除转换配置")
  134 + @PreAuthorize("@check.checkPermissions({'TENANT_ADMIN'},{'api:yt:convert:config:delete'})")
  135 + public ResponseEntity<Boolean> deleteConfig(
  136 + @Validated(DeleteGroup.class) @RequestBody DeleteDTO deleteDTO) throws ThingsboardException {
  137 + return delete(deleteDTO, FastIotConstants.CONVERT_DATA);
  138 + }
108 139
109 - @PostMapping("/check/config")  
110 - @ApiOperation("检查配置名称是否存在")  
111 - public ResponseEntity<Boolean> checkConvertConfig(@RequestBody Map<String, String> checkParam)  
112 - throws ThingsboardException {  
113 - String type = checkParam.get("type");  
114 - String name = checkParam.get("name");  
115 - if (StringUtils.isEmpty(type) || StringUtils.isEmpty(name)) {  
116 - throw new TkDataValidationException(ErrorMessage.INVALID_PARAMETER.getMessage());  
117 - }  
118 - return ResponseEntity.ok(  
119 - convertConfigService.checkConvertConfigNameExist(  
120 - null, name, type, getCurrentUser().getCurrentTenantId()));  
121 - } 140 + @DeleteMapping("js")
  141 + @ApiOperation("删除转换脚本")
  142 + @PreAuthorize("@check.checkPermissions({'TENANT_ADMIN'},{'api:yt:convert:js:delete'})")
  143 + public ResponseEntity<Boolean> deleteJS(
  144 + @Validated(DeleteGroup.class) @RequestBody DeleteDTO deleteDTO) throws ThingsboardException {
  145 + return delete(deleteDTO, FastIotConstants.JAVA_SCRIPT);
  146 + }
122 147
123 - @DeleteMapping("config")  
124 - @ApiOperation("删除转换配置")  
125 - @PreAuthorize("@check.checkPermissions({'TENANT_ADMIN'},{'api:yt:convert:config:delete'})")  
126 - public ResponseEntity<Boolean> deleteConfig(  
127 - @Validated(DeleteGroup.class) @RequestBody DeleteDTO deleteDTO) throws ThingsboardException {  
128 - return delete(deleteDTO, FastIotConstants.CONVERT_DATA); 148 + @PostMapping("update/config")
  149 + @ApiOperation("启用或禁用配置")
  150 + public RuleChainMetaData updateConfig(
  151 + @Validated(UpdateGroup.class) @RequestBody ConvertConfigReqDTO convertConfigReqDTO)
  152 + throws ThingsboardException {
  153 + if (convertConfigService.checkConvertConfigStatusExist(
  154 + convertConfigReqDTO.getConvertIds(),
  155 + convertConfigReqDTO.getStatus(),
  156 + getCurrentUser().getCurrentTenantId())) {
  157 + throw new TkDataValidationException(ErrorMessage.DATA_ALREADY_EXISTS.getMessage());
129 } 158 }
130 -  
131 - @DeleteMapping("js")  
132 - @ApiOperation("删除转换脚本")  
133 - @PreAuthorize("@check.checkPermissions({'TENANT_ADMIN'},{'api:yt:convert:js:delete'})")  
134 - public ResponseEntity<Boolean> deleteJS(  
135 - @Validated(DeleteGroup.class) @RequestBody DeleteDTO deleteDTO) throws ThingsboardException {  
136 - return delete(deleteDTO, FastIotConstants.JAVA_SCRIPT); 159 + List<String> ids = convertConfigReqDTO.getConvertIds();
  160 + int status = convertConfigReqDTO.getStatus();
  161 + List<RuleNode> nodes =
  162 + convertConfigService.getRuleNodesByConvertConfigIds(
  163 + ids, null, FastIotConstants.CONVERT_DATA);
  164 + RuleChainMetaData ruleChainMetaData = new RuleChainMetaData();
  165 + if (null != nodes && nodes.size() > 0) {
  166 + ruleChainMetaData = saveRuleChain(nodes, status, FastIotConstants.CONVERT_DATA);
137 } 167 }
  168 + convertConfigService.updateConvertStatusByIds(
  169 + ids, status, getCurrentUser().getCurrentTenantId());
  170 + return ruleChainMetaData;
  171 + }
138 172
139 - @PostMapping("update/config")  
140 - @ApiOperation("启用或禁用配置")  
141 - public RuleChainMetaData updateConfig(  
142 - @Validated(UpdateGroup.class) @RequestBody ConvertConfigReqDTO convertConfigReqDTO)  
143 - throws ThingsboardException {  
144 - if (convertConfigService.checkConvertConfigStatusExist(  
145 - convertConfigReqDTO.getConvertIds(),  
146 - convertConfigReqDTO.getStatus(),  
147 - getCurrentUser().getCurrentTenantId())) {  
148 - throw new TkDataValidationException(ErrorMessage.DATA_ALREADY_EXISTS.getMessage());  
149 - }  
150 - List<String> ids = convertConfigReqDTO.getConvertIds();  
151 - int status = convertConfigReqDTO.getStatus();  
152 - List<RuleNode> nodes =  
153 - convertConfigService.getRuleNodesByConvertConfigIds(  
154 - ids, null, FastIotConstants.CONVERT_DATA);  
155 - RuleChainMetaData ruleChainMetaData = new RuleChainMetaData();  
156 - if (null != nodes && nodes.size() > 0) {  
157 - ruleChainMetaData = saveRuleChain(nodes, status, FastIotConstants.CONVERT_DATA);  
158 - }  
159 - convertConfigService.updateConvertStatusByIds(  
160 - ids, status, getCurrentUser().getCurrentTenantId());  
161 - return ruleChainMetaData; 173 + @PostMapping("update/js")
  174 + @ApiOperation("启用或禁用转换脚本")
  175 + public RuleChainMetaData updateJs(
  176 + @Validated(UpdateGroup.class) @RequestBody ConvertReqDTO convertJSReqDTO)
  177 + throws ThingsboardException {
  178 + int status = convertJSReqDTO.getStatus();
  179 + if (status == FastIotConstants.StateValue.ENABLE
  180 + && convertConfigService.checkConvertJSStatusEnable(getCurrentUser().getCurrentTenantId())) {
  181 + throw new TkDataValidationException(ErrorMessage.CONVERT_JS_IS_ALONE.getMessage());
162 } 182 }
  183 + List<String> ids = new ArrayList<>();
  184 + ids.add(convertJSReqDTO.getId());
  185 + List<RuleNode> nodes =
  186 + convertConfigService.getRuleNodesByConvertConfigIds(
  187 + ids, null, FastIotConstants.JAVA_SCRIPT);
163 188
164 - @PostMapping("update/js")  
165 - @ApiOperation("启用或禁用转换脚本")  
166 - public RuleChainMetaData updateJs(  
167 - @Validated(UpdateGroup.class) @RequestBody ConvertReqDTO convertJSReqDTO)  
168 - throws ThingsboardException {  
169 - int status = convertJSReqDTO.getStatus();  
170 - if (status == FastIotConstants.StateValue.ENABLE  
171 - && convertConfigService.checkConvertJSStatusEnable(getCurrentUser().getCurrentTenantId())) {  
172 - throw new TkDataValidationException(ErrorMessage.CONVERT_JS_IS_ALONE.getMessage());  
173 - }  
174 - List<String> ids = new ArrayList<>();  
175 - ids.add(convertJSReqDTO.getId());  
176 - List<RuleNode> nodes =  
177 - convertConfigService.getRuleNodesByConvertConfigIds(  
178 - ids, null, FastIotConstants.JAVA_SCRIPT); 189 + RuleChainMetaData ruleChainMetaData =
  190 + saveRuleChain(nodes, status, FastIotConstants.JAVA_SCRIPT);
  191 + convertConfigService.updateConvertStatusByIds(
  192 + ids, status, getCurrentUser().getCurrentTenantId());
  193 + return ruleChainMetaData;
  194 + }
179 195
180 - RuleChainMetaData ruleChainMetaData =  
181 - saveRuleChain(nodes, status, FastIotConstants.JAVA_SCRIPT);  
182 - convertConfigService.updateConvertStatusByIds(  
183 - ids, status, getCurrentUser().getCurrentTenantId());  
184 - return ruleChainMetaData; 196 + @PostMapping("update/scene")
  197 + @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
  198 + @ApiOperation("启用或禁用场景联动")
  199 + public RuleChainMetaData updateScene(
  200 + @Validated(UpdateGroup.class) @RequestBody ConvertReqDTO convertReqDTO)
  201 + throws ThingsboardException {
  202 + int status = -1;
  203 + String sceneId = convertReqDTO.getId();
  204 + String currentTenant = getCurrentUser().getCurrentTenantId();
  205 + Integer sceneStatus = convertReqDTO.getStatus();
  206 + JsonNode configuration =
  207 + sceneLinkageService.getRuleNodeConfig(
  208 + sceneId,
  209 + currentTenant,
  210 + getCurrentUser().getCustomerId().getId().toString(),
  211 + sceneStatus);
  212 + boolean noValue = configuration == null;
  213 + if (noValue && convertReqDTO.getStatus() == FastIotConstants.StateValue.DISABLE) {
  214 + status = FastIotConstants.StateValue.DISABLE;
185 } 215 }
186 -  
187 - @PostMapping("update/scene")  
188 - @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")  
189 - @ApiOperation("启用或禁用场景联动")  
190 - public RuleChainMetaData updateScene(  
191 - @Validated(UpdateGroup.class) @RequestBody ConvertReqDTO convertReqDTO)  
192 - throws ThingsboardException {  
193 - int status = -1;  
194 - String sceneId = convertReqDTO.getId();  
195 - String currentTenant = getCurrentUser().getCurrentTenantId();  
196 - Integer sceneStatus = convertReqDTO.getStatus();  
197 - JsonNode configuration = sceneLinkageService.getRuleNodeConfig(sceneId, currentTenant, getCurrentUser().getCustomerId().getId().toString(), sceneStatus);  
198 - boolean noValue = configuration == null;  
199 - if (noValue && convertReqDTO.getStatus() == FastIotConstants.StateValue.DISABLE) {  
200 - status = FastIotConstants.StateValue.DISABLE;  
201 - }  
202 - if (!noValue) {  
203 - status = FastIotConstants.StateValue.ENABLE;  
204 - }  
205 - List<RuleNode> ruleNodes = new ArrayList<>();  
206 - RuleNode scene = new RuleNode();  
207 - scene.setName("Scene");  
208 - scene.setType("org.thingsboard.rule.engine.yunteng.scene.TbSceneReactNode");  
209 - scene.setConfiguration(configuration);  
210 - ruleNodes.add(scene);  
211 - RuleChainMetaData result = saveRuleChain(ruleNodes, status, FastIotConstants.SCENE_REACT);  
212 - sceneLinkageService.updateSceneStatus(sceneId, sceneStatus, currentTenant);  
213 - return result; 216 + if (!noValue) {
  217 + status = FastIotConstants.StateValue.ENABLE;
214 } 218 }
  219 + List<RuleNode> ruleNodes = new ArrayList<>();
  220 + RuleNode scene = new RuleNode();
  221 + scene.setName("Scene");
  222 + scene.setType("org.thingsboard.rule.engine.yunteng.scene.TbSceneReactNode");
  223 + scene.setConfiguration(configuration);
  224 + ruleNodes.add(scene);
  225 + RuleChainMetaData result = saveRuleChain(ruleNodes, status, FastIotConstants.SCENE_REACT);
  226 + sceneLinkageService.updateSceneStatus(sceneId, sceneStatus, currentTenant);
  227 + return result;
  228 + }
215 229
216 - /**  
217 - * 保存规则链  
218 - *  
219 - * @param nodes 规则节点  
220 - * @param status 0禁用 1启用  
221 - * @return 规则节点数据  
222 - */  
223 - private RuleChainMetaData saveRuleChain(List<RuleNode> nodes, Integer status, Integer nodeType)  
224 - throws ThingsboardException {  
225 - boolean needSaveRuleNode;  
226 - TenantId tenantId = getTenantId();  
227 - // 1. GET DEFAULT RULE CHAIN  
228 - RuleChain ruleChain = tkRuleChainService.getRootTenantRuleChain(getTenantId());  
229 - // 2. GET RULE CHAIN METADATA  
230 - RuleChainMetaData ruleChainMetaData =  
231 - ruleChainService.loadRuleChainMetaData(getTenantId(), ruleChain.getId());  
232 - // 3. SETUP CONNECTION AND ADD OR DELETE RULE NODE  
233 - if (status == FastIotConstants.MagicNumber.ZERO) {  
234 - needSaveRuleNode = convertConfigService.deleteRuleNode(nodes, ruleChainMetaData, nodeType);  
235 - } else {  
236 - convertConfigService.addRuleNode(nodes, ruleChainMetaData, nodeType);  
237 - needSaveRuleNode = true; 230 + /**
  231 + * 保存规则链
  232 + *
  233 + * @param nodes 规则节点
  234 + * @param status 0禁用 1启用
  235 + * @return 规则节点数据
  236 + */
  237 + private RuleChainMetaData saveRuleChain(List<RuleNode> nodes, Integer status, Integer nodeType)
  238 + throws ThingsboardException {
  239 + boolean needSaveRuleNode;
  240 + TenantId tenantId = getTenantId();
  241 + // 1. GET DEFAULT RULE CHAIN
  242 + RuleChain ruleChain = tkRuleChainService.getRootTenantRuleChain(getTenantId());
  243 + // 2. GET RULE CHAIN METADATA
  244 + RuleChainMetaData ruleChainMetaData =
  245 + ruleChainService.loadRuleChainMetaData(getTenantId(), ruleChain.getId());
  246 + // 3. SETUP CONNECTION AND ADD OR DELETE RULE NODE
  247 + if (status == FastIotConstants.MagicNumber.ZERO) {
  248 + needSaveRuleNode = convertConfigService.deleteRuleNode(nodes, ruleChainMetaData, nodeType);
  249 + } else {
  250 + convertConfigService.addRuleNode(nodes, ruleChainMetaData, nodeType);
  251 + needSaveRuleNode = true;
  252 + }
  253 + // 4. SAVE METADATA
  254 + RuleChainMetaData savedRuleChainMetaData = null;
  255 + if (needSaveRuleNode) {
  256 + if (debugPerTenantEnabled) {
  257 + ConcurrentMap<TenantId, DebugTbRateLimits> debugPerTenantLimits =
  258 + actorContext.getDebugPerTenantLimits();
  259 + DebugTbRateLimits debugTbRateLimits = debugPerTenantLimits.getOrDefault(tenantId, null);
  260 + if (debugTbRateLimits != null) {
  261 + debugPerTenantLimits.remove(tenantId, debugTbRateLimits);
238 } 262 }
239 - // 4. SAVE METADATA  
240 - RuleChainMetaData savedRuleChainMetaData = null;  
241 - if (needSaveRuleNode) {  
242 - if (debugPerTenantEnabled) {  
243 - ConcurrentMap<TenantId, DebugTbRateLimits> debugPerTenantLimits =  
244 - actorContext.getDebugPerTenantLimits();  
245 - DebugTbRateLimits debugTbRateLimits = debugPerTenantLimits.getOrDefault(tenantId, null);  
246 - if (debugTbRateLimits != null) {  
247 - debugPerTenantLimits.remove(tenantId, debugTbRateLimits);  
248 - }  
249 - }  
250 - ruleChain = checkRuleChain(ruleChainMetaData.getRuleChainId(), Operation.WRITE);  
251 - RuleChainUpdateResult result = ruleChainService.saveRuleChainMetaData(tenantId, ruleChainMetaData);  
252 - checkNotNull(result.isSuccess() ? true : null);  
253 -  
254 - List<RuleChain> updatedRuleChains;  
255 - if (result.isSuccess()) {  
256 - updatedRuleChains = tbRuleChainService.updateRelatedRuleChains(tenantId, ruleChainMetaData.getRuleChainId(), result);  
257 - } else {  
258 - updatedRuleChains = Collections.emptyList();  
259 - } 263 + }
  264 + ruleChain = checkRuleChain(ruleChainMetaData.getRuleChainId(), Operation.WRITE);
  265 + RuleChainUpdateResult result =
  266 + ruleChainService.saveRuleChainMetaData(tenantId, ruleChainMetaData);
  267 + checkNotNull(result.isSuccess() ? true : null);
260 268
261 - savedRuleChainMetaData = checkNotNull(ruleChainService.loadRuleChainMetaData(tenantId, ruleChainMetaData.getRuleChainId())); 269 + List<RuleChain> updatedRuleChains;
  270 + if (result.isSuccess()) {
  271 + updatedRuleChains =
  272 + tbRuleChainService.updateRelatedRuleChains(
  273 + tenantId, ruleChainMetaData.getRuleChainId(), result);
  274 + } else {
  275 + updatedRuleChains = Collections.emptyList();
  276 + }
262 277
263 - if (ruleChain.getType().equals(RuleChainType.CORE)) {  
264 - tbClusterService.broadcastEntityStateChangeEvent(ruleChain.getTenantId(), ruleChain.getId(), ComponentLifecycleEvent.UPDATED);  
265 - updatedRuleChains.forEach(updatedRuleChain -> {  
266 - tbClusterService.broadcastEntityStateChangeEvent(updatedRuleChain.getTenantId(), updatedRuleChain.getId(), ComponentLifecycleEvent.UPDATED);  
267 - });  
268 - } 278 + savedRuleChainMetaData =
  279 + checkNotNull(
  280 + ruleChainService.loadRuleChainMetaData(tenantId, ruleChainMetaData.getRuleChainId()));
269 281
270 - logEntityAction(ruleChain.getId(), ruleChain, null, ActionType.UPDATED, null, ruleChainMetaData); 282 + if (ruleChain.getType().equals(RuleChainType.CORE)) {
  283 + tbClusterService.broadcastEntityStateChangeEvent(
  284 + ruleChain.getTenantId(), ruleChain.getId(), ComponentLifecycleEvent.UPDATED);
  285 + updatedRuleChains.forEach(
  286 + updatedRuleChain -> {
  287 + tbClusterService.broadcastEntityStateChangeEvent(
  288 + updatedRuleChain.getTenantId(),
  289 + updatedRuleChain.getId(),
  290 + ComponentLifecycleEvent.UPDATED);
  291 + });
  292 + }
271 293
272 - for (RuleChain updatedRuleChain : updatedRuleChains) {  
273 - RuleChainMetaData updatedRuleChainMetaData = checkNotNull(ruleChainService.loadRuleChainMetaData(tenantId, updatedRuleChain.getId()));  
274 - logEntityAction(updatedRuleChain.getId(), updatedRuleChain, null, ActionType.UPDATED, null, updatedRuleChainMetaData);  
275 - } 294 + logEntityAction(
  295 + ruleChain.getId(), ruleChain, null, ActionType.UPDATED, null, ruleChainMetaData);
276 296
277 - }  
278 - return savedRuleChainMetaData; 297 + for (RuleChain updatedRuleChain : updatedRuleChains) {
  298 + RuleChainMetaData updatedRuleChainMetaData =
  299 + checkNotNull(
  300 + ruleChainService.loadRuleChainMetaData(tenantId, updatedRuleChain.getId()));
  301 + logEntityAction(
  302 + updatedRuleChain.getId(),
  303 + updatedRuleChain,
  304 + null,
  305 + ActionType.UPDATED,
  306 + null,
  307 + updatedRuleChainMetaData);
  308 + }
279 } 309 }
  310 + return savedRuleChainMetaData;
  311 + }
280 312
281 - private ResponseEntity<Boolean> delete(DeleteDTO deleteDTO, Integer nodeType)  
282 - throws ThingsboardException {  
283 - List<RuleNode> nodes =  
284 - convertConfigService.getRuleNodesByConvertConfigIds(  
285 - new ArrayList<>(deleteDTO.getIds()), FastIotConstants.StateValue.ENABLE, nodeType);  
286 - if (nodes != null && nodes.size() > FastIotConstants.MagicNumber.ZERO) {  
287 - saveRuleChain(nodes, 0, nodeType);  
288 - }  
289 - return ResponseEntity.ok(convertConfigService.deleteConvertConfig(deleteDTO, nodeType)); 313 + private ResponseEntity<Boolean> delete(DeleteDTO deleteDTO, Integer nodeType)
  314 + throws ThingsboardException {
  315 + List<RuleNode> nodes =
  316 + convertConfigService.getRuleNodesByConvertConfigIds(
  317 + new ArrayList<>(deleteDTO.getIds()), FastIotConstants.StateValue.ENABLE, nodeType);
  318 + if (nodes != null && nodes.size() > FastIotConstants.MagicNumber.ZERO) {
  319 + saveRuleChain(nodes, 0, nodeType);
290 } 320 }
  321 + return ResponseEntity.ok(convertConfigService.deleteConvertConfig(deleteDTO, nodeType));
  322 + }
291 } 323 }
@@ -208,43 +208,10 @@ public class TkDeviceController extends BaseController { @@ -208,43 +208,10 @@ public class TkDeviceController extends BaseController {
208 } 208 }
209 209
210 @PreAuthorize("@check.checkPermissions({'TENANT_ADMIN','CUSTOMER_USER'},{})") 210 @PreAuthorize("@check.checkPermissions({'TENANT_ADMIN','CUSTOMER_USER'},{})")
211 - @GetMapping(params = {PAGE_SIZE, PAGE}) 211 + @PostMapping(params = {PAGE_SIZE, PAGE})
212 @ApiOperation("查询") 212 @ApiOperation("查询")
213 - public TkPageData<DeviceDTO> pageDevice(  
214 - @RequestParam(PAGE_SIZE) int pageSize,  
215 - @RequestParam(PAGE) int page,  
216 - @RequestParam(value = "name", required = false) String name,  
217 - @RequestParam(value = "deviceState", required = false) DeviceState deviceState,  
218 - @RequestParam(value = "deviceType", required = false) DeviceTypeEnum deviceType,  
219 - @RequestParam(value = "organizationId", required = false) String organizationId,  
220 - @RequestParam(value = "alarmStatus", required = false) Integer alarmStatus,  
221 - @RequestParam(value = "deviceProfileId", required = false) String deviceProfileId,  
222 - @RequestParam(value = ORDER_FILED, required = false) String orderBy,  
223 - @RequestParam(value = ORDER_TYPE, required = false) OrderTypeEnum orderType) 213 + public TkPageData<DeviceDTO> pageDevice(@RequestBody Map<String,Object> queryMap)
224 throws ThingsboardException { 214 throws ThingsboardException {
225 - HashMap<String, Object> queryMap = new HashMap<>();  
226 - queryMap.put(PAGE_SIZE, pageSize);  
227 - queryMap.put(PAGE, page);  
228 - queryMap.put(ORDER_FILED, orderBy);  
229 - queryMap.put("name", name);  
230 - queryMap.put("alarmStatus", alarmStatus);  
231 - queryMap.put("deviceProfileId", deviceProfileId);  
232 - if (deviceState != null) {  
233 - if (deviceState != DeviceState.INACTIVE) {  
234 - queryMap.put("deviceState", deviceState == DeviceState.ONLINE);  
235 - } else {  
236 - queryMap.put("activeState", DeviceState.INACTIVE);  
237 - }  
238 - }  
239 - if (deviceType != null) {  
240 - queryMap.put("deviceType", deviceType.name());  
241 - }  
242 - if (!StringUtils.isEmpty(organizationId)) {  
243 - queryMap.put("organizationId", organizationId);  
244 - }  
245 - if (orderType != null) {  
246 - queryMap.put(ORDER_TYPE, orderType.name());  
247 - }  
248 // 如果当前用户是客户 215 // 如果当前用户是客户
249 if (getCurrentUser().isCustomerUser()) { 216 if (getCurrentUser().isCustomerUser()) {
250 queryMap.put("customerId", getCurrentUser().getCustomerId().toString()); 217 queryMap.put("customerId", getCurrentUser().getCustomerId().toString());
common/data/src/main/java/org/thingsboard/server/common/data/yunteng/dto/convert/ConvertConfigDTO.java renamed from common/data/src/main/java/org/thingsboard/server/common/data/yunteng/dto/ConvertConfigDTO.java
1 -package org.thingsboard.server.common.data.yunteng.dto; 1 +package org.thingsboard.server.common.data.yunteng.dto.convert;
2 2
3 import com.fasterxml.jackson.databind.JsonNode; 3 import com.fasterxml.jackson.databind.JsonNode;
4 import io.swagger.annotations.ApiModelProperty; 4 import io.swagger.annotations.ApiModelProperty;
5 import lombok.Data; 5 import lombok.Data;
  6 +import lombok.EqualsAndHashCode;
  7 +import org.thingsboard.server.common.data.yunteng.dto.TenantDTO;
  8 +import org.thingsboard.server.common.data.yunteng.enums.DatasourceTypeEnum;
6 9
7 import javax.validation.constraints.NotEmpty; 10 import javax.validation.constraints.NotEmpty;
8 import javax.validation.constraints.NotNull; 11 import javax.validation.constraints.NotNull;
9 12
  13 +@EqualsAndHashCode(callSuper = true)
10 @Data 14 @Data
11 public class ConvertConfigDTO extends TenantDTO { 15 public class ConvertConfigDTO extends TenantDTO {
12 @ApiModelProperty(value = "数据转换配置名称", required = true) 16 @ApiModelProperty(value = "数据转换配置名称", required = true)
@@ -27,6 +31,12 @@ public class ConvertConfigDTO extends TenantDTO { @@ -27,6 +31,12 @@ public class ConvertConfigDTO extends TenantDTO {
27 @ApiModelProperty(value = "配置状态") 31 @ApiModelProperty(value = "配置状态")
28 private Integer status; 32 private Integer status;
29 33
  34 + @ApiModelProperty(value = "数据源类型")
  35 + private DatasourceTypeEnum datasourceType;
  36 +
  37 + @ApiModelProperty(value = "数据源内容")
  38 + private JsonNode datasourceContent;
  39 +
30 private transient Integer nodeType; 40 private transient Integer nodeType;
31 41
32 private String remark; 42 private String remark;
common/data/src/main/java/org/thingsboard/server/common/data/yunteng/dto/convert/ConvertConfigReqDTO.java renamed from common/data/src/main/java/org/thingsboard/server/common/data/yunteng/dto/ConvertConfigReqDTO.java
1 -package org.thingsboard.server.common.data.yunteng.dto; 1 +package org.thingsboard.server.common.data.yunteng.dto.convert;
2 2
3 import io.swagger.annotations.ApiModelProperty; 3 import io.swagger.annotations.ApiModelProperty;
4 import lombok.Data; 4 import lombok.Data;
  1 +package org.thingsboard.server.common.data.yunteng.dto.convert;
  2 +
  3 +import lombok.Data;
  4 +
  5 +import java.util.List;
  6 +
  7 +@Data
  8 +public class ConvertDevicesDTO {
  9 + private String product;
  10 + private List<String> devices;
  11 +}
common/data/src/main/java/org/thingsboard/server/common/data/yunteng/dto/convert/ConvertReqDTO.java renamed from common/data/src/main/java/org/thingsboard/server/common/data/yunteng/dto/ConvertReqDTO.java
1 -package org.thingsboard.server.common.data.yunteng.dto; 1 +package org.thingsboard.server.common.data.yunteng.dto.convert;
2 2
3 import com.fasterxml.jackson.databind.JsonNode; 3 import com.fasterxml.jackson.databind.JsonNode;
4 import io.swagger.annotations.ApiModelProperty; 4 import io.swagger.annotations.ApiModelProperty;
  1 +package org.thingsboard.server.common.data.yunteng.dto.convert;
  2 +
  3 +import lombok.Data;
  4 +
  5 +import java.util.List;
  6 +
  7 +@Data
  8 +public class DatasourceContentDTO {
  9 + private List<String> convertProducts;
  10 + private List<ConvertDevicesDTO> convertDevices;
  11 +}
  1 +package org.thingsboard.server.common.data.yunteng.enums;
  2 +
  3 +public enum DatasourceTypeEnum {
  4 + ALL,
  5 + PRODUCTS,
  6 + DEVICES
  7 +}
1 package org.thingsboard.server.dao.yunteng; 1 package org.thingsboard.server.dao.yunteng;
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;
6 import com.fasterxml.jackson.databind.JsonNode; 7 import com.fasterxml.jackson.databind.JsonNode;
7 import lombok.Data; 8 import lombok.Data;
  9 +import org.apache.ibatis.type.EnumTypeHandler;
8 import org.thingsboard.server.common.data.yunteng.constant.ModelConstants; 10 import org.thingsboard.server.common.data.yunteng.constant.ModelConstants;
  11 +import org.thingsboard.server.common.data.yunteng.enums.DatasourceTypeEnum;
9 import org.thingsboard.server.dao.yunteng.entities.TenantBaseEntity; 12 import org.thingsboard.server.dao.yunteng.entities.TenantBaseEntity;
10 13
11 @Data 14 @Data
@@ -14,10 +17,19 @@ public class ConvertConfig extends TenantBaseEntity { @@ -14,10 +17,19 @@ public class ConvertConfig extends TenantBaseEntity {
14 private static final long serialVersionUID = -8354537796750197427L; 17 private static final long serialVersionUID = -8354537796750197427L;
15 private String name; 18 private String name;
16 private String type; 19 private String type;
  20 +
  21 + @TableField(typeHandler = EnumTypeHandler.class)
  22 + private DatasourceTypeEnum datasourceType;
  23 +
17 @TableField(typeHandler = JacksonTypeHandler.class) 24 @TableField(typeHandler = JacksonTypeHandler.class)
18 - private JsonNode configuration; 25 + private JsonNode datasourceContent;
  26 +
19 @TableField(typeHandler = JacksonTypeHandler.class) 27 @TableField(typeHandler = JacksonTypeHandler.class)
  28 + private JsonNode configuration;
  29 +
  30 + @TableField(typeHandler = JacksonTypeHandler.class,updateStrategy = FieldStrategy.IGNORED)
20 private JsonNode additionalInfo; 31 private JsonNode additionalInfo;
  32 +
21 private Integer status; 33 private Integer status;
22 private Integer nodeType; 34 private Integer nodeType;
23 private String remark; 35 private String remark;
@@ -17,8 +17,9 @@ import org.thingsboard.server.common.data.yunteng.constant.FastIotConstants; @@ -17,8 +17,9 @@ import org.thingsboard.server.common.data.yunteng.constant.FastIotConstants;
17 import org.thingsboard.server.common.data.yunteng.constant.ModelConstants; 17 import org.thingsboard.server.common.data.yunteng.constant.ModelConstants;
18 import org.thingsboard.server.common.data.yunteng.core.exception.TkDataValidationException; 18 import org.thingsboard.server.common.data.yunteng.core.exception.TkDataValidationException;
19 import org.thingsboard.server.common.data.yunteng.core.message.ErrorMessage; 19 import org.thingsboard.server.common.data.yunteng.core.message.ErrorMessage;
20 -import org.thingsboard.server.common.data.yunteng.dto.ConvertConfigDTO; 20 +import org.thingsboard.server.common.data.yunteng.dto.convert.ConvertConfigDTO;
21 import org.thingsboard.server.common.data.yunteng.dto.DeleteDTO; 21 import org.thingsboard.server.common.data.yunteng.dto.DeleteDTO;
  22 +import org.thingsboard.server.common.data.yunteng.dto.convert.DatasourceContentDTO;
22 import org.thingsboard.server.common.data.yunteng.utils.tools.TkPageData; 23 import org.thingsboard.server.common.data.yunteng.utils.tools.TkPageData;
23 import org.thingsboard.server.dao.yunteng.ConvertConfig; 24 import org.thingsboard.server.dao.yunteng.ConvertConfig;
24 import org.thingsboard.server.dao.yunteng.mapper.ConvertConfigMapper; 25 import org.thingsboard.server.dao.yunteng.mapper.ConvertConfigMapper;
@@ -63,6 +64,8 @@ public class TkConvertConfigServiceImpl @@ -63,6 +64,8 @@ public class TkConvertConfigServiceImpl
63 @Transactional 64 @Transactional
64 public ConvertConfigDTO createOrUpdate(ConvertConfigDTO convertConfig) { 65 public ConvertConfigDTO createOrUpdate(ConvertConfigDTO convertConfig) {
65 ConvertConfig config = convertConfig.getEntity(ConvertConfig.class); 66 ConvertConfig config = convertConfig.getEntity(ConvertConfig.class);
  67 + config.setDatasourceContent(
  68 + JacksonUtil.convertValue(convertConfig.getDatasourceContent(), JsonNode.class));
66 if (StringUtils.isNotEmpty(convertConfig.getId())) { 69 if (StringUtils.isNotEmpty(convertConfig.getId())) {
67 // 查询配置是否存在 70 // 查询配置是否存在
68 ConvertConfig checkConfig = 71 ConvertConfig checkConfig =
@@ -101,6 +104,15 @@ public class TkConvertConfigServiceImpl @@ -101,6 +104,15 @@ public class TkConvertConfigServiceImpl
101 } 104 }
102 105
103 @Override 106 @Override
  107 + public ConvertConfigDTO findConvertConfigDTOById(String tenantId, String id) {
  108 + ConvertConfig convertConfig = baseMapper.selectById(id);
  109 + if (null != convertConfig && !Objects.equals(convertConfig.getTenantId(), tenantId)) {
  110 + throw new TkDataValidationException(ErrorMessage.NOT_BELONG_CURRENT_TENANT.getMessage());
  111 + }
  112 + return null !=convertConfig?convertConfig.getDTO(ConvertConfigDTO.class):null;
  113 + }
  114 +
  115 + @Override
104 @Transactional 116 @Transactional
105 public boolean updateConvertStatusByIds(List<String> ids, Integer status, String tenantId) { 117 public boolean updateConvertStatusByIds(List<String> ids, Integer status, String tenantId) {
106 return baseMapper.updateConvertStatusByIds(tenantId, ids, status); 118 return baseMapper.updateConvertStatusByIds(tenantId, ids, status);
@@ -270,7 +282,7 @@ public class TkConvertConfigServiceImpl @@ -270,7 +282,7 @@ public class TkConvertConfigServiceImpl
270 int deleteIndex = 0; 282 int deleteIndex = 0;
271 boolean needDelete = false; 283 boolean needDelete = false;
272 for (RuleNode ruleNode : ruleChainMetaData.getNodes()) { 284 for (RuleNode ruleNode : ruleChainMetaData.getNodes()) {
273 - /**被删除节点右侧节点的下标左偏移1个量*/ 285 + /** 被删除节点右侧节点的下标左偏移1个量 */
274 if (deleteRuleNode.getName().equals(ruleNode.getName()) 286 if (deleteRuleNode.getName().equals(ruleNode.getName())
275 && deleteRuleNode.getType().equals(ruleNode.getType())) { 287 && deleteRuleNode.getType().equals(ruleNode.getType())) {
276 needDelete = true; 288 needDelete = true;
@@ -282,7 +294,7 @@ public class TkConvertConfigServiceImpl @@ -282,7 +294,7 @@ public class TkConvertConfigServiceImpl
282 294
283 if (needDelete) { 295 if (needDelete) {
284 // Delete Rule Node 296 // Delete Rule Node
285 - freshRuleChainMetaData(ruleChainMetaData,deleteIndex); 297 + freshRuleChainMetaData(ruleChainMetaData, deleteIndex);
286 } 298 }
287 }); 299 });
288 300
@@ -306,47 +318,50 @@ public class TkConvertConfigServiceImpl @@ -306,47 +318,50 @@ public class TkConvertConfigServiceImpl
306 } 318 }
307 if (needDelete) { 319 if (needDelete) {
308 // Delete Rule Node 320 // Delete Rule Node
309 - freshRuleChainMetaData(ruleChainMetaData,deleteIndex); 321 + freshRuleChainMetaData(ruleChainMetaData, deleteIndex);
310 } 322 }
311 return needDelete; 323 return needDelete;
312 } 324 }
313 325
314 /** 326 /**
315 * 刷新规则链的元数据 327 * 刷新规则链的元数据
316 - * @param ruleChainMetaData 规则链元数据  
317 - * @param removeNodeIndex 被删除的节点下标 328 + *
  329 + * @param ruleChainMetaData 规则链元数据
  330 + * @param removeNodeIndex 被删除的节点下标
318 */ 331 */
319 - private void freshRuleChainMetaData(RuleChainMetaData ruleChainMetaData,int removeNodeIndex){ 332 + private void freshRuleChainMetaData(RuleChainMetaData ruleChainMetaData, int removeNodeIndex) {
320 ruleChainMetaData.getNodes().remove(removeNodeIndex); 333 ruleChainMetaData.getNodes().remove(removeNodeIndex);
321 334
322 int firestIndex = ruleChainMetaData.getFirstNodeIndex(); 335 int firestIndex = ruleChainMetaData.getFirstNodeIndex();
323 - ruleChainMetaData.setFirstNodeIndex(Math.max(firestIndex< removeNodeIndex?firestIndex:firestIndex-1, 0)); 336 + ruleChainMetaData.setFirstNodeIndex(
  337 + Math.max(firestIndex < removeNodeIndex ? firestIndex : firestIndex - 1, 0));
324 338
325 - ruleChainMetaData.setConnections(freshRelation(ruleChainMetaData.getConnections(),removeNodeIndex)); 339 + ruleChainMetaData.setConnections(
  340 + freshRelation(ruleChainMetaData.getConnections(), removeNodeIndex));
326 } 341 }
327 342
328 /** 343 /**
329 * 刷新规则连中节点间的关联关系 344 * 刷新规则连中节点间的关联关系
330 - * @param connections 节点关联关系  
331 - * @param removeNodeIndex 被删除的节点下标 345 + *
  346 + * @param connections 节点关联关系
  347 + * @param removeNodeIndex 被删除的节点下标
332 * @return 348 * @return
333 */ 349 */
334 - private List<NodeConnectionInfo> freshRelation(List<NodeConnectionInfo> connections,int removeNodeIndex){ 350 + private List<NodeConnectionInfo> freshRelation(
  351 + List<NodeConnectionInfo> connections, int removeNodeIndex) {
335 List<NodeConnectionInfo> newConnections = new ArrayList<>(); 352 List<NodeConnectionInfo> newConnections = new ArrayList<>();
336 353
337 connections.forEach( 354 connections.forEach(
338 - oldRelation -> {  
339 - int fromIndex = oldRelation.getFromIndex();  
340 - int toIndex = oldRelation.getToIndex();  
341 - if (removeNodeIndex != fromIndex  
342 - && removeNodeIndex != toIndex) {  
343 - oldRelation.setFromIndex(  
344 - Math.max(fromIndex > removeNodeIndex ? fromIndex - 1 : fromIndex, 0));  
345 - oldRelation.setToIndex(  
346 - Math.max(toIndex > removeNodeIndex ? toIndex - 1 : toIndex, 0));  
347 - newConnections.add(oldRelation);  
348 - }  
349 - }); 355 + oldRelation -> {
  356 + int fromIndex = oldRelation.getFromIndex();
  357 + int toIndex = oldRelation.getToIndex();
  358 + if (removeNodeIndex != fromIndex && removeNodeIndex != toIndex) {
  359 + oldRelation.setFromIndex(
  360 + Math.max(fromIndex > removeNodeIndex ? fromIndex - 1 : fromIndex, 0));
  361 + oldRelation.setToIndex(Math.max(toIndex > removeNodeIndex ? toIndex - 1 : toIndex, 0));
  362 + newConnections.add(oldRelation);
  363 + }
  364 + });
350 365
351 return newConnections; 366 return newConnections;
352 } 367 }
@@ -362,14 +377,14 @@ public class TkConvertConfigServiceImpl @@ -362,14 +377,14 @@ public class TkConvertConfigServiceImpl
362 } 377 }
363 378
364 int scriptIndex = 0; 379 int scriptIndex = 0;
365 - /**数据流转的脚本转换是否已经存在*/ 380 + /** 数据流转的脚本转换是否已经存在 */
366 boolean hadScript = false; 381 boolean hadScript = false;
367 for (RuleNode ruleNode : ruleChainMetaData.getNodes()) { 382 for (RuleNode ruleNode : ruleChainMetaData.getNodes()) {
368 - /**规则链是否已经包含当前数据转发节点*/ 383 + /** 规则链是否已经包含当前数据转发节点 */
369 if (nodes.stream().anyMatch(n -> n.getName().equals(ruleNode.getName()))) { 384 if (nodes.stream().anyMatch(n -> n.getName().equals(ruleNode.getName()))) {
370 return; 385 return;
371 } 386 }
372 - /**规则链是否已经包含数据转发的前置节点*/ 387 + /** 规则链是否已经包含数据转发的前置节点 */
373 if (ruleNode.getType().equals(scriptType) && convertNodeName.equals(ruleNode.getName())) { 388 if (ruleNode.getType().equals(scriptType) && convertNodeName.equals(ruleNode.getName())) {
374 hadScript = true; 389 hadScript = true;
375 break; 390 break;
@@ -405,7 +420,7 @@ public class TkConvertConfigServiceImpl @@ -405,7 +420,7 @@ public class TkConvertConfigServiceImpl
405 nodeConnectionInfo.setFromIndex(finalScriptIndex); 420 nodeConnectionInfo.setFromIndex(finalScriptIndex);
406 nodeConnectionInfo.setType(connectionType); 421 nodeConnectionInfo.setType(connectionType);
407 nodeConnectionInfo.setToIndex(ruleChainMetaData.getNodes().size()); 422 nodeConnectionInfo.setToIndex(ruleChainMetaData.getNodes().size());
408 - ObjectNode objectNode = setAdditionalInfo(layoutX, layoutY,ruleNode); 423 + ObjectNode objectNode = setAdditionalInfo(layoutX, layoutY, ruleNode);
409 ruleNode.setAdditionalInfo(objectNode); 424 ruleNode.setAdditionalInfo(objectNode);
410 ruleChainMetaData.getConnections().add(nodeConnectionInfo); 425 ruleChainMetaData.getConnections().add(nodeConnectionInfo);
411 ruleChainMetaData.getNodes().add(ruleNode); 426 ruleChainMetaData.getNodes().add(ruleNode);
@@ -436,8 +451,12 @@ public class TkConvertConfigServiceImpl @@ -436,8 +451,12 @@ public class TkConvertConfigServiceImpl
436 } 451 }
437 } 452 }
438 if (findSons == 0) { 453 if (findSons == 0) {
439 - freshRuleChainMetaData(ruleChainMetaData,findOriginatorIndex > findScriptIndex?findOriginatorIndex:findScriptIndex);  
440 - freshRuleChainMetaData(ruleChainMetaData,findOriginatorIndex > findScriptIndex?findScriptIndex:findOriginatorIndex); 454 + freshRuleChainMetaData(
  455 + ruleChainMetaData,
  456 + findOriginatorIndex > findScriptIndex ? findOriginatorIndex : findScriptIndex);
  457 + freshRuleChainMetaData(
  458 + ruleChainMetaData,
  459 + findOriginatorIndex > findScriptIndex ? findScriptIndex : findOriginatorIndex);
441 } 460 }
442 } 461 }
443 462
@@ -491,7 +510,7 @@ public class TkConvertConfigServiceImpl @@ -491,7 +510,7 @@ public class TkConvertConfigServiceImpl
491 ruleNode.setType(type); 510 ruleNode.setType(type);
492 JsonNode jsonNode = JacksonUtil.toJsonNode(types.get(type)); 511 JsonNode jsonNode = JacksonUtil.toJsonNode(types.get(type));
493 ruleNode.setConfiguration(jsonNode); 512 ruleNode.setConfiguration(jsonNode);
494 - ObjectNode objectNode = setAdditionalInfo(layoutX, layoutY,ruleNode); 513 + ObjectNode objectNode = setAdditionalInfo(layoutX, layoutY, ruleNode);
495 ruleNode.setAdditionalInfo(objectNode); 514 ruleNode.setAdditionalInfo(objectNode);
496 ruleChainMetaData.getNodes().add(ruleNode); 515 ruleChainMetaData.getNodes().add(ruleNode);
497 }); 516 });
@@ -505,7 +524,7 @@ public class TkConvertConfigServiceImpl @@ -505,7 +524,7 @@ public class TkConvertConfigServiceImpl
505 RuleNode ruleNode = nodes.get(0); 524 RuleNode ruleNode = nodes.get(0);
506 int layoutX = 202; 525 int layoutX = 202;
507 int layoutY = 53; 526 int layoutY = 53;
508 - ObjectNode objectNode = setAdditionalInfo(layoutX, layoutY,ruleNode); 527 + ObjectNode objectNode = setAdditionalInfo(layoutX, layoutY, ruleNode);
509 ruleNode.setAdditionalInfo(objectNode); 528 ruleNode.setAdditionalInfo(objectNode);
510 ruleChainMetaData.getNodes().add(ruleNode); 529 ruleChainMetaData.getNodes().add(ruleNode);
511 int newFirstNodeIndex = ruleChainMetaData.getNodes().size() - 1; 530 int newFirstNodeIndex = ruleChainMetaData.getNodes().size() - 1;
@@ -539,7 +558,7 @@ public class TkConvertConfigServiceImpl @@ -539,7 +558,7 @@ public class TkConvertConfigServiceImpl
539 AtomicInteger ruleNodeIndex = new AtomicInteger(); 558 AtomicInteger ruleNodeIndex = new AtomicInteger();
540 int layoutX = 1128; 559 int layoutX = 1128;
541 int layoutY = 132; 560 int layoutY = 132;
542 - ObjectNode objectNode = setAdditionalInfo(layoutX, layoutY,ruleNode); 561 + ObjectNode objectNode = setAdditionalInfo(layoutX, layoutY, ruleNode);
543 ruleNode.setAdditionalInfo(objectNode); 562 ruleNode.setAdditionalInfo(objectNode);
544 ruleChainMetaData.getNodes().add(ruleNode); 563 ruleChainMetaData.getNodes().add(ruleNode);
545 ruleChainMetaData 564 ruleChainMetaData
@@ -568,13 +587,20 @@ public class TkConvertConfigServiceImpl @@ -568,13 +587,20 @@ public class TkConvertConfigServiceImpl
568 } 587 }
569 } 588 }
570 589
571 - private ObjectNode setAdditionalInfo(int layoutX, int layoutY,RuleNode ruleNode) { 590 + private ObjectNode setAdditionalInfo(int layoutX, int layoutY, RuleNode ruleNode) {
572 int randomNum = new Random().nextInt(50); 591 int randomNum = new Random().nextInt(50);
573 ObjectNode objectNode = JacksonUtil.newObjectNode(); 592 ObjectNode objectNode = JacksonUtil.newObjectNode();
574 593
575 - String desc="";  
576 - if(ruleNode.getAdditionalInfo() != null && ruleNode.getAdditionalInfo().has(ModelConstants.TablePropertyMapping.ADDITIONALINFO_DESCRIPTION)){  
577 - desc = ruleNode.getAdditionalInfo().get(ModelConstants.TablePropertyMapping.ADDITIONALINFO_DESCRIPTION).asText(""); 594 + String desc = "";
  595 + if (ruleNode.getAdditionalInfo() != null
  596 + && ruleNode
  597 + .getAdditionalInfo()
  598 + .has(ModelConstants.TablePropertyMapping.ADDITIONALINFO_DESCRIPTION)) {
  599 + desc =
  600 + ruleNode
  601 + .getAdditionalInfo()
  602 + .get(ModelConstants.TablePropertyMapping.ADDITIONALINFO_DESCRIPTION)
  603 + .asText("");
578 } 604 }
579 objectNode.put(ModelConstants.TablePropertyMapping.ADDITIONALINFO_DESCRIPTION, desc); 605 objectNode.put(ModelConstants.TablePropertyMapping.ADDITIONALINFO_DESCRIPTION, desc);
580 objectNode.put("layoutX", layoutX + randomNum); 606 objectNode.put("layoutX", layoutX + randomNum);
@@ -21,16 +21,17 @@ import org.thingsboard.server.common.data.yunteng.constant.ModelConstants; @@ -21,16 +21,17 @@ import org.thingsboard.server.common.data.yunteng.constant.ModelConstants;
21 import org.thingsboard.server.common.data.yunteng.core.exception.TkDataValidationException; 21 import org.thingsboard.server.common.data.yunteng.core.exception.TkDataValidationException;
22 import org.thingsboard.server.common.data.yunteng.core.message.ErrorMessage; 22 import org.thingsboard.server.common.data.yunteng.core.message.ErrorMessage;
23 import org.thingsboard.server.common.data.yunteng.dto.*; 23 import org.thingsboard.server.common.data.yunteng.dto.*;
24 -import org.thingsboard.server.common.data.yunteng.enums.DataTypeEnum;  
25 -import org.thingsboard.server.common.data.yunteng.enums.DeviceTypeEnum;  
26 -import org.thingsboard.server.common.data.yunteng.enums.FunctionTypeEnum;  
27 -import org.thingsboard.server.common.data.yunteng.enums.ScopeEnum; 24 +import org.thingsboard.server.common.data.yunteng.dto.convert.ConvertConfigDTO;
  25 +import org.thingsboard.server.common.data.yunteng.dto.convert.ConvertDevicesDTO;
  26 +import org.thingsboard.server.common.data.yunteng.dto.convert.DatasourceContentDTO;
  27 +import org.thingsboard.server.common.data.yunteng.enums.*;
28 import org.thingsboard.server.common.data.yunteng.utils.ReflectUtils; 28 import org.thingsboard.server.common.data.yunteng.utils.ReflectUtils;
29 import org.thingsboard.server.common.data.yunteng.utils.tools.TkPageData; 29 import org.thingsboard.server.common.data.yunteng.utils.tools.TkPageData;
30 import org.thingsboard.server.dao.device.DeviceProfileDao; 30 import org.thingsboard.server.dao.device.DeviceProfileDao;
31 import org.thingsboard.server.dao.yunteng.entities.*; 31 import org.thingsboard.server.dao.yunteng.entities.*;
32 import org.thingsboard.server.dao.yunteng.mapper.*; 32 import org.thingsboard.server.dao.yunteng.mapper.*;
33 import org.thingsboard.server.dao.yunteng.service.AbstractBaseService; 33 import org.thingsboard.server.dao.yunteng.service.AbstractBaseService;
  34 +import org.thingsboard.server.dao.yunteng.service.ConvertConfigService;
34 import org.thingsboard.server.dao.yunteng.service.ThingsModelService; 35 import org.thingsboard.server.dao.yunteng.service.ThingsModelService;
35 import org.thingsboard.server.dao.yunteng.service.TkDeviceService; 36 import org.thingsboard.server.dao.yunteng.service.TkDeviceService;
36 37
@@ -53,6 +54,7 @@ public class TkDeviceServiceImpl extends AbstractBaseService<DeviceMapper, TkDev @@ -53,6 +54,7 @@ public class TkDeviceServiceImpl extends AbstractBaseService<DeviceMapper, TkDev
53 private final DoConditionMapper conditionMapper; 54 private final DoConditionMapper conditionMapper;
54 private final DoActionMapper actionMapper; 55 private final DoActionMapper actionMapper;
55 private final ThingsModelService thingsModelService; 56 private final ThingsModelService thingsModelService;
  57 + private final ConvertConfigService convertConfigService;
56 58
57 @Override 59 @Override
58 @Transactional 60 @Transactional
@@ -357,10 +359,27 @@ public class TkDeviceServiceImpl extends AbstractBaseService<DeviceMapper, TkDev @@ -357,10 +359,27 @@ public class TkDeviceServiceImpl extends AbstractBaseService<DeviceMapper, TkDev
357 public TkPageData<DeviceDTO> page(String tenantId, Map<String, Object> queryMap) { 359 public TkPageData<DeviceDTO> page(String tenantId, Map<String, Object> queryMap) {
358 queryMap.put("tenantId", tenantId); 360 queryMap.put("tenantId", tenantId);
359 String organizationId = (String) queryMap.get("organizationId"); 361 String organizationId = (String) queryMap.get("organizationId");
  362 + String convertConfigId =
  363 + Optional.ofNullable(queryMap.get("convertConfigId")).map(Object::toString).orElse(null);
360 if (!StringUtils.isEmpty(organizationId)) { 364 if (!StringUtils.isEmpty(organizationId)) {
361 List<String> queryOrganizationIds = organizationAllIds(tenantId, organizationId); 365 List<String> queryOrganizationIds = organizationAllIds(tenantId, organizationId);
362 queryMap.put("organizationIds", queryOrganizationIds); 366 queryMap.put("organizationIds", queryOrganizationIds);
363 } 367 }
  368 + if (StringUtils.isNotEmpty(convertConfigId)) {
  369 + ConvertConfigDTO configDTO =
  370 + convertConfigService.findConvertConfigDTOById(tenantId, convertConfigId);
  371 + if (null != configDTO && configDTO.getDatasourceType().equals(DatasourceTypeEnum.DEVICES)) {
  372 + DatasourceContentDTO datasourceContentDTO =
  373 + JacksonUtil.convertValue(configDTO.getDatasourceContent(), DatasourceContentDTO.class);
  374 + if (datasourceContentDTO != null) {
  375 + List<String> deviceIds = new ArrayList<>();
  376 + for (ConvertDevicesDTO convertDevicesDTO : datasourceContentDTO.getConvertDevices()) {
  377 + deviceIds.addAll(convertDevicesDTO.getDevices());
  378 + }
  379 + queryMap.put("convertDevices", deviceIds);
  380 + }
  381 + }
  382 + }
364 IPage<TkDeviceEntity> page = 383 IPage<TkDeviceEntity> page =
365 getPage(queryMap, FastIotConstants.DefaultOrder.CREATE_TIME, false); 384 getPage(queryMap, FastIotConstants.DefaultOrder.CREATE_TIME, false);
366 IPage<DeviceDTO> deviceIPage = baseMapper.getDevicePage(page, queryMap); 385 IPage<DeviceDTO> deviceIPage = baseMapper.getDevicePage(page, queryMap);
@@ -636,7 +655,7 @@ public class TkDeviceServiceImpl extends AbstractBaseService<DeviceMapper, TkDev @@ -636,7 +655,7 @@ public class TkDeviceServiceImpl extends AbstractBaseService<DeviceMapper, TkDev
636 655
637 @Override 656 @Override
638 public DeviceDTO findDeviceInfoByTbDeviceId(String tenantId, String tbDeviceId) { 657 public DeviceDTO findDeviceInfoByTbDeviceId(String tenantId, String tbDeviceId) {
639 - if(StringUtils.isEmpty(tenantId) || StringUtils.isEmpty(tbDeviceId)){ 658 + if (StringUtils.isEmpty(tenantId) || StringUtils.isEmpty(tbDeviceId)) {
640 throw new TkDataValidationException(ErrorMessage.INVALID_PARAMETER.getMessage()); 659 throw new TkDataValidationException(ErrorMessage.INVALID_PARAMETER.getMessage());
641 } 660 }
642 return baseMapper.findDeviceInfo(tenantId, tbDeviceId); 661 return baseMapper.findDeviceInfo(tenantId, tbDeviceId);
@@ -2,7 +2,7 @@ package org.thingsboard.server.dao.yunteng.service; @@ -2,7 +2,7 @@ package org.thingsboard.server.dao.yunteng.service;
2 2
3 import org.thingsboard.server.common.data.rule.RuleChainMetaData; 3 import org.thingsboard.server.common.data.rule.RuleChainMetaData;
4 import org.thingsboard.server.common.data.rule.RuleNode; 4 import org.thingsboard.server.common.data.rule.RuleNode;
5 -import org.thingsboard.server.common.data.yunteng.dto.ConvertConfigDTO; 5 +import org.thingsboard.server.common.data.yunteng.dto.convert.ConvertConfigDTO;
6 import org.thingsboard.server.common.data.yunteng.dto.DeleteDTO; 6 import org.thingsboard.server.common.data.yunteng.dto.DeleteDTO;
7 import org.thingsboard.server.common.data.yunteng.utils.tools.TkPageData; 7 import org.thingsboard.server.common.data.yunteng.utils.tools.TkPageData;
8 import org.thingsboard.server.dao.yunteng.ConvertConfig; 8 import org.thingsboard.server.dao.yunteng.ConvertConfig;
@@ -12,11 +12,14 @@ import java.util.Map; @@ -12,11 +12,14 @@ import java.util.Map;
12 12
13 public interface ConvertConfigService extends BaseService<ConvertConfig> { 13 public interface ConvertConfigService extends BaseService<ConvertConfig> {
14 TkPageData<ConvertConfigDTO> page(String tenantId, Map<String, Object> queryMap); 14 TkPageData<ConvertConfigDTO> page(String tenantId, Map<String, Object> queryMap);
  15 +
15 ConvertConfigDTO createOrUpdate(ConvertConfigDTO convertConfig); 16 ConvertConfigDTO createOrUpdate(ConvertConfigDTO convertConfig);
16 17
17 - boolean updateConvertStatusByIds(List<String> ids,Integer status, String tenantId); 18 + ConvertConfigDTO findConvertConfigDTOById(String tenantId, String id);
  19 +
  20 + boolean updateConvertStatusByIds(List<String> ids, Integer status, String tenantId);
18 21
19 - boolean deleteConvertConfig(DeleteDTO deleteDTO,Integer nodeType); 22 + boolean deleteConvertConfig(DeleteDTO deleteDTO, Integer nodeType);
20 23
21 /** 24 /**
22 * 通过数据转换的IDS获取需要组装的节点 25 * 通过数据转换的IDS获取需要组装的节点
@@ -26,7 +29,7 @@ public interface ConvertConfigService extends BaseService<ConvertConfig> { @@ -26,7 +29,7 @@ public interface ConvertConfigService extends BaseService<ConvertConfig> {
26 * @param nodeType 0转换脚本 1数据流转 29 * @param nodeType 0转换脚本 1数据流转
27 * @return 规则节点列表 30 * @return 规则节点列表
28 */ 31 */
29 - List<RuleNode> getRuleNodesByConvertConfigIds(List<String> ids,Integer status,Integer nodeType); 32 + List<RuleNode> getRuleNodesByConvertConfigIds(List<String> ids, Integer status, Integer nodeType);
30 33
31 /** 34 /**
32 * 检查数据转换配置名称是否可用 35 * 检查数据转换配置名称是否可用
@@ -37,7 +40,7 @@ public interface ConvertConfigService extends BaseService<ConvertConfig> { @@ -37,7 +40,7 @@ public interface ConvertConfigService extends BaseService<ConvertConfig> {
37 * @param tenantId 租户ID 40 * @param tenantId 租户ID
38 * @return true 存在 false 不存在 41 * @return true 存在 false 不存在
39 */ 42 */
40 - boolean checkConvertConfigNameExist(String excludeId,String name,String type, String tenantId); 43 + boolean checkConvertConfigNameExist(String excludeId, String name, String type, String tenantId);
41 44
42 /** 45 /**
43 * 检查数据装换配置状态是否已经存在 46 * 检查数据装换配置状态是否已经存在
@@ -51,13 +54,14 @@ public interface ConvertConfigService extends BaseService<ConvertConfig> { @@ -51,13 +54,14 @@ public interface ConvertConfigService extends BaseService<ConvertConfig> {
51 54
52 /** 55 /**
53 * 检查该租户下是否已启用转换脚本状态 56 * 检查该租户下是否已启用转换脚本状态
  57 + *
54 * @param tenantId 租户ID 58 * @param tenantId 租户ID
55 * @return true已启用 false未启用 59 * @return true已启用 false未启用
56 */ 60 */
57 boolean checkConvertJSStatusEnable(String tenantId); 61 boolean checkConvertJSStatusEnable(String tenantId);
58 62
59 - boolean deleteRuleNode(List<RuleNode> nodes, RuleChainMetaData ruleChainMetaData, Integer nodeType); 63 + boolean deleteRuleNode(
  64 + List<RuleNode> nodes, RuleChainMetaData ruleChainMetaData, Integer nodeType);
60 65
61 void addRuleNode(List<RuleNode> nodes, RuleChainMetaData ruleChainMetaData, Integer nodeType); 66 void addRuleNode(List<RuleNode> nodes, RuleChainMetaData ruleChainMetaData, Integer nodeType);
62 -  
63 } 67 }
@@ -2,7 +2,7 @@ @@ -2,7 +2,7 @@
2 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> 2 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
3 3
4 <mapper namespace="org.thingsboard.server.dao.yunteng.mapper.ConvertConfigMapper"> 4 <mapper namespace="org.thingsboard.server.dao.yunteng.mapper.ConvertConfigMapper">
5 - <resultMap type="org.thingsboard.server.common.data.yunteng.dto.ConvertConfigDTO" id="convertMap"> 5 + <resultMap type="org.thingsboard.server.common.data.yunteng.dto.convert.ConvertConfigDTO" id="convertMap">
6 <result property="id" column="id"/> 6 <result property="id" column="id"/>
7 <result property="name" column="name"/> 7 <result property="name" column="name"/>
8 <result property="type" column="type"/> 8 <result property="type" column="type"/>
@@ -97,8 +97,17 @@ @@ -97,8 +97,17 @@
97 <if test="queryMap.tenantId !=null and queryMap.tenantId !=''"> 97 <if test="queryMap.tenantId !=null and queryMap.tenantId !=''">
98 AND ifd.tenant_id = #{queryMap.tenantId} 98 AND ifd.tenant_id = #{queryMap.tenantId}
99 </if> 99 </if>
100 - <if test="queryMap.deviceProfileId !=null and queryMap.deviceProfileId !=''">  
101 - AND ifd.device_profile_id = #{queryMap.deviceProfileId} 100 + <if test="queryMap.convertDevices !=null">
  101 + AND ifd.id IN
  102 + <foreach collection="queryMap.convertDevices" item="convertDevice" open="(" separator="," close=")">
  103 + #{convertDevice}
  104 + </foreach>
  105 + </if>
  106 + <if test="queryMap.deviceProfileIds !=null">
  107 + AND ifd.profile_id IN
  108 + <foreach collection="queryMap.deviceProfileIds" item="deviceProfileId" open="(" separator="," close=")">
  109 + #{deviceProfileId}
  110 + </foreach>
102 </if> 111 </if>
103 <if test="queryMap.name !=null and queryMap.name !=''"> 112 <if test="queryMap.name !=null and queryMap.name !=''">
104 AND ( 113 AND (