Commit 96a269ef03b16dcfc84f36614ea63e640537f1a6

Authored by xp.Huang
2 parents e5417d6c dd71a436

Merge branch 'master_dev_cassandra' into 'master_dev'

fix: 首页统计分析时序数据库兼容问题修复

See merge request yunteng/thingskit!352
1 package org.thingsboard.server.controller.yunteng; 1 package org.thingsboard.server.controller.yunteng;
2 2
  3 +import static org.thingsboard.server.common.data.yunteng.constant.QueryConstant.PAGE;
  4 +import static org.thingsboard.server.common.data.yunteng.constant.QueryConstant.PAGE_SIZE;
  5 +
3 import io.swagger.annotations.Api; 6 import io.swagger.annotations.Api;
4 import io.swagger.annotations.ApiOperation; 7 import io.swagger.annotations.ApiOperation;
5 import io.swagger.annotations.ApiParam; 8 import io.swagger.annotations.ApiParam;
  9 +import java.util.HashMap;
  10 +import java.util.List;
  11 +import java.util.concurrent.ExecutionException;
6 import lombok.RequiredArgsConstructor; 12 import lombok.RequiredArgsConstructor;
7 import org.springframework.http.HttpStatus; 13 import org.springframework.http.HttpStatus;
8 import org.springframework.http.ResponseEntity; 14 import org.springframework.http.ResponseEntity;
@@ -23,91 +29,87 @@ import org.thingsboard.server.dao.exception.DataValidationException; @@ -23,91 +29,87 @@ import org.thingsboard.server.dao.exception.DataValidationException;
23 import org.thingsboard.server.dao.yunteng.service.HomePageService; 29 import org.thingsboard.server.dao.yunteng.service.HomePageService;
24 import org.thingsboard.server.service.security.model.SecurityUser; 30 import org.thingsboard.server.service.security.model.SecurityUser;
25 31
26 -import java.util.HashMap;  
27 -import java.util.List;  
28 -import java.util.concurrent.ExecutionException;  
29 -  
30 -import static org.thingsboard.server.common.data.yunteng.constant.QueryConstant.PAGE;  
31 -import static org.thingsboard.server.common.data.yunteng.constant.QueryConstant.PAGE_SIZE;  
32 -  
33 @RequestMapping("api/yt/homepage") 32 @RequestMapping("api/yt/homepage")
34 @Api(tags = {"首页"}) 33 @Api(tags = {"首页"})
35 @RequiredArgsConstructor 34 @RequiredArgsConstructor
36 @RestController 35 @RestController
37 public class HomePageController extends BaseController { 36 public class HomePageController extends BaseController {
38 37
39 - private final HomePageService homePageService; 38 + private final HomePageService homePageService;
40 39
41 - @GetMapping("left/top")  
42 - @ApiOperation(value = "获取左侧顶部信息")  
43 - public HomePageLeftTopDTO getLeftTopInfo()  
44 - throws ThingsboardException, ExecutionException, InterruptedException {  
45 - return homePageService.getHomePageLeftTopInfo(  
46 - getCurrentUser().isPtSysadmin(),  
47 - getCurrentUser().isPtAdmin(),  
48 - getCurrentUser().isPtTenantAdmin(),  
49 - getCurrentUser().getCurrentTenantId(),  
50 - getCurrentUser().getCurrentUserId());  
51 - } 40 + @GetMapping("left/top")
  41 + @ApiOperation(value = "获取左侧顶部信息")
  42 + public HomePageLeftTopDTO getLeftTopInfo()
  43 + throws ThingsboardException, ExecutionException, InterruptedException {
  44 + return homePageService.getHomePageLeftTopInfo(
  45 + getCurrentUser().isPtSysadmin(),
  46 + getCurrentUser().isPtAdmin(),
  47 + getCurrentUser().isPtTenantAdmin(),
  48 + getCurrentUser().getCurrentTenantId(),
  49 + getCurrentUser().getCurrentUserId());
  50 + }
52 51
53 - @GetMapping("right/overdue")  
54 - @ApiOperation(value = "获取右侧过期租户信息")  
55 - @PreAuthorize("@check.checkPermissions({'SYS_ADMIN','PLATFORM_ADMIN'},{})")  
56 - public ResponseEntity<TkPageData<TenantDTO>> getRightTopInfo(  
57 - @RequestParam(PAGE) int page, @RequestParam(PAGE_SIZE) int pageSize) {  
58 - HashMap<String, Object> queryMap = new HashMap<>();  
59 - queryMap.put(PAGE_SIZE, pageSize);  
60 - queryMap.put(PAGE, page);  
61 - return ResponseEntity.ok(homePageService.getHomePageRightInfo(queryMap));  
62 - } 52 + @GetMapping("right/overdue")
  53 + @ApiOperation(value = "获取右侧过期租户信息")
  54 + @PreAuthorize("@check.checkPermissions({'SYS_ADMIN','PLATFORM_ADMIN'},{})")
  55 + public ResponseEntity<TkPageData<TenantDTO>> getRightTopInfo(
  56 + @RequestParam(PAGE) int page, @RequestParam(PAGE_SIZE) int pageSize) {
  57 + HashMap<String, Object> queryMap = new HashMap<>();
  58 + queryMap.put(PAGE_SIZE, pageSize);
  59 + queryMap.put(PAGE, page);
  60 + return ResponseEntity.ok(homePageService.getHomePageRightInfo(queryMap));
  61 + }
63 62
64 - @GetMapping("right/top10")  
65 - @ApiOperation(value = "获取右侧Top10")  
66 - @PreAuthorize("@check.checkPermissions({'SYS_ADMIN','PLATFORM_ADMIN'},{})")  
67 - public DeferredResult<List<TenantTransportMessageDTO>> getTop10() {  
68 - return homePageService.getTop10();  
69 - } 63 + @GetMapping("right/top10")
  64 + @ApiOperation(value = "获取右侧Top10")
  65 + @PreAuthorize("@check.checkPermissions({'SYS_ADMIN','PLATFORM_ADMIN'},{})")
  66 + public DeferredResult<List<TenantTransportMessageDTO>> getTop10() {
  67 + return homePageService.getTop10();
  68 + }
70 69
71 - @GetMapping("left/bottom")  
72 - @ApiOperation(value = "获取左侧底部信息")  
73 - @PreAuthorize("@check.checkPermissions({'SYS_ADMIN','PLATFORM_ADMIN','CUSTOMER_USER'},{})")  
74 - public DeferredResult<List<TkTsValue>> getLeftBottomInfo(  
75 - @RequestParam(value = "startTs") long startTs,  
76 - @RequestParam("endTs") long endTs,  
77 - @RequestParam("interval") long interval,  
78 - @RequestParam("trend") TrendType trend)  
79 - throws ThingsboardException {  
80 - String customerId;  
81 - if (getCurrentUser().isPtAdmin()) {  
82 - customerId = getCurrentUser().getCurrentTenantId();  
83 - } else {  
84 - customerId = getCurrentUser().getCustomerId().getId().toString();  
85 - }  
86 - boolean isCustomer = getCurrentUser().isCustomerUser();  
87 - if (TrendType.CUSTOMER_MESSAGE_STATISTICAL == trend  
88 - || TrendType.CUSTOMER_ALARM_STATISTICAL == trend) {  
89 - if (!isCustomer) {  
90 - throw new DataValidationException(ErrorMessage.INVALID_PARAMETER.getMessage());  
91 - }  
92 - }  
93 - if (TrendType.TENANT_TREND == trend || TrendType.CUSTOMER_TREND == trend) {  
94 - if (isCustomer) {  
95 - throw new DataValidationException(ErrorMessage.INVALID_PARAMETER.getMessage());  
96 - }  
97 - }  
98 - return homePageService.getHomePageLeftBottomInfo(  
99 - customerId, startTs, endTs, interval, trend, isCustomer); 70 + @GetMapping("left/bottom")
  71 + @ApiOperation(value = "获取左侧底部历史数据")
  72 + @PreAuthorize("@check.checkPermissions({'SYS_ADMIN','PLATFORM_ADMIN','CUSTOMER_USER'},{})")
  73 + public DeferredResult<List<TkTsValue>> getLeftBottomInfo(
  74 + @RequestParam(value = "startTs") long startTs,
  75 + @RequestParam("endTs") long endTs,
  76 + @RequestParam("interval") long interval,
  77 + @RequestParam("trend") TrendType trend)
  78 + throws ThingsboardException {
  79 + SecurityUser currentUser = getCurrentUser();
  80 + boolean isCustomer = currentUser.isCustomerUser();
  81 + if (TrendType.CUSTOMER_MESSAGE_STATISTICAL == trend
  82 + || TrendType.CUSTOMER_ALARM_STATISTICAL == trend) {
  83 + if (!isCustomer) {
  84 + throw new DataValidationException(ErrorMessage.INVALID_PARAMETER.getMessage());
  85 + }
  86 + }
  87 + if (TrendType.TENANT_TREND == trend || TrendType.CUSTOMER_TREND == trend) {
  88 + if (isCustomer) {
  89 + throw new DataValidationException(ErrorMessage.INVALID_PARAMETER.getMessage());
  90 + }
100 } 91 }
  92 + return homePageService.getHomePageLeftBottomInfo(
  93 + currentUser.getTenantId(), currentUser.getCustomerId(), startTs, endTs, interval, trend);
  94 + }
101 95
102 - @GetMapping("app")  
103 - @ApiOperation(value = "小程序首页统计信息")  
104 - public ResponseEntity<HomePageAppDTO> appStatistics(@ApiParam(value = "只取告警数据") @RequestParam("login") Boolean login)  
105 - throws ThingsboardException{  
106 - SecurityUser user = getCurrentUser();  
107 - if(user == null){  
108 - return ResponseEntity.status(HttpStatus.FORBIDDEN).build();  
109 - }  
110 - HomePageAppDTO app = homePageService.app(login,user.isPtSysadmin(),user.isPtAdmin(),user.isPtTenantAdmin(),user.getTenantId(),user.getCustomerId());  
111 - return ResponseEntity.ok(app); 96 + @GetMapping("app")
  97 + @ApiOperation(value = "小程序首页统计信息")
  98 + public ResponseEntity<HomePageAppDTO> appStatistics(
  99 + @ApiParam(value = "只取告警数据") @RequestParam("login") Boolean login)
  100 + throws ThingsboardException {
  101 + SecurityUser user = getCurrentUser();
  102 + if (user == null) {
  103 + return ResponseEntity.status(HttpStatus.FORBIDDEN).build();
112 } 104 }
  105 + HomePageAppDTO app =
  106 + homePageService.app(
  107 + login,
  108 + user.isPtSysadmin(),
  109 + user.isPtAdmin(),
  110 + user.isPtTenantAdmin(),
  111 + user.getTenantId(),
  112 + user.getCustomerId());
  113 + return ResponseEntity.ok(app);
  114 + }
113 } 115 }
@@ -16,5 +16,5 @@ public class UserSetting { @@ -16,5 +16,5 @@ public class UserSetting {
16 private String recordPath = null; 16 private String recordPath = null;
17 private Boolean streamOnDemand = Boolean.TRUE; 17 private Boolean streamOnDemand = Boolean.TRUE;
18 private Boolean sipUseSourceIpAsRemoteAddress = Boolean.FALSE; 18 private Boolean sipUseSourceIpAsRemoteAddress = Boolean.FALSE;
19 - private Integer playTimeout = 18000; 19 + private Integer playTimeout = 30000;
20 } 20 }
@@ -235,6 +235,23 @@ public interface FastIotConstants { @@ -235,6 +235,23 @@ public interface FastIotConstants {
235 String NODE = "NODE"; 235 String NODE = "NODE";
236 } 236 }
237 237
  238 + /**
  239 + * 首页统计分析指标
  240 + */
  241 + interface Statistics {
  242 + String TRANSPORT_MSG_COUNT_HOURLY = "transportMsgCountHourly";
  243 + String TRANSPORT_DATAPOINTS_COUNT_HOURLY = "transportDataPointsCountHourly";
  244 + String CREATED_ALARMS_COUNT_HOURLY = "createdAlarmsCountHourly";
  245 + String TRANSPORT_MSG_COUNT = "transportMsgCount";
  246 + String TRANSPORT_DATAPOINTS_COUNT = "transportDataPointsCount";
  247 + String CREATED_ALARMS_COUNT = "createdAlarmsCount";
  248 + }
  249 + /**
  250 + * 单位转换常量
  251 + */
  252 + interface Unit {
  253 + Long ONE_DAY_MILLISECONDS = 86400000L;
  254 + }
238 class DefaultOrder { 255 class DefaultOrder {
239 public static final String CREATE_TIME = "create_time"; 256 public static final String CREATE_TIME = "create_time";
240 } 257 }
1 package org.thingsboard.server.dao.yunteng.impl; 1 package org.thingsboard.server.dao.yunteng.impl;
2 2
  3 +import static org.thingsboard.server.dao.timeseries.AbstractCassandraBaseTimeseriesDao.DESC_ORDER;
  4 +
3 import com.google.common.util.concurrent.*; 5 import com.google.common.util.concurrent.*;
  6 +import java.time.*;
  7 +import java.time.format.DateTimeFormatter;
  8 +import java.time.temporal.TemporalAdjusters;
  9 +import java.util.*;
  10 +import java.util.concurrent.CompletableFuture;
  11 +import java.util.concurrent.ConcurrentHashMap;
  12 +import java.util.concurrent.ConcurrentMap;
  13 +import java.util.concurrent.ExecutionException;
  14 +import java.util.concurrent.atomic.AtomicInteger;
  15 +import java.util.concurrent.atomic.AtomicReference;
  16 +import java.util.stream.Collectors;
4 import lombok.RequiredArgsConstructor; 17 import lombok.RequiredArgsConstructor;
5 import org.apache.commons.lang3.StringUtils; 18 import org.apache.commons.lang3.StringUtils;
6 import org.checkerframework.checker.nullness.qual.Nullable; 19 import org.checkerframework.checker.nullness.qual.Nullable;
@@ -10,6 +23,7 @@ import org.springframework.web.context.request.async.DeferredResult; @@ -10,6 +23,7 @@ import org.springframework.web.context.request.async.DeferredResult;
10 import org.thingsboard.server.common.data.ApiUsageState; 23 import org.thingsboard.server.common.data.ApiUsageState;
11 import org.thingsboard.server.common.data.alarm.AlarmStatus; 24 import org.thingsboard.server.common.data.alarm.AlarmStatus;
12 import org.thingsboard.server.common.data.id.CustomerId; 25 import org.thingsboard.server.common.data.id.CustomerId;
  26 +import org.thingsboard.server.common.data.id.DeviceId;
13 import org.thingsboard.server.common.data.id.EntityId; 27 import org.thingsboard.server.common.data.id.EntityId;
14 import org.thingsboard.server.common.data.id.TenantId; 28 import org.thingsboard.server.common.data.id.TenantId;
15 import org.thingsboard.server.common.data.kv.Aggregation; 29 import org.thingsboard.server.common.data.kv.Aggregation;
@@ -26,25 +40,16 @@ import org.thingsboard.server.common.data.yunteng.enums.TrendType; @@ -26,25 +40,16 @@ import org.thingsboard.server.common.data.yunteng.enums.TrendType;
26 import org.thingsboard.server.common.data.yunteng.utils.tools.TkPageData; 40 import org.thingsboard.server.common.data.yunteng.utils.tools.TkPageData;
27 import org.thingsboard.server.dao.entity.EntityService; 41 import org.thingsboard.server.dao.entity.EntityService;
28 import org.thingsboard.server.dao.timeseries.TimeseriesService; 42 import org.thingsboard.server.dao.timeseries.TimeseriesService;
  43 +import org.thingsboard.server.dao.usagerecord.ApiUsageStateDao;
29 import org.thingsboard.server.dao.usagerecord.ApiUsageStateService; 44 import org.thingsboard.server.dao.usagerecord.ApiUsageStateService;
30 import org.thingsboard.server.dao.yunteng.mapper.DeviceMapper; 45 import org.thingsboard.server.dao.yunteng.mapper.DeviceMapper;
31 -import org.thingsboard.server.dao.yunteng.mapper.UserMapper;  
32 import org.thingsboard.server.dao.yunteng.mapper.TkAlarmMapper; 46 import org.thingsboard.server.dao.yunteng.mapper.TkAlarmMapper;
  47 +import org.thingsboard.server.dao.yunteng.mapper.UserMapper;
33 import org.thingsboard.server.dao.yunteng.service.HomePageService; 48 import org.thingsboard.server.dao.yunteng.service.HomePageService;
34 import org.thingsboard.server.dao.yunteng.service.TkDeviceProfileService; 49 import org.thingsboard.server.dao.yunteng.service.TkDeviceProfileService;
35 import org.thingsboard.server.dao.yunteng.service.TkTenantService; 50 import org.thingsboard.server.dao.yunteng.service.TkTenantService;
36 import org.thingsboard.server.dao.yunteng.service.TkUserService; 51 import org.thingsboard.server.dao.yunteng.service.TkUserService;
37 52
38 -import java.time.*;  
39 -import java.time.format.DateTimeFormatter;  
40 -import java.time.temporal.TemporalAdjusters;  
41 -import java.util.*;  
42 -import java.util.concurrent.CompletableFuture;  
43 -import java.util.concurrent.ExecutionException;  
44 -import java.util.concurrent.atomic.AtomicInteger;  
45 -import java.util.concurrent.atomic.AtomicReference;  
46 -import java.util.stream.Collectors;  
47 -  
48 @Service 53 @Service
49 @RequiredArgsConstructor 54 @RequiredArgsConstructor
50 public class TkHomePageServiceImpl implements HomePageService { 55 public class TkHomePageServiceImpl implements HomePageService {
@@ -58,7 +63,9 @@ public class TkHomePageServiceImpl implements HomePageService { @@ -58,7 +63,9 @@ public class TkHomePageServiceImpl implements HomePageService {
58 private final EntityService entityService; 63 private final EntityService entityService;
59 64
60 private final ApiUsageStateService apiUsageStateService; 65 private final ApiUsageStateService apiUsageStateService;
  66 + private final ApiUsageStateDao apiUsageStateDao;
61 67
  68 + /** 查询遥测数据,兼容多种数据库 */
62 private final TimeseriesService timeseriesService; 69 private final TimeseriesService timeseriesService;
63 70
64 private final TkUserService tkUserService; 71 private final TkUserService tkUserService;
@@ -81,41 +88,47 @@ public class TkHomePageServiceImpl implements HomePageService { @@ -81,41 +88,47 @@ public class TkHomePageServiceImpl implements HomePageService {
81 HomePageLeftTopDTO homePageLeftTopDTO = new HomePageLeftTopDTO(); 88 HomePageLeftTopDTO homePageLeftTopDTO = new HomePageLeftTopDTO();
82 HomeDeviceInfoDTO homeDeviceInfo; 89 HomeDeviceInfoDTO homeDeviceInfo;
83 LocalDateTime nowTime = LocalDateTime.now(); 90 LocalDateTime nowTime = LocalDateTime.now();
84 - LocalDateTime startTime = LocalDateTime.of(nowTime.toLocalDate(), LocalTime.MIN);  
85 - LocalDateTime endTime = LocalDateTime.of(nowTime.toLocalDate(), LocalTime.MAX); 91 + LocalDateTime todayBegin = LocalDateTime.of(nowTime.toLocalDate(), LocalTime.MIN);
  92 + LocalDateTime todayEnd = LocalDateTime.of(nowTime.toLocalDate(), LocalTime.MAX);
86 int zero = FastIotConstants.MagicNumber.ZERO; 93 int zero = FastIotConstants.MagicNumber.ZERO;
87 HomePageTopMessage messageInfo = new HomePageTopMessage(zero); 94 HomePageTopMessage messageInfo = new HomePageTopMessage(zero);
88 BaseHomePageTop alarm = new BaseHomePageTop(zero); 95 BaseHomePageTop alarm = new BaseHomePageTop(zero);
89 BaseHomePageTop product = new BaseHomePageTop(zero); 96 BaseHomePageTop product = new BaseHomePageTop(zero);
90 Map<String, Object> queryMap = new HashMap<>(); 97 Map<String, Object> queryMap = new HashMap<>();
  98 + TenantId currentTenantId = TenantId.fromUUID(UUID.fromString(tenantId));
91 String customerId = null; 99 String customerId = null;
92 List<DeviceDTO> deviceList; 100 List<DeviceDTO> deviceList;
93 if (isPtSysAdmin || isPtAdmin) { 101 if (isPtSysAdmin || isPtAdmin) {
94 - setTenantInfoData(homePageLeftTopDTO, startTime, endTime);  
95 - setCustomerInfoData(homePageLeftTopDTO, startTime, endTime); 102 + setTenantInfoData(homePageLeftTopDTO, todayBegin, todayEnd);
  103 + setCustomerInfoData(homePageLeftTopDTO, todayBegin, todayEnd);
96 } else if (isTenantAdmin) { 104 } else if (isTenantAdmin) {
97 queryMap.put("tenantId", tenantId); 105 queryMap.put("tenantId", tenantId);
98 - setAlarmAndMessageInfo(tenantId, messageInfo, alarm); 106 +
  107 + ApiUsageState apiUsageState = apiUsageStateService.findTenantApiUsageState(currentTenantId);
  108 + setAllAlarmAndMessageInfo(currentTenantId, apiUsageState.getId(), messageInfo, alarm);
  109 +
  110 + // 查询今日数据
  111 + setTodayAlarmAndMessageInfo(
  112 + todayBegin, todayEnd, currentTenantId, apiUsageState.getId(), messageInfo, alarm);
99 113
100 } else { 114 } else {
101 customerId = userMapper.findCustomerIdByUserId(currentUserId); 115 customerId = userMapper.findCustomerIdByUserId(currentUserId);
102 if (StringUtils.isNotEmpty(customerId)) { 116 if (StringUtils.isNotEmpty(customerId)) {
103 // 查询customerId 117 // 查询customerId
104 queryMap.put("customerId", customerId); 118 queryMap.put("customerId", customerId);
105 - long startTs = startTime.toInstant(ZoneOffset.of("+8")).toEpochMilli();  
106 - List<BaseHomePageTop> baseHomePageTopList =  
107 - deviceMapper.findDeviceMessageInfo(startTs, customerId);  
108 - if (baseHomePageTopList.size() > zero) {  
109 - BaseHomePageTop baseHomePageTop = baseHomePageTopList.get(0);  
110 - messageInfo.setMessageCount(baseHomePageTop.getSumCount());  
111 - messageInfo.setTodayMessageAdd(baseHomePageTop.getTodayAdd() ==null ? zero:baseHomePageTop.getTodayAdd()); 119 + List<String> tbDevices = deviceMapper.findDeviceIdsByCustomerId(customerId);
  120 + for (String devId : tbDevices) {
  121 + setCustomerMessageInfo(
  122 + todayBegin, todayEnd, currentTenantId, DeviceId.fromString(devId), messageInfo);
112 } 123 }
  124 + long startTs = todayBegin.toInstant(ZoneOffset.of("+8")).toEpochMilli();
113 List<BaseHomePageTop> alarmList = 125 List<BaseHomePageTop> alarmList =
114 deviceMapper.findDeviceAlarmInfoByCustomer(startTs, customerId); 126 deviceMapper.findDeviceAlarmInfoByCustomer(startTs, customerId);
115 if (alarmList.size() > zero) { 127 if (alarmList.size() > zero) {
116 BaseHomePageTop baseHomePageTop = alarmList.get(0); 128 BaseHomePageTop baseHomePageTop = alarmList.get(0);
117 alarm.setSumCount(baseHomePageTop.getSumCount()); 129 alarm.setSumCount(baseHomePageTop.getSumCount());
118 - alarm.setTodayAdd(baseHomePageTop.getTodayAdd() == null ? zero :baseHomePageTop.getTodayAdd()); 130 + alarm.setTodayAdd(
  131 + baseHomePageTop.getTodayAdd() == null ? zero : baseHomePageTop.getTodayAdd());
119 } 132 }
120 } 133 }
121 } 134 }
@@ -133,21 +146,21 @@ public class TkHomePageServiceImpl implements HomePageService { @@ -133,21 +146,21 @@ public class TkHomePageServiceImpl implements HomePageService {
133 if (StringUtils.isNotEmpty(customerId)) { 146 if (StringUtils.isNotEmpty(customerId)) {
134 deviceProfileDTOList = 147 deviceProfileDTOList =
135 tkDeviceProfileService.findCustomerDeviceProfiles( 148 tkDeviceProfileService.findCustomerDeviceProfiles(
136 - tenantId, new CustomerId(UUID.fromString(customerId)), null,null); 149 + tenantId, new CustomerId(UUID.fromString(customerId)), null, null);
137 } 150 }
138 } 151 }
139 int todayAdd = zero; 152 int todayAdd = zero;
140 - if (null !=deviceProfileDTOList && !deviceProfileDTOList.isEmpty()) { 153 + if (null != deviceProfileDTOList && !deviceProfileDTOList.isEmpty()) {
141 todayAdd = 154 todayAdd =
142 (int) 155 (int)
143 deviceProfileDTOList.stream() 156 deviceProfileDTOList.stream()
144 .filter( 157 .filter(
145 item -> 158 item ->
146 - item.getCreateTime().isAfter(startTime)  
147 - && item.getCreateTime().isBefore(endTime)) 159 + item.getCreateTime().isAfter(todayBegin)
  160 + && item.getCreateTime().isBefore(todayEnd))
148 .count(); 161 .count();
149 } 162 }
150 - product.setSumCount(null !=deviceProfileDTOList?deviceProfileDTOList.size():zero); 163 + product.setSumCount(null != deviceProfileDTOList ? deviceProfileDTOList.size() : zero);
151 product.setTodayAdd(todayAdd); 164 product.setTodayAdd(todayAdd);
152 homePageLeftTopDTO.setProductInfo(product); 165 homePageLeftTopDTO.setProductInfo(product);
153 } 166 }
@@ -334,10 +347,12 @@ public class TkHomePageServiceImpl implements HomePageService { @@ -334,10 +347,12 @@ public class TkHomePageServiceImpl implements HomePageService {
334 347
335 return filter; 348 return filter;
336 } 349 }
  350 +
337 /** 获取当前用户权限下的客户信息 */ 351 /** 获取当前用户权限下的客户信息 */
338 private List<UserDetailsDTO> getCustomerInfo(Map<String, Object> filter) { 352 private List<UserDetailsDTO> getCustomerInfo(Map<String, Object> filter) {
339 return userMapper.findCustomers(filter); 353 return userMapper.findCustomers(filter);
340 } 354 }
  355 +
341 /** 356 /**
342 * 查询实体ID的设备 357 * 查询实体ID的设备
343 * 358 *
@@ -380,7 +395,6 @@ public class TkHomePageServiceImpl implements HomePageService { @@ -380,7 +395,6 @@ public class TkHomePageServiceImpl implements HomePageService {
380 return statistics; 395 return statistics;
381 } 396 }
382 397
383 -  
384 @Override 398 @Override
385 public TkPageData<TenantDTO> getHomePageRightInfo(Map<String, Object> queryMap) { 399 public TkPageData<TenantDTO> getHomePageRightInfo(Map<String, Object> queryMap) {
386 return tenantService.getCurrentMonthExpireTenantPage(queryMap); 400 return tenantService.getCurrentMonthExpireTenantPage(queryMap);
@@ -388,52 +402,45 @@ public class TkHomePageServiceImpl implements HomePageService { @@ -388,52 +402,45 @@ public class TkHomePageServiceImpl implements HomePageService {
388 402
389 @Override 403 @Override
390 public DeferredResult<List<TkTsValue>> getHomePageLeftBottomInfo( 404 public DeferredResult<List<TkTsValue>> getHomePageLeftBottomInfo(
391 - String customerId, 405 + TenantId tenantId,
  406 + CustomerId customerId,
392 long startTs, 407 long startTs,
393 long endTs, 408 long endTs,
394 long interval, 409 long interval,
395 - TrendType trend,  
396 - boolean isCustomer) { 410 + TrendType trend) {
397 List<CompletableFuture<TkTsValue>> futures = new ArrayList<>(); 411 List<CompletableFuture<TkTsValue>> futures = new ArrayList<>();
398 long stepTs = startTs; 412 long stepTs = startTs;
399 boolean isYearQuery = false; 413 boolean isYearQuery = false;
400 - if((endTs - startTs)/86400000 >= 365){  
401 - isYearQuery =true; 414 + if ((endTs - startTs) / FastIotConstants.Unit.ONE_DAY_MILLISECONDS >= 365) {
  415 + isYearQuery = true;
402 } 416 }
403 while (stepTs < endTs) { 417 while (stepTs < endTs) {
404 - Long tempStartTs = stepTs; 418 + long tempStartTs = stepTs;
405 Long tempEndTs = stepTs + interval; 419 Long tempEndTs = stepTs + interval;
406 LocalDateTime startTime; 420 LocalDateTime startTime;
407 LocalDateTime endTime; 421 LocalDateTime endTime;
408 - if(isYearQuery){  
409 - //按月份过滤 422 + if (isYearQuery) {
  423 + // 按月份过滤
410 Instant instant = Instant.ofEpochMilli(tempStartTs); 424 Instant instant = Instant.ofEpochMilli(tempStartTs);
411 LocalDateTime dateTime = LocalDateTime.ofInstant(instant, ZoneId.systemDefault()); 425 LocalDateTime dateTime = LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
412 startTime = getMonthStartTime(dateTime); 426 startTime = getMonthStartTime(dateTime);
413 endTime = getNextMonthStartTime(dateTime); 427 endTime = getNextMonthStartTime(dateTime);
414 - }else{  
415 - //按聚合条件过滤  
416 - startTime =  
417 - LocalDateTime.ofEpochSecond(tempStartTs / 1000, 0, ZoneOffset.ofHours(8));  
418 - endTime =  
419 - LocalDateTime.ofEpochSecond(tempEndTs / 1000, 0, ZoneOffset.ofHours(8)); 428 + } else {
  429 + // 按聚合条件过滤
  430 + startTime = LocalDateTime.ofEpochSecond(tempStartTs / 1000, 0, ZoneOffset.ofHours(8));
  431 + endTime = LocalDateTime.ofEpochSecond(tempEndTs / 1000, 0, ZoneOffset.ofHours(8));
420 } 432 }
421 CompletableFuture<TkTsValue> tsValueCompletableFuture = null; 433 CompletableFuture<TkTsValue> tsValueCompletableFuture = null;
422 - // 客户查询的是告警统计 消息统计  
423 - if (isCustomer) {  
424 - String date = getDateByLocalTime(startTime,isYearQuery,true);  
425 - if (trend == TrendType.CUSTOMER_ALARM_STATISTICAL) {  
426 - tsValueCompletableFuture =  
427 - findDeviceInfoByTs(  
428 - customerId, tempStartTs, tempEndTs, date, TrendType.CUSTOMER_ALARM_STATISTICAL);  
429 - }  
430 - if (trend == TrendType.CUSTOMER_MESSAGE_STATISTICAL) {  
431 - tsValueCompletableFuture =  
432 - findDeviceInfoByTs(  
433 - customerId, tempStartTs, tempEndTs, date, TrendType.CUSTOMER_MESSAGE_STATISTICAL);  
434 - } 434 +
  435 + String date = getDateByLocalTime(startTime, isYearQuery, true);
  436 + if (trend == TrendType.CUSTOMER_MESSAGE_STATISTICAL) {
  437 + tsValueCompletableFuture =
  438 + findCusterMessageHistory(tenantId, customerId, startTime, endTime, date);
  439 + } else if (trend == TrendType.CUSTOMER_ALARM_STATISTICAL) {
  440 + tsValueCompletableFuture =
  441 + findCusterAlarmHistory(customerId.getId().toString(), tempStartTs, tempEndTs, date);
435 } else { 442 } else {
436 - String date = getDateByLocalTime(startTime,isYearQuery,false); 443 + date = getDateByLocalTime(startTime, isYearQuery, false);
437 if (trend == TrendType.TENANT_TREND) { 444 if (trend == TrendType.TENANT_TREND) {
438 tsValueCompletableFuture = tenantService.findTenantsByTs(startTime, endTime, date); 445 tsValueCompletableFuture = tenantService.findTenantsByTs(startTime, endTime, date);
439 } 446 }
@@ -445,7 +452,7 @@ public class TkHomePageServiceImpl implements HomePageService { @@ -445,7 +452,7 @@ public class TkHomePageServiceImpl implements HomePageService {
445 stepTs = tempEndTs; 452 stepTs = tempEndTs;
446 } 453 }
447 final DeferredResult<List<TkTsValue>> deferredResult = new DeferredResult<>(); 454 final DeferredResult<List<TkTsValue>> deferredResult = new DeferredResult<>();
448 - if (futures.size() > FastIotConstants.MagicNumber.ZERO) { 455 + if (!futures.isEmpty()) {
449 ListenableFuture<List<TkTsValue>> listenableFuture = 456 ListenableFuture<List<TkTsValue>> listenableFuture =
450 Futures.transform( 457 Futures.transform(
451 setFutures(futures), 458 setFutures(futures),
@@ -473,7 +480,7 @@ public class TkHomePageServiceImpl implements HomePageService { @@ -473,7 +480,7 @@ public class TkHomePageServiceImpl implements HomePageService {
473 futures.add(getTransportMessageByTenantId(tenantId, tenant.getName())); 480 futures.add(getTransportMessageByTenantId(tenantId, tenant.getName()));
474 }); 481 });
475 final DeferredResult<List<TenantTransportMessageDTO>> deferredResult = new DeferredResult<>(); 482 final DeferredResult<List<TenantTransportMessageDTO>> deferredResult = new DeferredResult<>();
476 - if (futures.size() > FastIotConstants.MagicNumber.ZERO) { 483 + if (!futures.isEmpty()) {
477 ListenableFuture<List<TenantTransportMessageDTO>> listenableFuture = 484 ListenableFuture<List<TenantTransportMessageDTO>> listenableFuture =
478 Futures.transform( 485 Futures.transform(
479 settableFuture(futures), 486 settableFuture(futures),
@@ -500,36 +507,32 @@ public class TkHomePageServiceImpl implements HomePageService { @@ -500,36 +507,32 @@ public class TkHomePageServiceImpl implements HomePageService {
500 @Async 507 @Async
501 public CompletableFuture<TenantTransportMessageDTO> getTransportMessageByTenantId( 508 public CompletableFuture<TenantTransportMessageDTO> getTransportMessageByTenantId(
502 TenantId tenantId, String tenantName) { 509 TenantId tenantId, String tenantName) {
503 - List<EntityKey> latestValues = new ArrayList<>();  
504 - latestValues.add(new EntityKey(EntityKeyType.TIME_SERIES, "transportMsgCount"));  
505 ApiUsageState apiUsageState = apiUsageStateService.findTenantApiUsageState(tenantId); 510 ApiUsageState apiUsageState = apiUsageStateService.findTenantApiUsageState(tenantId);
506 - PageData<EntityData> pageData =  
507 - queryEntityData(apiUsageState.getId(), tenantId, null, latestValues);  
508 - Map<EntityKeyType, Map<String, TsValue>> latest = pageData.getData().get(0).getLatest(); 511 + List<String> allKeys = new ArrayList<>();
  512 + allKeys.add(FastIotConstants.Statistics.TRANSPORT_MSG_COUNT);
  513 + ListenableFuture<List<TsKvEntry>> tsKvFuture =
  514 + queryAllTimescalDatas(apiUsageState.getId(), tenantId, allKeys, Aggregation.SUM);
  515 + ListenableFuture<Long> dataFuture = Futures.transform(
  516 + tsKvFuture,
  517 + result -> {
  518 + AtomicReference<Long> value = new AtomicReference<>(0L);
  519 + result.forEach(
  520 + tsKvEntry -> {
  521 + if (tsKvEntry.getLongValue().isPresent()) {
  522 + value.updateAndGet(v -> v + tsKvEntry.getLongValue().get());
  523 + }
  524 + });
  525 + return value.get();
  526 + },
  527 + MoreExecutors.directExecutor());
509 TenantTransportMessageDTO transportMessage = new TenantTransportMessageDTO(); 528 TenantTransportMessageDTO transportMessage = new TenantTransportMessageDTO();
510 - latest  
511 - .keySet()  
512 - .forEach(  
513 - item -> {  
514 - if (item.equals(EntityKeyType.TIME_SERIES)) {  
515 - Map<String, TsValue> tsValueMap = latest.get(item);  
516 - tsValueMap  
517 - .keySet()  
518 - .forEach(  
519 - mapKey -> {  
520 - Long value =  
521 - Long.valueOf(  
522 - tsValueMap.get(mapKey).getValue().isEmpty()  
523 - ? FastIotConstants.MagicNumber.ZERO + ""  
524 - : tsValueMap.get(mapKey).getValue());  
525 - if (mapKey.equals("transportMsgCount")) {  
526 - transportMessage.setName(tenantName);  
527 - transportMessage.setCount(value);  
528 - }  
529 - });  
530 - }  
531 - });  
532 - return CompletableFuture.supplyAsync(() -> transportMessage); 529 + transportMessage.setName(tenantName);
  530 + try {
  531 + transportMessage.setCount(dataFuture.get());
  532 + } catch (InterruptedException | ExecutionException e) {
  533 + throw new RuntimeException(e);
  534 + }
  535 + return CompletableFuture.supplyAsync(() -> transportMessage);
533 } 536 }
534 537
535 /** 538 /**
@@ -609,46 +612,6 @@ public class TkHomePageServiceImpl implements HomePageService { @@ -609,46 +612,6 @@ public class TkHomePageServiceImpl implements HomePageService {
609 } 612 }
610 613
611 /** 614 /**
612 - * 设置首页的告警和消息  
613 - *  
614 - * @param tenantId 租户ID  
615 - * @param messageInfo 消息  
616 - * @param alarm 告警  
617 - */  
618 - private void setAlarmAndMessageInfo(  
619 - String tenantId, HomePageTopMessage messageInfo, BaseHomePageTop alarm)  
620 - throws ExecutionException, InterruptedException {  
621 - List<String> dictionaries = new ArrayList<>();  
622 - String key= "transportMsgCount";  
623 - String key1= "transportDataPointsCount";  
624 - String key2= "createdAlarmsCount";  
625 - dictionaries.add(key);  
626 - dictionaries.add(key1);  
627 - dictionaries.add(key2);  
628 - //查询所有数据  
629 - List<KvDictionaryValueDTO> sumCount = deviceMapper.getMsgSumByTenantIdAndDictionary(tenantId,dictionaries);  
630 - if(!sumCount.isEmpty()){  
631 - for (KvDictionaryValueDTO kvDictionary : sumCount) {  
632 - if(Objects.equals(key,kvDictionary.getKey())){  
633 - messageInfo.setMessageCount(kvDictionary.getValue());  
634 - continue;  
635 - }  
636 - if(Objects.equals(key1,kvDictionary.getKey())){  
637 - messageInfo.setDataPointsCount(kvDictionary.getValue());  
638 - continue;  
639 - }  
640 - if(Objects.equals(key2,kvDictionary.getKey())){  
641 - alarm.setSumCount(kvDictionary.getValue());  
642 - }  
643 - }  
644 - }  
645 - TenantId currentTenantId = TenantId.fromUUID(UUID.fromString(tenantId));  
646 - ApiUsageState apiUsageState = apiUsageStateService.findTenantApiUsageState(currentTenantId);  
647 - // 查询今日数据  
648 - setTodayAlarmAndMessageInfo(currentTenantId, apiUsageState.getId(), messageInfo, alarm);  
649 - }  
650 -  
651 - /**  
652 * 设置今日告警和今日消息 615 * 设置今日告警和今日消息
653 * 616 *
654 * @param currentTenantId 当前租户 617 * @param currentTenantId 当前租户
@@ -659,29 +622,33 @@ public class TkHomePageServiceImpl implements HomePageService { @@ -659,29 +622,33 @@ public class TkHomePageServiceImpl implements HomePageService {
659 * @throws InterruptedException 异常 622 * @throws InterruptedException 异常
660 */ 623 */
661 private void setTodayAlarmAndMessageInfo( 624 private void setTodayAlarmAndMessageInfo(
  625 + LocalDateTime todayBegin,
  626 + LocalDateTime todayend,
662 TenantId currentTenantId, 627 TenantId currentTenantId,
663 EntityId apiUsageState, 628 EntityId apiUsageState,
664 HomePageTopMessage messageInfo, 629 HomePageTopMessage messageInfo,
665 BaseHomePageTop alarm) 630 BaseHomePageTop alarm)
666 throws ExecutionException, InterruptedException { 631 throws ExecutionException, InterruptedException {
667 - Map<String, Aggregation> queries = new HashMap<>();  
668 - queries.put("transportMsgCountHourly", Aggregation.SUM);  
669 - queries.put("transportDataPointsCountHourly", Aggregation.SUM);  
670 - queries.put("createdAlarmsCountHourly", Aggregation.SUM);  
671 -  
672 - List<TsKvEntry> tsKv = queryEntityTimeseries(apiUsageState, currentTenantId, queries); 632 + List<String> allKeys = new ArrayList<>();
  633 + allKeys.add(FastIotConstants.Statistics.TRANSPORT_MSG_COUNT_HOURLY);
  634 + allKeys.add(FastIotConstants.Statistics.TRANSPORT_DATAPOINTS_COUNT_HOURLY);
  635 + allKeys.add(FastIotConstants.Statistics.CREATED_ALARMS_COUNT_HOURLY);
  636 + List<TsKvEntry> tsKv =
  637 + queryTodayTimescalDatas(
  638 + todayBegin, todayend, apiUsageState, currentTenantId, allKeys, Aggregation.SUM)
  639 + .get();
673 tsKv.forEach( 640 tsKv.forEach(
674 tsKvEntry -> { 641 tsKvEntry -> {
675 if (tsKvEntry.getLongValue().isPresent()) { 642 if (tsKvEntry.getLongValue().isPresent()) {
676 int count = tsKvEntry.getLongValue().get().intValue(); 643 int count = tsKvEntry.getLongValue().get().intValue();
677 switch (tsKvEntry.getKey()) { 644 switch (tsKvEntry.getKey()) {
678 - case "transportMsgCountHourly": 645 + case FastIotConstants.Statistics.TRANSPORT_MSG_COUNT_HOURLY:
679 messageInfo.setTodayMessageAdd(count + messageInfo.getTodayMessageAdd()); 646 messageInfo.setTodayMessageAdd(count + messageInfo.getTodayMessageAdd());
680 break; 647 break;
681 - case "transportDataPointsCountHourly": 648 + case FastIotConstants.Statistics.TRANSPORT_DATAPOINTS_COUNT_HOURLY:
682 messageInfo.setTodayDataPointsAdd(count + messageInfo.getTodayDataPointsAdd()); 649 messageInfo.setTodayDataPointsAdd(count + messageInfo.getTodayDataPointsAdd());
683 break; 650 break;
684 - case "createdAlarmsCountHourly": 651 + case FastIotConstants.Statistics.CREATED_ALARMS_COUNT_HOURLY:
685 alarm.setTodayAdd(count + alarm.getTodayAdd()); 652 alarm.setTodayAdd(count + alarm.getTodayAdd());
686 break; 653 break;
687 default: 654 default:
@@ -690,6 +657,116 @@ public class TkHomePageServiceImpl implements HomePageService { @@ -690,6 +657,116 @@ public class TkHomePageServiceImpl implements HomePageService {
690 } 657 }
691 }); 658 });
692 } 659 }
  660 + /**
  661 + * 设置今日告警和今日消息
  662 + *
  663 + * @param currentTenantId 当前租户
  664 + * @param messageInfo 消息
  665 + * @param alarm 告警
  666 + * @throws ExecutionException 异常
  667 + * @throws InterruptedException 异常
  668 + */
  669 +
  670 + private void setAllAlarmAndMessageInfo(
  671 + TenantId currentTenantId,
  672 + EntityId apiUsageId,
  673 + HomePageTopMessage messageInfo,
  674 + BaseHomePageTop alarm) {
  675 + List<String> allKeys = new ArrayList<>();
  676 + allKeys.add(FastIotConstants.Statistics.TRANSPORT_MSG_COUNT);
  677 + allKeys.add(FastIotConstants.Statistics.TRANSPORT_DATAPOINTS_COUNT);
  678 + allKeys.add(FastIotConstants.Statistics.CREATED_ALARMS_COUNT);
  679 + ListenableFuture<List<TsKvEntry>> tsKvFuture =
  680 + queryAllTimescalDatas(apiUsageId, currentTenantId, allKeys, Aggregation.SUM);
  681 + Futures.transform(
  682 + tsKvFuture,
  683 + result -> {
  684 + result.forEach(
  685 + tsKvEntry -> {
  686 + if (tsKvEntry.getLongValue().isPresent()) {
  687 + int count = tsKvEntry.getLongValue().get().intValue();
  688 + switch (tsKvEntry.getKey()) {
  689 + case FastIotConstants.Statistics.TRANSPORT_MSG_COUNT:
  690 + messageInfo.setMessageCount(count + messageInfo.getMessageCount());
  691 + break;
  692 + case FastIotConstants.Statistics.TRANSPORT_DATAPOINTS_COUNT:
  693 + messageInfo.setDataPointsCount(count + messageInfo.getDataPointsCount());
  694 + break;
  695 + case FastIotConstants.Statistics.CREATED_ALARMS_COUNT:
  696 + alarm.setSumCount(count + alarm.getSumCount());
  697 + break;
  698 + default:
  699 + break;
  700 + }
  701 + }
  702 + });
  703 + return null;
  704 + },
  705 + MoreExecutors.directExecutor());
  706 + }
  707 +
  708 + private void setCustomerMessageInfo(
  709 + LocalDateTime todayBegin,
  710 + LocalDateTime todayend,
  711 + TenantId currentTenantId,
  712 + EntityId devId,
  713 + HomePageTopMessage messageInfo)
  714 + throws ExecutionException, InterruptedException {
  715 +
  716 + List<String> allKeys = deviceKeys(currentTenantId, devId).get();
  717 + if(allKeys == null || allKeys.isEmpty()){
  718 + return;
  719 + }
  720 + List<TsKvEntry> allTsKv =
  721 + queryAllTimescalDatas(devId, currentTenantId, allKeys, Aggregation.COUNT).get();
  722 + if(allTsKv != null){
  723 + allTsKv.forEach(
  724 + tsKvEntry -> {
  725 + if (tsKvEntry.getLongValue().isPresent()) {
  726 + int count = tsKvEntry.getLongValue().get().intValue();
  727 + messageInfo.setMessageCount(count + messageInfo.getMessageCount());
  728 + }
  729 + });
  730 + }
  731 + List<TsKvEntry> todayTsKv =
  732 + queryTodayTimescalDatas(
  733 + todayBegin, todayend, devId, currentTenantId, allKeys, Aggregation.COUNT)
  734 + .get();
  735 + if(todayTsKv != null){
  736 + todayTsKv.forEach(
  737 + tsKvEntry -> {
  738 + if (tsKvEntry.getLongValue().isPresent()) {
  739 + int count = tsKvEntry.getLongValue().get().intValue();
  740 + messageInfo.setTodayMessageAdd(count + messageInfo.getTodayMessageAdd());
  741 + }
  742 + });
  743 + }
  744 + }
  745 +
  746 + /**
  747 + * 获取设备的遥测指标
  748 + *
  749 + * @param tenantId 租户ID
  750 + * @param devId 设备ID
  751 + * @return
  752 + */
  753 + private ListenableFuture<List<String>> deviceKeys(TenantId tenantId, EntityId devId) {
  754 + List<EntityId> keyFilters = new ArrayList<>();
  755 + keyFilters.add(devId);
  756 + List<String> allKeys = timeseriesService.findAllKeysByEntityIds(tenantId, keyFilters);
  757 +
  758 + ListenableFuture<List<String>> keysFuture;
  759 + if (allKeys == null || allKeys.isEmpty()) {
  760 + keysFuture =
  761 + Futures.transform(
  762 + timeseriesService.findAllLatest(tenantId, devId),
  763 + latest -> latest.stream().map(TsKvEntry::getKey).collect(Collectors.toList()),
  764 + MoreExecutors.directExecutor());
  765 + } else {
  766 + keysFuture = Futures.immediateFuture(allKeys);
  767 + }
  768 + return keysFuture;
  769 + }
693 770
694 /** 771 /**
695 * 查询实体的运行数据 772 * 查询实体的运行数据
@@ -725,32 +802,53 @@ public class TkHomePageServiceImpl implements HomePageService { @@ -725,32 +802,53 @@ public class TkHomePageServiceImpl implements HomePageService {
725 } 802 }
726 803
727 /** 804 /**
728 - * 查询实体当天遥测数据的统计信息 805 + * 查询实体当天遥测数据的统计信息 统计流量信息
729 * 806 *
730 * @param entityId 实体ID,例如:设备、用户、流量统计等 807 * @param entityId 实体ID,例如:设备、用户、流量统计等
731 * @param currentTenantId 租户ID 808 * @param currentTenantId 租户ID
732 - * @param statics 统计内容,包括需要统计的指标名、数据聚合的算法 统计的时间区间、数据聚合的时间窗口、  
733 * @return 809 * @return
734 * @throws ExecutionException 810 * @throws ExecutionException
735 * @throws InterruptedException 811 * @throws InterruptedException
736 */ 812 */
737 - private List<TsKvEntry> queryEntityTimeseries(  
738 - EntityId entityId, TenantId currentTenantId, Map<String, Aggregation> statics) 813 + private ListenableFuture<List<TsKvEntry>> queryTodayTimescalDatas(
  814 + LocalDateTime todayBegin,
  815 + LocalDateTime todayend,
  816 + EntityId entityId,
  817 + TenantId currentTenantId,
  818 + List<String> keys,
  819 + Aggregation aggregation)
739 throws ExecutionException, InterruptedException { 820 throws ExecutionException, InterruptedException {
740 - long startTs =  
741 - LocalDateTime.of(LocalDateTime.now().toLocalDate(), LocalTime.MIN)  
742 - .toInstant(ZoneOffset.of("+8"))  
743 - .toEpochMilli();  
744 - long endTs = LocalDateTime.now().toInstant(ZoneOffset.of("+8")).toEpochMilli();  
745 - int interval = 7200000;  
746 - int limit = (int) ((endTs - startTs) / interval) + FastIotConstants.MagicNumber.ONE; 821 + long startTs = todayBegin.toInstant(ZoneOffset.of("+8")).toEpochMilli();
  822 + long endTs = todayend.toInstant(ZoneOffset.of("+8")).toEpochMilli();
  823 + int interval = (int) (endTs - startTs);
  824 + List<ReadTsKvQuery> queries = new ArrayList<>();
  825 + for (String key : keys) {
  826 + queries.add(
  827 + new BaseReadTsKvQuery(
  828 + key, startTs, endTs, interval, FastIotConstants.MagicNumber.ONE, aggregation));
  829 + }
  830 + return timeseriesService.findAll(currentTenantId, entityId, queries);
  831 + }
747 832
  833 + /**
  834 + * 查询实体累积的遥测数据的统计信息 统计流量信息
  835 + *
  836 + * @param apiUsageId 实体ID,例如:设备、用户、流量统计等
  837 + * @param currentTenantId 租户ID
  838 + * @return
  839 + * @throws ExecutionException
  840 + * @throws InterruptedException
  841 + */
  842 + private ListenableFuture<List<TsKvEntry>> queryAllTimescalDatas(
  843 + EntityId apiUsageId, TenantId currentTenantId, List<String> keys, Aggregation aggregation) {
  844 + /** 浏览信息统计 1、先从ApiUsageState获取entityId 2、查询流量统计 */
  845 + long startTs = 0;
  846 + long endTs = LocalDateTime.now().toInstant(ZoneOffset.of("+8")).toEpochMilli();
748 List<ReadTsKvQuery> queries = new ArrayList<>(); 847 List<ReadTsKvQuery> queries = new ArrayList<>();
749 - for (String key : statics.keySet()) {  
750 - queries.add(new BaseReadTsKvQuery(key, startTs, endTs, interval, limit, statics.get(key))); 848 + for (String key : keys) {
  849 + queries.add(new BaseReadTsKvQuery(key, startTs, endTs, endTs, 1, aggregation, DESC_ORDER));
751 } 850 }
752 - List<TsKvEntry> tsKv = timeseriesService.findAll(currentTenantId, entityId, queries).get();  
753 - return tsKv; 851 + return timeseriesService.findAll(currentTenantId, apiUsageId, queries);
754 } 852 }
755 853
756 /** 854 /**
@@ -766,14 +864,14 @@ public class TkHomePageServiceImpl implements HomePageService { @@ -766,14 +864,14 @@ public class TkHomePageServiceImpl implements HomePageService {
766 int sumCount = userList != null ? userList.size() : FastIotConstants.MagicNumber.ZERO; 864 int sumCount = userList != null ? userList.size() : FastIotConstants.MagicNumber.ZERO;
767 865
768 int todayAdd = FastIotConstants.MagicNumber.ZERO; 866 int todayAdd = FastIotConstants.MagicNumber.ZERO;
769 - if (userList != null && userList.size() > FastIotConstants.MagicNumber.ZERO) { 867 + if (userList != null && !userList.isEmpty()) {
770 todayAdd += 868 todayAdd +=
771 - userList.stream()  
772 - .filter(  
773 - userDTO ->  
774 - userDTO.getCreateTime().isAfter(startTime)  
775 - && userDTO.getCreateTime().isBefore(endTime))  
776 - .count(); 869 + (int) userList.stream()
  870 + .filter(
  871 + userDTO ->
  872 + userDTO.getCreateTime().isAfter(startTime)
  873 + && userDTO.getCreateTime().isBefore(endTime))
  874 + .count();
777 } 875 }
778 BaseHomePageTop baseHomePageTop = new BaseHomePageTop(sumCount, todayAdd); 876 BaseHomePageTop baseHomePageTop = new BaseHomePageTop(sumCount, todayAdd);
779 homePageLeftTopDTO.setCustomerInfo(baseHomePageTop); 877 homePageLeftTopDTO.setCustomerInfo(baseHomePageTop);
@@ -835,7 +933,7 @@ public class TkHomePageServiceImpl implements HomePageService { @@ -835,7 +933,7 @@ public class TkHomePageServiceImpl implements HomePageService {
835 @Override 933 @Override
836 public void onSuccess(@Nullable List<TenantTransportMessageDTO> values) { 934 public void onSuccess(@Nullable List<TenantTransportMessageDTO> values) {
837 // sort 935 // sort
838 - if (null != values && values.size() > FastIotConstants.MagicNumber.ZERO) { 936 + if (null != values && !values.isEmpty()) {
839 int length = values.size() - FastIotConstants.MagicNumber.ONE; 937 int length = values.size() - FastIotConstants.MagicNumber.ONE;
840 for (int i = FastIotConstants.MagicNumber.ZERO; i < length; i++) { 938 for (int i = FastIotConstants.MagicNumber.ZERO; i < length; i++) {
841 for (int j = FastIotConstants.MagicNumber.ZERO; j < length - i; j++) { 939 for (int j = FastIotConstants.MagicNumber.ZERO; j < length - i; j++) {
@@ -866,42 +964,90 @@ public class TkHomePageServiceImpl implements HomePageService { @@ -866,42 +964,90 @@ public class TkHomePageServiceImpl implements HomePageService {
866 }; 964 };
867 } 965 }
868 966
869 - private CompletableFuture<TkTsValue> findDeviceInfoByTs(  
870 - String customerId, Long startTs, Long endTs, String date, TrendType trend) {  
871 - Integer value;  
872 - if (trend == TrendType.CUSTOMER_MESSAGE_STATISTICAL) {  
873 - value = deviceMapper.findDeviceMessageInfoByTs(customerId, startTs, endTs);  
874 - } else {  
875 - value = deviceMapper.findDeviceAlarmInfoByCreatedTime(customerId, startTs, endTs); 967 + private final ConcurrentMap<String, DeviceId> customer = new ConcurrentHashMap<>();
  968 +
  969 + private CompletableFuture<TkTsValue> findCusterMessageHistory(
  970 + TenantId tenantId,
  971 + CustomerId customerId,
  972 + LocalDateTime todayBegin,
  973 + LocalDateTime todayend,
  974 + String dataKey) {
  975 + List<String> tbDeviceIds =
  976 + deviceMapper.findDeviceIdsByCustomerId(customerId.getId().toString());
  977 + AtomicReference<Integer> value = new AtomicReference<>(0);
  978 + if (tbDeviceIds == null || tbDeviceIds.isEmpty()){
  979 + return CompletableFuture.failedFuture(new NullPointerException());
876 } 980 }
  981 + tbDeviceIds.forEach(
  982 + id -> {
  983 + DeviceId deviceId = DeviceId.fromString(id);
  984 + try {
  985 + List<String> allKeys = deviceKeys(tenantId, deviceId).get();
  986 + if(allKeys == null || allKeys.isEmpty()){
  987 + return;
  988 + }
  989 + List<TsKvEntry> tempDatas =
  990 + queryTodayTimescalDatas(
  991 + todayBegin, todayend, deviceId, tenantId, allKeys, Aggregation.COUNT)
  992 + .get();
  993 + if(tempDatas == null){
  994 + return;
  995 + }
  996 + tempDatas.forEach(
  997 + item -> {
  998 + item.getLongValue()
  999 + .ifPresent(lv -> value.updateAndGet(v -> Math.toIntExact(v + lv)));
  1000 + });
  1001 + } catch (ExecutionException | InterruptedException e) {
  1002 + throw new RuntimeException(e);
  1003 + }
  1004 + });
  1005 +
  1006 + return CompletableFuture.supplyAsync(() -> new TkTsValue(dataKey, String.valueOf(value.get())));
  1007 + }
  1008 +
  1009 + private CompletableFuture<TkTsValue> findCusterAlarmHistory(
  1010 + String customerId, Long startTs, Long endTs, String date) {
  1011 + Integer value = deviceMapper.findDeviceAlarmInfoByCreatedTime(customerId, startTs, endTs);
877 return CompletableFuture.supplyAsync(() -> new TkTsValue(date, String.valueOf(value))); 1012 return CompletableFuture.supplyAsync(() -> new TkTsValue(date, String.valueOf(value)));
878 } 1013 }
879 1014
880 /** 1015 /**
881 * 获取本月的开始时间 1016 * 获取本月的开始时间
  1017 + *
882 * @param dateTime 本月时间 1018 * @param dateTime 本月时间
883 * @return 本月第一天时间 1019 * @return 本月第一天时间
884 */ 1020 */
885 - public LocalDateTime getMonthStartTime(LocalDateTime dateTime){ 1021 + public LocalDateTime getMonthStartTime(LocalDateTime dateTime) {
886 // 获取本月的第一天0点的时间戳 1022 // 获取本月的第一天0点的时间戳
887 - return dateTime.with(TemporalAdjusters.firstDayOfMonth()).withHour(0).withMinute(0).withSecond(0).withNano(0); 1023 + return dateTime
  1024 + .with(TemporalAdjusters.firstDayOfMonth())
  1025 + .withHour(0)
  1026 + .withMinute(0)
  1027 + .withSecond(0)
  1028 + .withNano(0);
888 } 1029 }
889 1030
890 /** 1031 /**
891 * 获取下个月的开始时间 1032 * 获取下个月的开始时间
  1033 + *
892 * @param dateTime 本月时间 1034 * @param dateTime 本月时间
893 * @return 下个月第一天时间 1035 * @return 下个月第一天时间
894 */ 1036 */
895 - public LocalDateTime getNextMonthStartTime(LocalDateTime dateTime){ 1037 + public LocalDateTime getNextMonthStartTime(LocalDateTime dateTime) {
896 // 获取下个月的第一天 1038 // 获取下个月的第一天
897 - LocalDateTime firstDayOfNextMonth = dateTime.with(TemporalAdjusters.firstDayOfNextMonth()).with(TemporalAdjusters.firstDayOfMonth()); 1039 + LocalDateTime firstDayOfNextMonth =
  1040 + dateTime
  1041 + .with(TemporalAdjusters.firstDayOfNextMonth())
  1042 + .with(TemporalAdjusters.firstDayOfMonth());
898 // 将时间设置为0点 1043 // 将时间设置为0点
899 return firstDayOfNextMonth.withHour(0).withMinute(0).withSecond(0).withNano(0); 1044 return firstDayOfNextMonth.withHour(0).withMinute(0).withSecond(0).withNano(0);
900 } 1045 }
901 1046
902 - public String getDateByLocalTime(LocalDateTime startTime,boolean isYearQuery,boolean isCustomer){  
903 - String format = isYearQuery ?"yyyy-MM":"yyyy-MM-dd";  
904 - format = isCustomer?"yyyy-MM-dd HH:mm:ss":format; 1047 + public String getDateByLocalTime(
  1048 + LocalDateTime startTime, boolean isYearQuery, boolean isCustomer) {
  1049 + String format = isYearQuery ? "yyyy-MM" : "yyyy-MM-dd";
  1050 + format = isCustomer ? "yyyy-MM-dd HH:mm:ss" : format;
905 DateTimeFormatter formatter = DateTimeFormatter.ofPattern(format); 1051 DateTimeFormatter formatter = DateTimeFormatter.ofPattern(format);
906 return startTime.format(formatter); 1052 return startTime.format(formatter);
907 } 1053 }
@@ -68,12 +68,14 @@ public interface DeviceMapper extends BaseMapper<TkDeviceEntity> { @@ -68,12 +68,14 @@ public interface DeviceMapper extends BaseMapper<TkDeviceEntity> {
68 List<DeviceDTO> findDeviceInfoByCustomerId( 68 List<DeviceDTO> findDeviceInfoByCustomerId(
69 @Param("tenantId") String tenantId, @Param("customerId") String customerId); 69 @Param("tenantId") String tenantId, @Param("customerId") String customerId);
70 70
  71 + @Deprecated
71 List<BaseHomePageTop> findDeviceMessageInfo( 72 List<BaseHomePageTop> findDeviceMessageInfo(
72 @Param("todayTime") Long todayTime, @Param("customerId") String customerId); 73 @Param("todayTime") Long todayTime, @Param("customerId") String customerId);
73 74
74 List<BaseHomePageTop> findDeviceAlarmInfoByCustomer( 75 List<BaseHomePageTop> findDeviceAlarmInfoByCustomer(
75 @Param("todayTime") Long todayTime, @Param("customerId") String customerId); 76 @Param("todayTime") Long todayTime, @Param("customerId") String customerId);
76 77
  78 + @Deprecated
77 Integer findDeviceMessageInfoByTs( 79 Integer findDeviceMessageInfoByTs(
78 @Param("customerId") String customerId, 80 @Param("customerId") String customerId,
79 @Param("startTime") Long startTime, 81 @Param("startTime") Long startTime,
@@ -144,6 +146,7 @@ public interface DeviceMapper extends BaseMapper<TkDeviceEntity> { @@ -144,6 +146,7 @@ public interface DeviceMapper extends BaseMapper<TkDeviceEntity> {
144 146
145 DeviceDTO findDeviceInfo(@Param("tenantId") String tenantId,@Param("tbDeviceId") String tbDeviceId); 147 DeviceDTO findDeviceInfo(@Param("tenantId") String tenantId,@Param("tbDeviceId") String tbDeviceId);
146 148
  149 + @Deprecated
147 List<KvDictionaryValueDTO> getMsgSumByTenantIdAndDictionary(@Param("tenantId") String tenantId, @Param("dictionaries")List<String> dictionaries); 150 List<KvDictionaryValueDTO> getMsgSumByTenantIdAndDictionary(@Param("tenantId") String tenantId, @Param("dictionaries")List<String> dictionaries);
148 151
149 List<DeviceDTO> findDevicesByOrganizationIds(@Param("orgIds")List<String> orgIds,@Param("deviceProfileIds") List<String> deviceProfileIds); 152 List<DeviceDTO> findDevicesByOrganizationIds(@Param("orgIds")List<String> orgIds,@Param("deviceProfileIds") List<String> deviceProfileIds);
1 package org.thingsboard.server.dao.yunteng.service; 1 package org.thingsboard.server.dao.yunteng.service;
2 2
  3 +import java.util.List;
  4 +import java.util.Map;
  5 +import java.util.concurrent.CompletableFuture;
  6 +import java.util.concurrent.ExecutionException;
3 import org.springframework.web.context.request.async.DeferredResult; 7 import org.springframework.web.context.request.async.DeferredResult;
  8 +import org.thingsboard.server.common.data.id.CustomerId;
4 import org.thingsboard.server.common.data.id.EntityId; 9 import org.thingsboard.server.common.data.id.EntityId;
5 import org.thingsboard.server.common.data.id.TenantId; 10 import org.thingsboard.server.common.data.id.TenantId;
6 import org.thingsboard.server.common.data.yunteng.dto.HomePageLeftTopDTO; 11 import org.thingsboard.server.common.data.yunteng.dto.HomePageLeftTopDTO;
@@ -11,77 +16,82 @@ import org.thingsboard.server.common.data.yunteng.dto.statistics.HomePageAppDTO; @@ -11,77 +16,82 @@ import org.thingsboard.server.common.data.yunteng.dto.statistics.HomePageAppDTO;
11 import org.thingsboard.server.common.data.yunteng.enums.TrendType; 16 import org.thingsboard.server.common.data.yunteng.enums.TrendType;
12 import org.thingsboard.server.common.data.yunteng.utils.tools.TkPageData; 17 import org.thingsboard.server.common.data.yunteng.utils.tools.TkPageData;
13 18
14 -import java.util.List;  
15 -import java.util.Map;  
16 -import java.util.concurrent.CompletableFuture;  
17 -import java.util.concurrent.ExecutionException;  
18 -  
19 public interface HomePageService { 19 public interface HomePageService {
20 - /**  
21 - * 通过租户ID获取首页左边顶部信息  
22 - *  
23 - * @param isPtSysAdmin 是否超级管理员  
24 - * @param isPtAdmin 是否平台管理员  
25 - * @param isTenantAdmin 是否租户管理员  
26 - * @param tenantId 租户ID  
27 - * @param currentUserId 当前用户ID  
28 - * @return 首页左边顶部信息  
29 - */  
30 - HomePageLeftTopDTO getHomePageLeftTopInfo(  
31 - boolean isPtSysAdmin,  
32 - boolean isPtAdmin,  
33 - boolean isTenantAdmin,  
34 - String tenantId,  
35 - String currentUserId)  
36 - throws ExecutionException, InterruptedException; 20 + /**
  21 + * 通过租户ID获取首页左边顶部信息
  22 + *
  23 + * @param isPtSysAdmin 是否超级管理员
  24 + * @param isPtAdmin 是否平台管理员
  25 + * @param isTenantAdmin 是否租户管理员
  26 + * @param tenantId 租户ID
  27 + * @param currentUserId 当前用户ID
  28 + * @return 首页左边顶部信息
  29 + */
  30 + HomePageLeftTopDTO getHomePageLeftTopInfo(
  31 + boolean isPtSysAdmin,
  32 + boolean isPtAdmin,
  33 + boolean isTenantAdmin,
  34 + String tenantId,
  35 + String currentUserId)
  36 + throws ExecutionException, InterruptedException;
37 37
38 - /**  
39 - * 获取首页右侧信息  
40 - *  
41 - * @param queryMap 查询条件  
42 - * @return 右侧信息  
43 - */  
44 - TkPageData<TenantDTO> getHomePageRightInfo(Map<String, Object> queryMap); 38 + /**
  39 + * 获取首页右侧信息
  40 + *
  41 + * @param queryMap 查询条件
  42 + * @return 右侧信息
  43 + */
  44 + TkPageData<TenantDTO> getHomePageRightInfo(Map<String, Object> queryMap);
45 45
46 - /**  
47 - * 获取首页左侧底部信息  
48 - *  
49 - * @param startTs 开始时间  
50 - * @param endTs 结束时间  
51 - * @param interval 时间间隔  
52 - * @param trend 趋势类型  
53 - * @return 左侧底部信息  
54 - */  
55 - DeferredResult<List<TkTsValue>> getHomePageLeftBottomInfo(  
56 - String customerId, long startTs, long endTs, long interval, TrendType trend, boolean isCustomer); 46 + /**
  47 + * 获取首页左侧底部历史数据
  48 + *
  49 + * @param startTs 开始时间
  50 + * @param endTs 结束时间
  51 + * @param interval 时间间隔,数据分片大小
  52 + * @param trend 趋势类型
  53 + * @return 左侧底部信息
  54 + */
  55 + DeferredResult<List<TkTsValue>> getHomePageLeftBottomInfo(
  56 + TenantId tenantId,
  57 + CustomerId customerId,
  58 + long startTs,
  59 + long endTs,
  60 + long interval,
  61 + TrendType trend);
57 62
58 - /**  
59 - * 获取首页TOP10  
60 - *  
61 - * @return top10  
62 - */  
63 - DeferredResult<List<TenantTransportMessageDTO>> getTop10(); 63 + /**
  64 + * 获取首页TOP10
  65 + *
  66 + * @return top10
  67 + */
  68 + DeferredResult<List<TenantTransportMessageDTO>> getTop10();
64 69
65 - /**  
66 - * 获取租户的传输信息  
67 - *  
68 - * @param tenantId 租户ID  
69 - * @param tenantName 租户姓名  
70 - * @return 传输信息  
71 - */  
72 - CompletableFuture<TenantTransportMessageDTO> getTransportMessageByTenantId(  
73 - TenantId tenantId, String tenantName); 70 + /**
  71 + * 获取租户的传输信息
  72 + *
  73 + * @param tenantId 租户ID
  74 + * @param tenantName 租户姓名
  75 + * @return 传输信息
  76 + */
  77 + CompletableFuture<TenantTransportMessageDTO> getTransportMessageByTenantId(
  78 + TenantId tenantId, String tenantName);
74 79
75 - /**  
76 - * app首页统计信息  
77 - * @param isPtSysAdmin  
78 - * @param isPtAdmin  
79 - * @param isTenantAdmin  
80 - * @param tenantId  
81 - * @param customerId  
82 - * @return  
83 - */  
84 - HomePageAppDTO app(Boolean login,boolean isPtSysAdmin, boolean isPtAdmin, boolean isTenantAdmin, EntityId tenantId, EntityId customerId); 80 + /**
  81 + * app首页统计信息
  82 + *
  83 + * @param isPtSysAdmin
  84 + * @param isPtAdmin
  85 + * @param isTenantAdmin
  86 + * @param tenantId
  87 + * @param customerId
  88 + * @return
  89 + */
  90 + HomePageAppDTO app(
  91 + Boolean login,
  92 + boolean isPtSysAdmin,
  93 + boolean isPtAdmin,
  94 + boolean isTenantAdmin,
  95 + EntityId tenantId,
  96 + EntityId customerId);
85 } 97 }
86 -  
87 -