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 | 39 | import org.thingsboard.server.common.data.page.PageData; |
40 | 40 | import org.thingsboard.server.common.data.page.PageDataIterable; |
41 | 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 | 45 | import org.thingsboard.server.common.msg.TbMsg; |
43 | 46 | import org.thingsboard.server.common.msg.TbMsgDataType; |
44 | 47 | import org.thingsboard.server.common.msg.TbMsgMetaData; |
... | ... | @@ -49,6 +52,8 @@ import org.thingsboard.server.dao.attributes.AttributesService; |
49 | 52 | import org.thingsboard.server.dao.device.DeviceService; |
50 | 53 | import org.thingsboard.server.dao.tenant.TenantService; |
51 | 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 | 57 | import org.thingsboard.server.gen.transport.TransportProtos; |
53 | 58 | import org.thingsboard.server.queue.discovery.PartitionService; |
54 | 59 | import org.thingsboard.server.service.partition.AbstractPartitionBasedService; |
... | ... | @@ -58,6 +63,7 @@ import javax.annotation.Nonnull; |
58 | 63 | import javax.annotation.Nullable; |
59 | 64 | import javax.annotation.PostConstruct; |
60 | 65 | import javax.annotation.PreDestroy; |
66 | +import java.time.LocalDateTime; | |
61 | 67 | import java.util.*; |
62 | 68 | import java.util.concurrent.*; |
63 | 69 | |
... | ... | @@ -87,6 +93,8 @@ public class DefaultDeviceStateService extends AbstractPartitionBasedService<Dev |
87 | 93 | private final TimeseriesService tsService; |
88 | 94 | private final TbClusterService clusterService; |
89 | 95 | private final PartitionService partitionService; |
96 | + private final TkDeviceService tkDeviceService; | |
97 | + private final TkDeviceStateLogService tkDeviceStateLogService; | |
90 | 98 | |
91 | 99 | private TelemetrySubscriptionService tsSubService; |
92 | 100 | |
... | ... | @@ -112,13 +120,16 @@ public class DefaultDeviceStateService extends AbstractPartitionBasedService<Dev |
112 | 120 | |
113 | 121 | public DefaultDeviceStateService(TenantService tenantService, DeviceService deviceService, |
114 | 122 | AttributesService attributesService, TimeseriesService tsService, |
115 | - TbClusterService clusterService, PartitionService partitionService) { | |
123 | + TbClusterService clusterService, PartitionService partitionService, | |
124 | + TkDeviceService tkDeviceService,TkDeviceStateLogService tkDeviceStateLogService) { | |
116 | 125 | this.tenantService = tenantService; |
117 | 126 | this.deviceService = deviceService; |
118 | 127 | this.attributesService = attributesService; |
119 | 128 | this.tsService = tsService; |
120 | 129 | this.clusterService = clusterService; |
121 | 130 | this.partitionService = partitionService; |
131 | + this.tkDeviceService = tkDeviceService; | |
132 | + this.tkDeviceStateLogService = tkDeviceStateLogService; | |
122 | 133 | } |
123 | 134 | |
124 | 135 | @Autowired |
... | ... | @@ -165,6 +176,8 @@ public class DefaultDeviceStateService extends AbstractPartitionBasedService<Dev |
165 | 176 | save(deviceId, LAST_CONNECT_TIME, ts); |
166 | 177 | pushRuleEngineMessage(stateData, CONNECT_EVENT); |
167 | 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 | 220 | stateData.getState().setLastDisconnectTime(ts); |
208 | 221 | save(deviceId, LAST_DISCONNECT_TIME, ts); |
209 | 222 | pushRuleEngineMessage(stateData, DISCONNECT_EVENT); |
223 | + //ThingsKit | |
224 | + saveDeviceStateLog(tenantId.toString(),deviceId.toString(), FastIotConstants.StateValue.OFFLINE); | |
210 | 225 | } |
211 | 226 | |
212 | 227 | @Override |
... | ... | @@ -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 | 381 | private void addDeviceUsingState(TopicPartitionInfo tpi, DeviceStateData state) { |
348 | 382 | Set<DeviceId> deviceIds = partitionedEntities.get(tpi); |
349 | 383 | if (deviceIds != null) { | ... | ... |
... | ... | @@ -26,6 +26,8 @@ import org.thingsboard.server.dao.attributes.AttributesService; |
26 | 26 | import org.thingsboard.server.dao.device.DeviceService; |
27 | 27 | import org.thingsboard.server.dao.tenant.TenantService; |
28 | 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 | 31 | import org.thingsboard.server.queue.discovery.PartitionService; |
30 | 32 | import org.thingsboard.server.cluster.TbClusterService; |
31 | 33 | |
... | ... | @@ -53,6 +55,10 @@ public class DefaultDeviceStateServiceTest { |
53 | 55 | PartitionService partitionService; |
54 | 56 | @Mock |
55 | 57 | DeviceStateData deviceStateDataMock; |
58 | + @Mock | |
59 | + TkDeviceService tkDeviceService; | |
60 | + @Mock | |
61 | + TkDeviceStateLogService tkDeviceStateLogService; | |
56 | 62 | |
57 | 63 | DeviceId deviceId = DeviceId.fromString("00797a3b-7aeb-4b5b-b57a-c2a810d0f112"); |
58 | 64 | |
... | ... | @@ -60,7 +66,7 @@ public class DefaultDeviceStateServiceTest { |
60 | 66 | |
61 | 67 | @Before |
62 | 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 | 72 | @Test | ... | ... |
... | ... | @@ -13,9 +13,54 @@ public interface FastIotConstants { |
13 | 13 | String CHART_EXECUTE_ATTRIBUTES = "executeAttributes"; |
14 | 14 | String ASSERT_DEFAULT_NAME = "default"; |
15 | 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 | 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 | 64 | class ScheduleConstants { |
20 | 65 | public static final String TASK_CLASS_NAME = "TASK_CLASS_NAME"; |
21 | 66 | |
... | ... | @@ -34,61 +79,47 @@ public interface FastIotConstants { |
34 | 79 | /** 不触发立即执行 */ |
35 | 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 | 87 | public static final String HTTP = "http://"; |
45 | 88 | |
46 | - /** | |
47 | - * https请求 | |
48 | - */ | |
89 | + /** https请求 */ | |
49 | 90 | public static final String HTTPS = "https://"; |
50 | 91 | |
51 | - | |
52 | - /** | |
53 | - * RMI 远程方法调用 | |
54 | - */ | |
92 | + /** RMI 远程方法调用 */ | |
55 | 93 | public static final String LOOKUP_RMI = "rmi:"; |
56 | 94 | |
57 | - /** | |
58 | - * LDAP 远程方法调用 | |
59 | - */ | |
95 | + /** LDAP 远程方法调用 */ | |
60 | 96 | public static final String LOOKUP_LDAP = "ldap:"; |
61 | 97 | |
62 | - /** | |
63 | - * LDAPS 远程方法调用 | |
64 | - */ | |
98 | + /** LDAPS 远程方法调用 */ | |
65 | 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 | 111 | public static final int ZERO = 0; |
75 | 112 | public static final int ONE = 1; |
76 | 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 | 116 | class ConfigJSONKey { |
86 | 117 | public static final String BASE_URL = "baseUrl"; |
87 | 118 | } |
119 | + | |
88 | 120 | class Relation { |
89 | 121 | public static final String relationType = "Created"; |
90 | 122 | } |
91 | - String DEFAULT_DELIMITER = "#"; | |
92 | 123 | |
93 | 124 | class StateValue { |
94 | 125 | /** 禁用 */ |
... | ... | @@ -96,6 +127,11 @@ public interface FastIotConstants { |
96 | 127 | /** 启用 */ |
97 | 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 | 136 | public static final String DELETE_SUCCESS = "删除成功"; |
101 | 137 | |
... | ... | @@ -105,7 +141,7 @@ public interface FastIotConstants { |
105 | 141 | |
106 | 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 | 147 | public static final int IS_PLATFORM_ADMIN = 1; |
... | ... | @@ -116,42 +152,4 @@ public interface FastIotConstants { |
116 | 152 | /** 租户下的用户 */ |
117 | 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 | 110 | public static final String TK_THING_MODEL = "tk_things_model"; |
111 | 111 | /** 客户和设备的映射表 */ |
112 | 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 | 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 | 633 | } |
634 | 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 | 144 | @Param("deviceIds") List<String> deviceIds); |
145 | 145 | |
146 | 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 | 190 | JsonNode getDeviceAttributes(String deviceProfileId, String tenantId, DataTypeEnum dataType); |
191 | 191 | |
192 | 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 | 448 | AND to_id :: TEXT = #{deviceId} |
449 | 449 | </if> |
450 | 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 | 461 | </mapper> | ... | ... |