Commit d9eb373a57efd89438a89c7a2ccdb984264099ba
1 parent
da3f63d8
feat: 【ThingsKit】add device state logs
Showing
14 changed files
with
448 additions
and
77 deletions
application/src/main/java/org/thingsboard/server/controller/yunteng/TkDeviceStateLogController.java
0 → 100644
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.springframework.http.ResponseEntity; | ||
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.DeleteGroup; | ||
13 | +import org.thingsboard.server.common.data.yunteng.core.exception.TkDataValidationException; | ||
14 | +import org.thingsboard.server.common.data.yunteng.core.message.ErrorMessage; | ||
15 | +import org.thingsboard.server.common.data.yunteng.dto.DeleteDTO; | ||
16 | +import org.thingsboard.server.common.data.yunteng.dto.TkDeviceStateLogDTO; | ||
17 | +import org.thingsboard.server.common.data.yunteng.enums.OrderTypeEnum; | ||
18 | +import org.thingsboard.server.common.data.yunteng.utils.tools.TkPageData; | ||
19 | +import org.thingsboard.server.controller.BaseController; | ||
20 | +import org.thingsboard.server.dao.yunteng.service.TkDeviceStateLogService; | ||
21 | + | ||
22 | +import java.sql.Timestamp; | ||
23 | +import java.util.HashMap; | ||
24 | +import java.util.Map; | ||
25 | + | ||
26 | +import static org.thingsboard.server.common.data.yunteng.constant.QueryConstant.*; | ||
27 | +import static org.thingsboard.server.common.data.yunteng.constant.QueryConstant.ORDER_TYPE; | ||
28 | + | ||
29 | +@RestController | ||
30 | +@RequiredArgsConstructor | ||
31 | +@RequestMapping("api/yt/device/state/log") | ||
32 | +@Api(tags = {"设备上下线记录"}) | ||
33 | +public class TkDeviceStateLogController extends BaseController { | ||
34 | + private final TkDeviceStateLogService tkDeviceStateLogService; | ||
35 | + | ||
36 | + @PreAuthorize("@check.checkPermissions({'TENANT_ADMIN','CUSTOMER_USER'},{'api:yt:device:state:log:view'})") | ||
37 | + @GetMapping(params = {PAGE_SIZE, PAGE}) | ||
38 | + @ApiOperation("查询") | ||
39 | + public TkPageData<TkDeviceStateLogDTO> page( | ||
40 | + @RequestParam(PAGE_SIZE) int pageSize, | ||
41 | + @RequestParam(PAGE) int page, | ||
42 | + @RequestParam(value = "deviceName", required = false) String deviceName, | ||
43 | + @RequestParam(value = "organizationName", required = false) String organizationName, | ||
44 | + @RequestParam(value = "deviceProfileName", required = false) String deviceProfileName, | ||
45 | + @RequestParam(value = "status", required = false) Integer status, | ||
46 | + @RequestParam(value = "startTime", required = false) Long startTime, | ||
47 | + @RequestParam(value = "endTime", required = false) Long endTime, | ||
48 | + @RequestParam(value = ORDER_FILED, required = false) String orderBy, | ||
49 | + @RequestParam(value = ORDER_TYPE, required = false) OrderTypeEnum orderType) | ||
50 | + throws ThingsboardException { | ||
51 | + Map<String, Object> queryMap = new HashMap<>(); | ||
52 | + queryMap.put("deviceName", deviceName); | ||
53 | + queryMap.put("organizationName", organizationName); | ||
54 | + queryMap.put("deviceProfileName", deviceProfileName); | ||
55 | + queryMap.put("status", status); | ||
56 | + if (null != startTime && null != endTime) { | ||
57 | + if (startTime > endTime) { | ||
58 | + throw new TkDataValidationException( | ||
59 | + ErrorMessage.START_TIME_NOT_MORE_THAN_END_TIME.getMessage()); | ||
60 | + } | ||
61 | + queryMap.put("startTime", new Timestamp(startTime).toLocalDateTime()); | ||
62 | + queryMap.put("endTime", new Timestamp(endTime).toLocalDateTime()); | ||
63 | + } | ||
64 | + queryMap.put(PAGE_SIZE, pageSize); | ||
65 | + queryMap.put(PAGE, page); | ||
66 | + queryMap.put(ORDER_FILED, orderBy); | ||
67 | + queryMap.put(ORDER_TYPE, orderType); | ||
68 | + queryMap.put(TENANT_ID, getCurrentUser().getCurrentTenantId()); | ||
69 | + return tkDeviceStateLogService.page(getCurrentUser().getCurrentTenantId(), queryMap); | ||
70 | + } | ||
71 | + | ||
72 | + @DeleteMapping | ||
73 | + @PreAuthorize("@check.checkPermissions({'TENANT_ADMIN','CUSTOMER_USER'},{'api:yt:device:state:log::delete'})") | ||
74 | + public ResponseEntity<Boolean> deleteDeviceStateLog( | ||
75 | + @Validated({DeleteGroup.class}) @RequestBody DeleteDTO deleteDTO) | ||
76 | + throws ThingsboardException { | ||
77 | + deleteDTO.setTenantId(getCurrentUser().getCurrentTenantId()); | ||
78 | + return ResponseEntity.ok(tkDeviceStateLogService.deleteTkDeviceStateLog(deleteDTO)); | ||
79 | + } | ||
80 | + | ||
81 | + @PostMapping | ||
82 | + @PreAuthorize("@check.checkPermissions({'TENANT_ADMIN','CUSTOMER_USER'},{'api:yt:device:state:log::post'})") | ||
83 | + public ResponseEntity<TkDeviceStateLogDTO> updateDeviceStateLogInfo( | ||
84 | + @RequestBody TkDeviceStateLogDTO tkDeviceStateLogDTO) throws ThingsboardException { | ||
85 | + if(StringUtils.isEmpty(tkDeviceStateLogDTO.getId())){ | ||
86 | + throw new TkDataValidationException(ErrorMessage.INVALID_PARAMETER.getMessage()); | ||
87 | + } | ||
88 | + tkDeviceStateLogDTO.setTenantId(getCurrentUser().getCurrentTenantId()); | ||
89 | + return ResponseEntity.ok( | ||
90 | + tkDeviceStateLogService.saveOrUpdateTkDeviceStateLogInfo(tkDeviceStateLogDTO)); | ||
91 | + } | ||
92 | + | ||
93 | + @GetMapping("{id}") | ||
94 | + @PreAuthorize("@check.checkPermissions({'TENANT_ADMIN','CUSTOMER_USER'},{'api:yt:device:state:log::detail'})") | ||
95 | + public ResponseEntity<TkDeviceStateLogDTO> getDeviceStateLogInfo(@PathVariable("id") String id) | ||
96 | + throws ThingsboardException { | ||
97 | + return ResponseEntity.ok( | ||
98 | + tkDeviceStateLogService.findTkDeviceStateLogInfoById( | ||
99 | + getCurrentUser().getCurrentTenantId(), id)); | ||
100 | + } | ||
101 | +} |
@@ -39,6 +39,9 @@ import org.thingsboard.server.common.data.kv.*; | @@ -39,6 +39,9 @@ import org.thingsboard.server.common.data.kv.*; | ||
39 | import org.thingsboard.server.common.data.page.PageData; | 39 | import org.thingsboard.server.common.data.page.PageData; |
40 | import org.thingsboard.server.common.data.page.PageDataIterable; | 40 | import org.thingsboard.server.common.data.page.PageDataIterable; |
41 | import org.thingsboard.server.common.data.page.PageLink; | 41 | import org.thingsboard.server.common.data.page.PageLink; |
42 | +import org.thingsboard.server.common.data.yunteng.constant.FastIotConstants; | ||
43 | +import org.thingsboard.server.common.data.yunteng.dto.DeviceDTO; | ||
44 | +import org.thingsboard.server.common.data.yunteng.dto.TkDeviceStateLogDTO; | ||
42 | import org.thingsboard.server.common.msg.TbMsg; | 45 | import org.thingsboard.server.common.msg.TbMsg; |
43 | import org.thingsboard.server.common.msg.TbMsgDataType; | 46 | import org.thingsboard.server.common.msg.TbMsgDataType; |
44 | import org.thingsboard.server.common.msg.TbMsgMetaData; | 47 | import org.thingsboard.server.common.msg.TbMsgMetaData; |
@@ -49,6 +52,8 @@ import org.thingsboard.server.dao.attributes.AttributesService; | @@ -49,6 +52,8 @@ import org.thingsboard.server.dao.attributes.AttributesService; | ||
49 | import org.thingsboard.server.dao.device.DeviceService; | 52 | import org.thingsboard.server.dao.device.DeviceService; |
50 | import org.thingsboard.server.dao.tenant.TenantService; | 53 | import org.thingsboard.server.dao.tenant.TenantService; |
51 | import org.thingsboard.server.dao.timeseries.TimeseriesService; | 54 | import org.thingsboard.server.dao.timeseries.TimeseriesService; |
55 | +import org.thingsboard.server.dao.yunteng.service.TkDeviceService; | ||
56 | +import org.thingsboard.server.dao.yunteng.service.TkDeviceStateLogService; | ||
52 | import org.thingsboard.server.gen.transport.TransportProtos; | 57 | import org.thingsboard.server.gen.transport.TransportProtos; |
53 | import org.thingsboard.server.queue.discovery.PartitionService; | 58 | import org.thingsboard.server.queue.discovery.PartitionService; |
54 | import org.thingsboard.server.service.partition.AbstractPartitionBasedService; | 59 | import org.thingsboard.server.service.partition.AbstractPartitionBasedService; |
@@ -58,6 +63,7 @@ import javax.annotation.Nonnull; | @@ -58,6 +63,7 @@ import javax.annotation.Nonnull; | ||
58 | import javax.annotation.Nullable; | 63 | import javax.annotation.Nullable; |
59 | import javax.annotation.PostConstruct; | 64 | import javax.annotation.PostConstruct; |
60 | import javax.annotation.PreDestroy; | 65 | import javax.annotation.PreDestroy; |
66 | +import java.time.LocalDateTime; | ||
61 | import java.util.*; | 67 | import java.util.*; |
62 | import java.util.concurrent.*; | 68 | import java.util.concurrent.*; |
63 | 69 | ||
@@ -87,6 +93,8 @@ public class DefaultDeviceStateService extends AbstractPartitionBasedService<Dev | @@ -87,6 +93,8 @@ public class DefaultDeviceStateService extends AbstractPartitionBasedService<Dev | ||
87 | private final TimeseriesService tsService; | 93 | private final TimeseriesService tsService; |
88 | private final TbClusterService clusterService; | 94 | private final TbClusterService clusterService; |
89 | private final PartitionService partitionService; | 95 | private final PartitionService partitionService; |
96 | + private final TkDeviceService tkDeviceService; | ||
97 | + private final TkDeviceStateLogService tkDeviceStateLogService; | ||
90 | 98 | ||
91 | private TelemetrySubscriptionService tsSubService; | 99 | private TelemetrySubscriptionService tsSubService; |
92 | 100 | ||
@@ -112,13 +120,16 @@ public class DefaultDeviceStateService extends AbstractPartitionBasedService<Dev | @@ -112,13 +120,16 @@ public class DefaultDeviceStateService extends AbstractPartitionBasedService<Dev | ||
112 | 120 | ||
113 | public DefaultDeviceStateService(TenantService tenantService, DeviceService deviceService, | 121 | public DefaultDeviceStateService(TenantService tenantService, DeviceService deviceService, |
114 | AttributesService attributesService, TimeseriesService tsService, | 122 | AttributesService attributesService, TimeseriesService tsService, |
115 | - TbClusterService clusterService, PartitionService partitionService) { | 123 | + TbClusterService clusterService, PartitionService partitionService, |
124 | + TkDeviceService tkDeviceService,TkDeviceStateLogService tkDeviceStateLogService) { | ||
116 | this.tenantService = tenantService; | 125 | this.tenantService = tenantService; |
117 | this.deviceService = deviceService; | 126 | this.deviceService = deviceService; |
118 | this.attributesService = attributesService; | 127 | this.attributesService = attributesService; |
119 | this.tsService = tsService; | 128 | this.tsService = tsService; |
120 | this.clusterService = clusterService; | 129 | this.clusterService = clusterService; |
121 | this.partitionService = partitionService; | 130 | this.partitionService = partitionService; |
131 | + this.tkDeviceService = tkDeviceService; | ||
132 | + this.tkDeviceStateLogService = tkDeviceStateLogService; | ||
122 | } | 133 | } |
123 | 134 | ||
124 | @Autowired | 135 | @Autowired |
@@ -165,6 +176,8 @@ public class DefaultDeviceStateService extends AbstractPartitionBasedService<Dev | @@ -165,6 +176,8 @@ public class DefaultDeviceStateService extends AbstractPartitionBasedService<Dev | ||
165 | save(deviceId, LAST_CONNECT_TIME, ts); | 176 | save(deviceId, LAST_CONNECT_TIME, ts); |
166 | pushRuleEngineMessage(stateData, CONNECT_EVENT); | 177 | pushRuleEngineMessage(stateData, CONNECT_EVENT); |
167 | checkAndUpdateState(deviceId, stateData); | 178 | checkAndUpdateState(deviceId, stateData); |
179 | + //ThingsKit | ||
180 | + saveDeviceStateLog(tenantId.toString(),deviceId.toString(), FastIotConstants.StateValue.ONLINE); | ||
168 | 181 | ||
169 | } | 182 | } |
170 | 183 | ||
@@ -207,6 +220,8 @@ public class DefaultDeviceStateService extends AbstractPartitionBasedService<Dev | @@ -207,6 +220,8 @@ public class DefaultDeviceStateService extends AbstractPartitionBasedService<Dev | ||
207 | stateData.getState().setLastDisconnectTime(ts); | 220 | stateData.getState().setLastDisconnectTime(ts); |
208 | save(deviceId, LAST_DISCONNECT_TIME, ts); | 221 | save(deviceId, LAST_DISCONNECT_TIME, ts); |
209 | pushRuleEngineMessage(stateData, DISCONNECT_EVENT); | 222 | pushRuleEngineMessage(stateData, DISCONNECT_EVENT); |
223 | + //ThingsKit | ||
224 | + saveDeviceStateLog(tenantId.toString(),deviceId.toString(), FastIotConstants.StateValue.OFFLINE); | ||
210 | } | 225 | } |
211 | 226 | ||
212 | @Override | 227 | @Override |
@@ -343,7 +358,26 @@ public class DefaultDeviceStateService extends AbstractPartitionBasedService<Dev | @@ -343,7 +358,26 @@ public class DefaultDeviceStateService extends AbstractPartitionBasedService<Dev | ||
343 | } | 358 | } |
344 | } | 359 | } |
345 | } | 360 | } |
346 | - | 361 | + //ThingsKit |
362 | + private void saveDeviceStateLog(String tenantId,String tbDeviceId,Integer status){ | ||
363 | + try{ | ||
364 | + DeviceDTO deviceDTO = tkDeviceService.findDeviceInfoByTbDeviceId(tenantId,tbDeviceId); | ||
365 | + if(null != deviceDTO){ | ||
366 | + TkDeviceStateLogDTO tkDeviceStateLogDTO = new TkDeviceStateLogDTO(); | ||
367 | + tkDeviceStateLogDTO.setTenantId(tenantId); | ||
368 | + tkDeviceStateLogDTO.setTbDeviceId(tbDeviceId); | ||
369 | + tkDeviceStateLogDTO.setStatus(status); | ||
370 | + tkDeviceStateLogDTO.setDeviceName(deviceDTO.getName()); | ||
371 | + tkDeviceStateLogDTO.setDeviceType(deviceDTO.getDeviceType()); | ||
372 | + tkDeviceStateLogDTO.setDeviceProfileName(deviceDTO.getDeviceProfile().getName()); | ||
373 | + tkDeviceStateLogDTO.setOrganizationName(deviceDTO.getOrganizationDTO().getName()); | ||
374 | + tkDeviceStateLogDTO.setCreateTime(LocalDateTime.now()); | ||
375 | + tkDeviceStateLogService.saveOrUpdateTkDeviceStateLogInfo(tkDeviceStateLogDTO); | ||
376 | + } | ||
377 | + }catch (Exception e){ | ||
378 | + e.printStackTrace(); | ||
379 | + } | ||
380 | + } | ||
347 | private void addDeviceUsingState(TopicPartitionInfo tpi, DeviceStateData state) { | 381 | private void addDeviceUsingState(TopicPartitionInfo tpi, DeviceStateData state) { |
348 | Set<DeviceId> deviceIds = partitionedEntities.get(tpi); | 382 | Set<DeviceId> deviceIds = partitionedEntities.get(tpi); |
349 | if (deviceIds != null) { | 383 | if (deviceIds != null) { |
@@ -26,6 +26,8 @@ import org.thingsboard.server.dao.attributes.AttributesService; | @@ -26,6 +26,8 @@ import org.thingsboard.server.dao.attributes.AttributesService; | ||
26 | import org.thingsboard.server.dao.device.DeviceService; | 26 | import org.thingsboard.server.dao.device.DeviceService; |
27 | import org.thingsboard.server.dao.tenant.TenantService; | 27 | import org.thingsboard.server.dao.tenant.TenantService; |
28 | import org.thingsboard.server.dao.timeseries.TimeseriesService; | 28 | import org.thingsboard.server.dao.timeseries.TimeseriesService; |
29 | +import org.thingsboard.server.dao.yunteng.service.TkDeviceService; | ||
30 | +import org.thingsboard.server.dao.yunteng.service.TkDeviceStateLogService; | ||
29 | import org.thingsboard.server.queue.discovery.PartitionService; | 31 | import org.thingsboard.server.queue.discovery.PartitionService; |
30 | import org.thingsboard.server.cluster.TbClusterService; | 32 | import org.thingsboard.server.cluster.TbClusterService; |
31 | 33 | ||
@@ -53,6 +55,10 @@ public class DefaultDeviceStateServiceTest { | @@ -53,6 +55,10 @@ public class DefaultDeviceStateServiceTest { | ||
53 | PartitionService partitionService; | 55 | PartitionService partitionService; |
54 | @Mock | 56 | @Mock |
55 | DeviceStateData deviceStateDataMock; | 57 | DeviceStateData deviceStateDataMock; |
58 | + @Mock | ||
59 | + TkDeviceService tkDeviceService; | ||
60 | + @Mock | ||
61 | + TkDeviceStateLogService tkDeviceStateLogService; | ||
56 | 62 | ||
57 | DeviceId deviceId = DeviceId.fromString("00797a3b-7aeb-4b5b-b57a-c2a810d0f112"); | 63 | DeviceId deviceId = DeviceId.fromString("00797a3b-7aeb-4b5b-b57a-c2a810d0f112"); |
58 | 64 | ||
@@ -60,7 +66,7 @@ public class DefaultDeviceStateServiceTest { | @@ -60,7 +66,7 @@ public class DefaultDeviceStateServiceTest { | ||
60 | 66 | ||
61 | @Before | 67 | @Before |
62 | public void setUp() { | 68 | public void setUp() { |
63 | - service = spy(new DefaultDeviceStateService(tenantService, deviceService, attributesService, tsService, clusterService, partitionService)); | 69 | + service = spy(new DefaultDeviceStateService(tenantService, deviceService, attributesService, tsService, clusterService, partitionService,tkDeviceService,tkDeviceStateLogService)); |
64 | } | 70 | } |
65 | 71 | ||
66 | @Test | 72 | @Test |
@@ -13,9 +13,54 @@ public interface FastIotConstants { | @@ -13,9 +13,54 @@ public interface FastIotConstants { | ||
13 | String CHART_EXECUTE_ATTRIBUTES = "executeAttributes"; | 13 | String CHART_EXECUTE_ATTRIBUTES = "executeAttributes"; |
14 | String ASSERT_DEFAULT_NAME = "default"; | 14 | String ASSERT_DEFAULT_NAME = "default"; |
15 | public static final String TCP_DEVICE_IDENTIFY_FILED = "deviceCode"; | 15 | public static final String TCP_DEVICE_IDENTIFY_FILED = "deviceCode"; |
16 | + String MOBILE = | ||
17 | + "^[1](([3][0-9])|([4][0,1,4-9])|([5][0-3,5-9])|([6][2,5,6,7])|([7][0-8])|([8][0-9])|([9][0-3,5-9]))[0-9]{8}$"; | ||
18 | + String EMAIL = "^[A-Z0-9._%+-]+@[A-Z0-9.-]+\\.[A-Z]{2,}$"; | ||
19 | + Pattern EMAIL_PATTERN = Pattern.compile(EMAIL, Pattern.CASE_INSENSITIVE); | ||
20 | + Pattern CHINA_MOBILE_PATTERN = Pattern.compile(MOBILE); | ||
21 | + String DEFAULT_DELIMITER = "#"; | ||
22 | + interface CacheConfigKey { | ||
23 | + String CACHE_CONFIG_KEY = "yunTengIotCache"; | ||
24 | + String USER_PERMISSION_PREFIX = "userPermissionFor_"; | ||
25 | + String MOBILE_LOGIN_SMS_CODE = "mobileLoginSmsCode"; | ||
26 | + } | ||
27 | + interface TBCacheConfig { | ||
28 | + String TB_CACHE_CONFIG_KEY = "TB_CONNECT_CACHE"; | ||
29 | + String EXISTING_TENANT = "EXISTING_TENANT"; | ||
30 | + } | ||
31 | + | ||
32 | + interface ReadState { | ||
33 | + String UNREAD = "0"; | ||
34 | + String READ = "1"; | ||
35 | + } | ||
36 | + | ||
37 | + interface ReceiverType { | ||
38 | + int PERSONAL = 3; | ||
39 | + int DEPARTMENT = 2; | ||
40 | + int ORGANIZATION = 1; | ||
41 | + int ALL = 0; | ||
42 | + } | ||
43 | + | ||
44 | + interface DraftStatus { | ||
45 | + int PUBLISHED = 1; | ||
46 | + int DRAFT = 0; | ||
47 | + } | ||
48 | + | ||
49 | + interface CacheKey { | ||
50 | + String area = "thingsArea"; | ||
51 | + int DRAFT = 0; | ||
52 | + } | ||
53 | + | ||
54 | + interface ConfigureLevel { | ||
55 | + String CONFIGURE = "CONFIGURE"; | ||
56 | + String CONTENT = "CONTENT"; | ||
57 | + String NODE = "NODE"; | ||
58 | + } | ||
59 | + | ||
16 | class DefaultOrder { | 60 | class DefaultOrder { |
17 | - public static final String CREATE_TIME="create_time"; | 61 | + public static final String CREATE_TIME = "create_time"; |
18 | } | 62 | } |
63 | + | ||
19 | class ScheduleConstants { | 64 | class ScheduleConstants { |
20 | public static final String TASK_CLASS_NAME = "TASK_CLASS_NAME"; | 65 | public static final String TASK_CLASS_NAME = "TASK_CLASS_NAME"; |
21 | 66 | ||
@@ -34,61 +79,47 @@ public interface FastIotConstants { | @@ -34,61 +79,47 @@ public interface FastIotConstants { | ||
34 | /** 不触发立即执行 */ | 79 | /** 不触发立即执行 */ |
35 | public static final int MISFIRE_DO_NOTHING = 3; | 80 | public static final int MISFIRE_DO_NOTHING = 3; |
36 | 81 | ||
37 | - /** | ||
38 | - * 定时任务白名单配置(仅允许访问的包名,如其他需要可以自行添加) | ||
39 | - */ | ||
40 | - public static final String[] JOB_WHITELIST_STR = { "org.thingsboard.server.dao.util.yunteng.task" }; | ||
41 | - /** | ||
42 | - * http请求 | ||
43 | - */ | 82 | + /** 定时任务白名单配置(仅允许访问的包名,如其他需要可以自行添加) */ |
83 | + public static final String[] JOB_WHITELIST_STR = { | ||
84 | + "org.thingsboard.server.dao.util.yunteng.task" | ||
85 | + }; | ||
86 | + /** http请求 */ | ||
44 | public static final String HTTP = "http://"; | 87 | public static final String HTTP = "http://"; |
45 | 88 | ||
46 | - /** | ||
47 | - * https请求 | ||
48 | - */ | 89 | + /** https请求 */ |
49 | public static final String HTTPS = "https://"; | 90 | public static final String HTTPS = "https://"; |
50 | 91 | ||
51 | - | ||
52 | - /** | ||
53 | - * RMI 远程方法调用 | ||
54 | - */ | 92 | + /** RMI 远程方法调用 */ |
55 | public static final String LOOKUP_RMI = "rmi:"; | 93 | public static final String LOOKUP_RMI = "rmi:"; |
56 | 94 | ||
57 | - /** | ||
58 | - * LDAP 远程方法调用 | ||
59 | - */ | 95 | + /** LDAP 远程方法调用 */ |
60 | public static final String LOOKUP_LDAP = "ldap:"; | 96 | public static final String LOOKUP_LDAP = "ldap:"; |
61 | 97 | ||
62 | - /** | ||
63 | - * LDAPS 远程方法调用 | ||
64 | - */ | 98 | + /** LDAPS 远程方法调用 */ |
65 | public static final String LOOKUP_LDAPS = "ldaps:"; | 99 | public static final String LOOKUP_LDAPS = "ldaps:"; |
66 | - /** | ||
67 | - * 定时任务违规的字符 | ||
68 | - */ | ||
69 | - public static final String[] JOB_ERROR_STR = { "java.net.URL", "javax.naming.InitialContext", "org.yaml.snakeyaml", | ||
70 | - "org.springframework", "org.apache"}; | ||
71 | - | 100 | + /** 定时任务违规的字符 */ |
101 | + public static final String[] JOB_ERROR_STR = { | ||
102 | + "java.net.URL", | ||
103 | + "javax.naming.InitialContext", | ||
104 | + "org.yaml.snakeyaml", | ||
105 | + "org.springframework", | ||
106 | + "org.apache" | ||
107 | + }; | ||
72 | } | 108 | } |
73 | - class MagicNumber{ | 109 | + |
110 | + class MagicNumber { | ||
74 | public static final int ZERO = 0; | 111 | public static final int ZERO = 0; |
75 | public static final int ONE = 1; | 112 | public static final int ONE = 1; |
76 | public static final int TEN = 10; | 113 | public static final int TEN = 10; |
77 | } | 114 | } |
78 | 115 | ||
79 | - String MOBILE = | ||
80 | - "^[1](([3][0-9])|([4][0,1,4-9])|([5][0-3,5-9])|([6][2,5,6,7])|([7][0-8])|([8][0-9])|([9][0-3,5-9]))[0-9]{8}$"; | ||
81 | - String EMAIL = "^[A-Z0-9._%+-]+@[A-Z0-9.-]+\\.[A-Z]{2,}$"; | ||
82 | - Pattern EMAIL_PATTERN = Pattern.compile(EMAIL, Pattern.CASE_INSENSITIVE); | ||
83 | - Pattern CHINA_MOBILE_PATTERN = Pattern.compile(MOBILE); | ||
84 | - | ||
85 | class ConfigJSONKey { | 116 | class ConfigJSONKey { |
86 | public static final String BASE_URL = "baseUrl"; | 117 | public static final String BASE_URL = "baseUrl"; |
87 | } | 118 | } |
119 | + | ||
88 | class Relation { | 120 | class Relation { |
89 | public static final String relationType = "Created"; | 121 | public static final String relationType = "Created"; |
90 | } | 122 | } |
91 | - String DEFAULT_DELIMITER = "#"; | ||
92 | 123 | ||
93 | class StateValue { | 124 | class StateValue { |
94 | /** 禁用 */ | 125 | /** 禁用 */ |
@@ -96,6 +127,11 @@ public interface FastIotConstants { | @@ -96,6 +127,11 @@ public interface FastIotConstants { | ||
96 | /** 启用 */ | 127 | /** 启用 */ |
97 | public static final int ENABLE = 1; | 128 | public static final int ENABLE = 1; |
98 | 129 | ||
130 | + /** 离线 */ | ||
131 | + public static final int OFFLINE = 0; | ||
132 | + /** 在线 */ | ||
133 | + public static final int ONLINE = 1; | ||
134 | + | ||
99 | /** 删除成功 */ | 135 | /** 删除成功 */ |
100 | public static final String DELETE_SUCCESS = "删除成功"; | 136 | public static final String DELETE_SUCCESS = "删除成功"; |
101 | 137 | ||
@@ -105,7 +141,7 @@ public interface FastIotConstants { | @@ -105,7 +141,7 @@ public interface FastIotConstants { | ||
105 | 141 | ||
106 | class LevelValue { | 142 | class LevelValue { |
107 | /** 超级管理员 */ | 143 | /** 超级管理员 */ |
108 | - public static final int IS_ADMIN=0; | 144 | + public static final int IS_ADMIN = 0; |
109 | 145 | ||
110 | /** 系统平台其他管理员 */ | 146 | /** 系统平台其他管理员 */ |
111 | public static final int IS_PLATFORM_ADMIN = 1; | 147 | public static final int IS_PLATFORM_ADMIN = 1; |
@@ -116,42 +152,4 @@ public interface FastIotConstants { | @@ -116,42 +152,4 @@ public interface FastIotConstants { | ||
116 | /** 租户下的用户 */ | 152 | /** 租户下的用户 */ |
117 | public static final int IS_CUSTOMER_USER = 3; | 153 | public static final int IS_CUSTOMER_USER = 3; |
118 | } | 154 | } |
119 | - | ||
120 | - interface CacheConfigKey { | ||
121 | - String CACHE_CONFIG_KEY = "yunTengIotCache"; | ||
122 | - String USER_PERMISSION_PREFIX = "userPermissionFor_"; | ||
123 | - String MOBILE_LOGIN_SMS_CODE = "mobileLoginSmsCode"; | ||
124 | - } | ||
125 | - | ||
126 | - interface TBCacheConfig { | ||
127 | - String TB_CACHE_CONFIG_KEY = "TB_CONNECT_CACHE"; | ||
128 | - String EXISTING_TENANT = "EXISTING_TENANT"; | ||
129 | - } | ||
130 | - interface ReadState { | ||
131 | - String UNREAD = "0"; | ||
132 | - String READ = "1"; | ||
133 | - } | ||
134 | - | ||
135 | - interface ReceiverType { | ||
136 | - int PERSONAL = 3; | ||
137 | - int DEPARTMENT = 2; | ||
138 | - int ORGANIZATION = 1; | ||
139 | - int ALL = 0; | ||
140 | - } | ||
141 | - | ||
142 | - interface DraftStatus { | ||
143 | - int PUBLISHED = 1; | ||
144 | - int DRAFT = 0; | ||
145 | - } | ||
146 | - | ||
147 | - interface CacheKey { | ||
148 | - String area = "thingsArea"; | ||
149 | - int DRAFT = 0; | ||
150 | - } | ||
151 | - | ||
152 | - interface ConfigureLevel { | ||
153 | - String CONFIGURE = "CONFIGURE"; | ||
154 | - String CONTENT = "CONTENT"; | ||
155 | - String NODE = "NODE"; | ||
156 | - } | ||
157 | } | 155 | } |
@@ -110,6 +110,8 @@ public final class ModelConstants { | @@ -110,6 +110,8 @@ public final class ModelConstants { | ||
110 | public static final String TK_THING_MODEL = "tk_things_model"; | 110 | public static final String TK_THING_MODEL = "tk_things_model"; |
111 | /** 客户和设备的映射表 */ | 111 | /** 客户和设备的映射表 */ |
112 | public static final String TK_CUSTOMER_DEVICE_NAME = "tk_customer_device"; | 112 | public static final String TK_CUSTOMER_DEVICE_NAME = "tk_customer_device"; |
113 | + /** 设备上下线记录表 */ | ||
114 | + public static final String TK_DEVICE_STATE_LOG = "tk_device_state_log"; | ||
113 | } | 115 | } |
114 | 116 | ||
115 | public static class TableFields { | 117 | public static class TableFields { |
common/data/src/main/java/org/thingsboard/server/common/data/yunteng/dto/TkDeviceStateLogDTO.java
0 → 100644
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.DeviceTypeEnum; | ||
6 | + | ||
7 | +@Data | ||
8 | +public class TkDeviceStateLogDTO extends TenantDTO { | ||
9 | + @ApiModelProperty(value = "设备ID") | ||
10 | + private String tbDeviceId; | ||
11 | + | ||
12 | + @ApiModelProperty(value = "设备状态:0离线 1在线") | ||
13 | + private Integer status; | ||
14 | + | ||
15 | + @ApiModelProperty(value = "备注") | ||
16 | + private String remark; | ||
17 | + | ||
18 | + @ApiModelProperty(value = "设备名称") | ||
19 | + private String deviceName; | ||
20 | + | ||
21 | + @ApiModelProperty(value = "设备配置名称") | ||
22 | + private String deviceProfileName; | ||
23 | + | ||
24 | + @ApiModelProperty(value = "设备类型") | ||
25 | + private DeviceTypeEnum deviceType; | ||
26 | + | ||
27 | + @ApiModelProperty(value = "组织名称") | ||
28 | + private String organizationName; | ||
29 | +} |
dao/src/main/java/org/thingsboard/server/dao/yunteng/entities/TkDeviceStateLogEntity.java
0 → 100644
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 lombok.Data; | ||
6 | +import lombok.EqualsAndHashCode; | ||
7 | +import org.apache.ibatis.type.EnumTypeHandler; | ||
8 | +import org.thingsboard.server.common.data.yunteng.constant.ModelConstants; | ||
9 | +import org.thingsboard.server.common.data.yunteng.enums.DeviceTypeEnum; | ||
10 | + | ||
11 | +@Data | ||
12 | +@TableName(value = ModelConstants.Table.TK_DEVICE_STATE_LOG, autoResultMap = true) | ||
13 | +@EqualsAndHashCode(callSuper = true) | ||
14 | +public class TkDeviceStateLogEntity extends TenantBaseEntity { | ||
15 | + private String tbDeviceId; | ||
16 | + /** 告警状态:0:正常 1:告警 */ | ||
17 | + private Integer status; | ||
18 | + | ||
19 | + private String deviceName; | ||
20 | + private String deviceProfileName; | ||
21 | + | ||
22 | + @TableField(typeHandler = EnumTypeHandler.class) | ||
23 | + private DeviceTypeEnum deviceType; | ||
24 | + | ||
25 | + private String organizationName; | ||
26 | + private String remark; | ||
27 | +} |
@@ -633,4 +633,12 @@ public class TkDeviceServiceImpl extends AbstractBaseService<DeviceMapper, TkDev | @@ -633,4 +633,12 @@ public class TkDeviceServiceImpl extends AbstractBaseService<DeviceMapper, TkDev | ||
633 | } | 633 | } |
634 | return baseMapper.getDeviceRelation(isSlave, deviceId); | 634 | return baseMapper.getDeviceRelation(isSlave, deviceId); |
635 | } | 635 | } |
636 | + | ||
637 | + @Override | ||
638 | + public DeviceDTO findDeviceInfoByTbDeviceId(String tenantId, String tbDeviceId) { | ||
639 | + if(StringUtils.isEmpty(tenantId) || StringUtils.isEmpty(tbDeviceId)){ | ||
640 | + throw new TkDataValidationException(ErrorMessage.INVALID_PARAMETER.getMessage()); | ||
641 | + } | ||
642 | + return baseMapper.findDeviceInfo(tenantId, tbDeviceId); | ||
643 | + } | ||
636 | } | 644 | } |
dao/src/main/java/org/thingsboard/server/dao/yunteng/impl/TkDeviceStateLogServiceImpl.java
0 → 100644
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 lombok.RequiredArgsConstructor; | ||
6 | +import org.apache.commons.lang3.StringUtils; | ||
7 | +import org.springframework.stereotype.Service; | ||
8 | +import org.springframework.transaction.annotation.Transactional; | ||
9 | +import org.thingsboard.server.common.data.yunteng.constant.FastIotConstants; | ||
10 | +import org.thingsboard.server.common.data.yunteng.core.exception.TkDataValidationException; | ||
11 | +import org.thingsboard.server.common.data.yunteng.core.message.ErrorMessage; | ||
12 | +import org.thingsboard.server.common.data.yunteng.dto.DeleteDTO; | ||
13 | +import org.thingsboard.server.common.data.yunteng.dto.TkDeviceStateLogDTO; | ||
14 | +import org.thingsboard.server.common.data.yunteng.utils.tools.TkPageData; | ||
15 | +import org.thingsboard.server.dao.yunteng.entities.TkDeviceStateLogEntity; | ||
16 | +import org.thingsboard.server.dao.yunteng.mapper.TkDeviceStateLogMapper; | ||
17 | +import org.thingsboard.server.dao.yunteng.service.AbstractBaseService; | ||
18 | +import org.thingsboard.server.dao.yunteng.service.TkDeviceStateLogService; | ||
19 | + | ||
20 | +import java.time.LocalDateTime; | ||
21 | +import java.util.Map; | ||
22 | +import java.util.Objects; | ||
23 | +import java.util.Optional; | ||
24 | + | ||
25 | +@Service | ||
26 | +@RequiredArgsConstructor | ||
27 | +public class TkDeviceStateLogServiceImpl | ||
28 | + extends AbstractBaseService<TkDeviceStateLogMapper, TkDeviceStateLogEntity> | ||
29 | + implements TkDeviceStateLogService { | ||
30 | + @Override | ||
31 | + public TkPageData<TkDeviceStateLogDTO> page(String tenantId, Map<String, Object> queryMap) { | ||
32 | + String deviceName = | ||
33 | + Optional.ofNullable(queryMap.get("deviceName")).map(Object::toString).orElse(null); | ||
34 | + String organizationName = | ||
35 | + Optional.ofNullable(queryMap.get("organizationName")).map(Object::toString).orElse(null); | ||
36 | + String deviceProfileName = | ||
37 | + Optional.ofNullable(queryMap.get("deviceProfileName")).map(Object::toString).orElse(null); | ||
38 | + Integer status = | ||
39 | + Optional.ofNullable(queryMap.get("status")) | ||
40 | + .map(obj -> Integer.valueOf(obj.toString())) | ||
41 | + .orElse(null); | ||
42 | + LocalDateTime startTime = | ||
43 | + (LocalDateTime) Optional.ofNullable(queryMap.get("startTime")).orElse(null); | ||
44 | + LocalDateTime endTime = | ||
45 | + (LocalDateTime) Optional.ofNullable(queryMap.get("endTime")).orElse(null); | ||
46 | + IPage<TkDeviceStateLogEntity> currentPage = | ||
47 | + getPage(queryMap, FastIotConstants.DefaultOrder.CREATE_TIME, false); | ||
48 | + LambdaQueryWrapper<TkDeviceStateLogEntity> queryWrapper = | ||
49 | + new LambdaQueryWrapper<TkDeviceStateLogEntity>() | ||
50 | + .eq(TkDeviceStateLogEntity::getTenantId, tenantId) | ||
51 | + .eq(null != status, TkDeviceStateLogEntity::getStatus, status) | ||
52 | + .like( | ||
53 | + StringUtils.isNotEmpty(deviceName), | ||
54 | + TkDeviceStateLogEntity::getDeviceName, | ||
55 | + deviceName) | ||
56 | + .like( | ||
57 | + StringUtils.isNotEmpty(organizationName), | ||
58 | + TkDeviceStateLogEntity::getOrganizationName, | ||
59 | + organizationName) | ||
60 | + .like( | ||
61 | + StringUtils.isNotEmpty(deviceProfileName), | ||
62 | + TkDeviceStateLogEntity::getDeviceProfileName, | ||
63 | + deviceProfileName) | ||
64 | + .and( | ||
65 | + null != startTime && null != endTime, | ||
66 | + qr -> | ||
67 | + qr.ge(TkDeviceStateLogEntity::getCreateTime, startTime) | ||
68 | + .le(TkDeviceStateLogEntity::getCreateTime, endTime)); | ||
69 | + return getPageData(baseMapper.selectPage(currentPage, queryWrapper), TkDeviceStateLogDTO.class); | ||
70 | + } | ||
71 | + | ||
72 | + @Override | ||
73 | + @Transactional | ||
74 | + public boolean deleteTkDeviceStateLog(DeleteDTO deleteDTO) { | ||
75 | + return baseMapper.delete( | ||
76 | + new LambdaQueryWrapper<TkDeviceStateLogEntity>() | ||
77 | + .eq(TkDeviceStateLogEntity::getTenantId, deleteDTO.getTenantId()) | ||
78 | + .in(TkDeviceStateLogEntity::getId, deleteDTO.getIds())) | ||
79 | + > FastIotConstants.MagicNumber.ZERO; | ||
80 | + } | ||
81 | + | ||
82 | + @Override | ||
83 | + public TkDeviceStateLogDTO findTkDeviceStateLogInfoById(String tenantId, String id) { | ||
84 | + TkDeviceStateLogEntity entity = | ||
85 | + baseMapper.selectOne( | ||
86 | + new LambdaQueryWrapper<TkDeviceStateLogEntity>().eq(TkDeviceStateLogEntity::getId, id)); | ||
87 | + if (null != entity && !Objects.equals(entity.getTenantId(), tenantId)) { | ||
88 | + throw new TkDataValidationException( | ||
89 | + ErrorMessage.INVALID_PARAMETER_OR_NOT_MATCH_TENANT.getMessage()); | ||
90 | + } | ||
91 | + return null != entity ? entity.getDTO(TkDeviceStateLogDTO.class) : null; | ||
92 | + } | ||
93 | + | ||
94 | + @Override | ||
95 | + @Transactional | ||
96 | + public TkDeviceStateLogDTO saveOrUpdateTkDeviceStateLogInfo( | ||
97 | + TkDeviceStateLogDTO tkDeviceStateLogDTO) { | ||
98 | + TkDeviceStateLogEntity saveEntity = tkDeviceStateLogDTO.getEntity(TkDeviceStateLogEntity.class); | ||
99 | + if (null == tkDeviceStateLogDTO.getId()) { | ||
100 | + baseMapper.insert(saveEntity); | ||
101 | + } else { | ||
102 | + TkDeviceStateLogEntity entity = | ||
103 | + baseMapper.selectOne( | ||
104 | + new LambdaQueryWrapper<TkDeviceStateLogEntity>() | ||
105 | + .eq(TkDeviceStateLogEntity::getId, tkDeviceStateLogDTO.getId())); | ||
106 | + if (null == entity | ||
107 | + || !Objects.equals(tkDeviceStateLogDTO.getTenantId(), entity.getTenantId())) { | ||
108 | + throw new TkDataValidationException( | ||
109 | + ErrorMessage.INVALID_PARAMETER_OR_NOT_MATCH_TENANT.getMessage()); | ||
110 | + } | ||
111 | + baseMapper.updateById(saveEntity); | ||
112 | + } | ||
113 | + | ||
114 | + return tkDeviceStateLogDTO; | ||
115 | + } | ||
116 | +} |
@@ -144,4 +144,6 @@ public interface DeviceMapper extends BaseMapper<TkDeviceEntity> { | @@ -144,4 +144,6 @@ public interface DeviceMapper extends BaseMapper<TkDeviceEntity> { | ||
144 | @Param("deviceIds") List<String> deviceIds); | 144 | @Param("deviceIds") List<String> deviceIds); |
145 | 145 | ||
146 | String getDeviceRelation(@Param("isSlave") boolean isSlave, @Param("deviceId") String deviceId); | 146 | String getDeviceRelation(@Param("isSlave") boolean isSlave, @Param("deviceId") String deviceId); |
147 | + | ||
148 | + DeviceDTO findDeviceInfo(@Param("tenantId") String tenantId,@Param("tbDeviceId") String tbDeviceId); | ||
147 | } | 149 | } |
1 | +package org.thingsboard.server.dao.yunteng.mapper; | ||
2 | + | ||
3 | +import com.baomidou.mybatisplus.core.mapper.BaseMapper; | ||
4 | +import com.baomidou.mybatisplus.core.metadata.IPage; | ||
5 | +import org.apache.ibatis.annotations.Mapper; | ||
6 | +import org.apache.ibatis.annotations.Param; | ||
7 | +import org.thingsboard.server.common.data.yunteng.dto.DeviceProfileDTO; | ||
8 | +import org.thingsboard.server.dao.yunteng.entities.TkDeviceStateLogEntity; | ||
9 | + | ||
10 | +import java.util.Map; | ||
11 | + | ||
12 | +@Mapper | ||
13 | +public interface TkDeviceStateLogMapper extends BaseMapper<TkDeviceStateLogEntity> { | ||
14 | + IPage<DeviceProfileDTO> getPage( | ||
15 | + IPage<?> page, | ||
16 | + @Param("tenantId") String tenantId, | ||
17 | + @Param("queryMap") Map<String, Object> queryMap); | ||
18 | +} |
@@ -190,4 +190,6 @@ public interface TkDeviceService extends BaseService<TkDeviceEntity> { | @@ -190,4 +190,6 @@ public interface TkDeviceService extends BaseService<TkDeviceEntity> { | ||
190 | JsonNode getDeviceAttributes(String deviceProfileId, String tenantId, DataTypeEnum dataType); | 190 | JsonNode getDeviceAttributes(String deviceProfileId, String tenantId, DataTypeEnum dataType); |
191 | 191 | ||
192 | String getDeviceRelation(boolean isSlave,String deviceId); | 192 | String getDeviceRelation(boolean isSlave,String deviceId); |
193 | + | ||
194 | + DeviceDTO findDeviceInfoByTbDeviceId(String tenantId,String tbDeviceId); | ||
193 | } | 195 | } |
dao/src/main/java/org/thingsboard/server/dao/yunteng/service/TkDeviceStateLogService.java
0 → 100644
1 | +package org.thingsboard.server.dao.yunteng.service; | ||
2 | + | ||
3 | +import org.thingsboard.server.common.data.yunteng.dto.DeleteDTO; | ||
4 | +import org.thingsboard.server.common.data.yunteng.dto.TkDeviceStateLogDTO; | ||
5 | +import org.thingsboard.server.common.data.yunteng.utils.tools.TkPageData; | ||
6 | +import org.thingsboard.server.dao.yunteng.entities.TkDeviceStateLogEntity; | ||
7 | + | ||
8 | +import java.util.Map; | ||
9 | + | ||
10 | +public interface TkDeviceStateLogService extends BaseService<TkDeviceStateLogEntity> { | ||
11 | + TkPageData<TkDeviceStateLogDTO> page(String tenantId,Map<String, Object> queryMap); | ||
12 | + | ||
13 | + boolean deleteTkDeviceStateLog(DeleteDTO deleteDTO); | ||
14 | + | ||
15 | + TkDeviceStateLogDTO findTkDeviceStateLogInfoById(String tenantId, String id); | ||
16 | + | ||
17 | + TkDeviceStateLogDTO saveOrUpdateTkDeviceStateLogInfo(TkDeviceStateLogDTO tkDeviceStateLogDTO); | ||
18 | +} |
@@ -448,4 +448,14 @@ | @@ -448,4 +448,14 @@ | ||
448 | AND to_id :: TEXT = #{deviceId} | 448 | AND to_id :: TEXT = #{deviceId} |
449 | </if> | 449 | </if> |
450 | </select> | 450 | </select> |
451 | + | ||
452 | + <select id="findDeviceInfo" resultMap="deviceMap"> | ||
453 | + SELECT | ||
454 | + <include refid="basicColumns"/>,tdp.name AS profile_name,io.name AS organization_name | ||
455 | + FROM tk_device ifd | ||
456 | + LEFT JOIN tk_device_profile tdp ON ifd.device_profile_id = tdp.id | ||
457 | + LEFT JOIN tk_organization io ON io.id = ifd.organization_id | ||
458 | + WHERE ifd.tb_device_id = #{tbDeviceId} | ||
459 | + AND ifd.tenant_id = #{tenantId} | ||
460 | + </select> | ||
451 | </mapper> | 461 | </mapper> |