feat: 首页数据统计接口更新

V0.5.x
gaoyoulong 2024-04-10 15:36:11 +08:00
parent d456f41a1a
commit a0d2d820aa
6 changed files with 184 additions and 2 deletions

View File

@ -38,6 +38,25 @@ public interface IThingModelMessageData {
*/ */
List<TimeData> getDeviceMessageStatsWithUid(String uid, long start, long end); List<TimeData> getDeviceMessageStatsWithUid(String uid, long start, long end);
/**
*
* @param uid id
* @param start
* @param end
*/
List<TimeData> getDeviceUpMessageStatsWithUid(String uid, Long start, Long end);
/**
*
* @param uid id
* @param start
* @param end
*/
List<TimeData> getDeviceDownMessageStatsWithUid(String uid, Long start, Long end);
void add(ThingModelMessage msg); void add(ThingModelMessage msg);
long count(); long count();

View File

@ -16,6 +16,7 @@ import cc.iotkit.model.stats.TimeData;
import cc.iotkit.temporal.IThingModelMessageData; import cc.iotkit.temporal.IThingModelMessageData;
import cc.iotkit.temporal.es.dao.ThingModelMessageRepository; import cc.iotkit.temporal.es.dao.ThingModelMessageRepository;
import cc.iotkit.temporal.es.document.DocThingModelMessage; import cc.iotkit.temporal.es.document.DocThingModelMessage;
import cn.hutool.core.util.ObjectUtil;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.elasticsearch.index.query.BoolQueryBuilder; import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders; import org.elasticsearch.index.query.QueryBuilders;
@ -28,6 +29,7 @@ import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort; import org.springframework.data.domain.Sort;
import org.springframework.data.elasticsearch.core.ElasticsearchAggregations; import org.springframework.data.elasticsearch.core.ElasticsearchAggregations;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate; import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.SearchHit;
import org.springframework.data.elasticsearch.core.SearchHits; import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery; import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder; import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
@ -100,6 +102,92 @@ public class ThingModelMessageDataImpl implements IThingModelMessageData {
return data; return data;
} }
@Override
public List<TimeData> getDeviceUpMessageStatsWithUid(String uid, Long start, Long end) {
BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();
if (ObjectUtil.isNotEmpty(start) && ObjectUtil.isNotEmpty(end)) {
queryBuilder.must(QueryBuilders.rangeQuery("time")
.from(start, true).to(end, true));
}
if ( ObjectUtil.isNotEmpty(uid) ) {
queryBuilder =
queryBuilder.must(QueryBuilders.termQuery("uid", uid));
}
// 查询字段type='property' and identifier='report', 或者 type='event' 的数据
queryBuilder = queryBuilder.must(QueryBuilders.boolQuery()
.should(QueryBuilders.boolQuery()
.must(QueryBuilders.termQuery("type", "property"))
.must(QueryBuilders.termQuery("identifier", "report")))
.should(QueryBuilders.termQuery("type", "event")));
NativeSearchQuery query = new NativeSearchQueryBuilder()
.withQuery(queryBuilder)
.withAggregations(AggregationBuilders.dateHistogram("agg")
.field("time")
.calendarInterval(DateHistogramInterval.HOUR)
.calendarInterval(DateHistogramInterval.hours(1))
)
.build();
ElasticsearchAggregations result = (ElasticsearchAggregations) template
.search(query, DocThingModelMessage.class).getAggregations();
ParsedDateHistogram histogram = result.aggregations().get("agg");
List<TimeData> data = new ArrayList<>();
for (Histogram.Bucket bucket : histogram.getBuckets()) {
long seconds = ((ZonedDateTime) bucket.getKey()).toInstant().getEpochSecond();
data.add(new TimeData(seconds * 1000, bucket.getDocCount()));
}
return data;
}
@Override
public List<TimeData> getDeviceDownMessageStatsWithUid(String uid, Long start, Long end) {
BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();
if (ObjectUtil.isNotEmpty(start) && ObjectUtil.isNotEmpty(end)) {
queryBuilder.must(QueryBuilders.rangeQuery("time")
.from(start, true).to(end, true));
}
if ( ObjectUtil.isNotEmpty(uid) ) {
queryBuilder =
queryBuilder.must(QueryBuilders.termQuery("uid", uid));
}
// 查询字段type='property' and identifie!='report', 或者 type='service' 或者 type= 'config'
queryBuilder = queryBuilder.must(QueryBuilders.boolQuery()
.should(QueryBuilders.boolQuery()
.must(QueryBuilders.termQuery("type", "property"))
.must(QueryBuilders.boolQuery()
.mustNot(QueryBuilders.termQuery("identifier", "report"))))
.should(QueryBuilders.termQuery("type", "service"))
.should(QueryBuilders.termQuery("type", "config")));
NativeSearchQuery query = new NativeSearchQueryBuilder()
.withQuery(queryBuilder)
.withAggregations(AggregationBuilders.dateHistogram("agg")
.field("time")
.calendarInterval(DateHistogramInterval.HOUR)
.calendarInterval(DateHistogramInterval.hours(1))
)
.build();
ElasticsearchAggregations result = (ElasticsearchAggregations) template
.search(query, DocThingModelMessage.class).getAggregations();
ParsedDateHistogram histogram = result.aggregations().get("agg");
List<TimeData> data = new ArrayList<>();
for (Histogram.Bucket bucket : histogram.getBuckets()) {
long seconds = ((ZonedDateTime) bucket.getKey()).toInstant().getEpochSecond();
data.add(new TimeData(seconds * 1000, bucket.getDocCount()));
}
return data;
}
@Override @Override
public void add(ThingModelMessage msg) { public void add(ThingModelMessage msg) {
thingModelMessageRepository.save(MapstructUtils.convert(msg, DocThingModelMessage.class)); thingModelMessageRepository.save(MapstructUtils.convert(msg, DocThingModelMessage.class));

View File

@ -33,6 +33,16 @@ public class ThingModelMessageDataImpl implements IThingModelMessageData {
return new ArrayList<>(); return new ArrayList<>();
} }
@Override
public List<TimeData> getDeviceUpMessageStatsWithUid(String uid, Long start, Long end) {
return null;
}
@Override
public List<TimeData> getDeviceDownMessageStatsWithUid(String uid, Long start, Long end) {
return null;
}
@Override @Override
public void add(ThingModelMessage msg) { public void add(ThingModelMessage msg) {
} }

View File

@ -16,6 +16,7 @@ import cc.iotkit.model.stats.TimeData;
import cc.iotkit.temporal.IThingModelMessageData; import cc.iotkit.temporal.IThingModelMessageData;
import cc.iotkit.temporal.td.dao.TdTemplate; import cc.iotkit.temporal.td.dao.TdTemplate;
import cc.iotkit.temporal.td.model.TbThingModelMessage; import cc.iotkit.temporal.td.model.TbThingModelMessage;
import cn.hutool.core.util.ObjectUtil;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.BeanPropertyRowMapper; import org.springframework.jdbc.core.BeanPropertyRowMapper;
@ -89,6 +90,56 @@ public class ThingModelMessageDataImpl implements IThingModelMessageData {
return tdTemplate.query(sql, new BeanPropertyRowMapper<>(TimeData.class), args.toArray()); return tdTemplate.query(sql, new BeanPropertyRowMapper<>(TimeData.class), args.toArray());
} }
@Override
public List<TimeData> getDeviceUpMessageStatsWithUid(String uid, Long start, Long end) {
String sql = "select time,count(*) as data from(" +
"select TIMETRUNCATE(time,1h) as time from thing_model_message " +
"where (type='property' and identifier='report') or type='event' ";
StringBuilder sqlBuffer = new StringBuilder();
sqlBuffer.append(sql);
List<Object> args = new ArrayList<>();
if (ObjectUtil.isNotEmpty(uid)) {
sqlBuffer.append(" and uid=?");
args.add(uid);
}
if (ObjectUtil.isNotEmpty(start) && ObjectUtil.isNotEmpty(end)) {
sqlBuffer.append(" and time>=? and time<=?");
args.add(start);
args.add(end);
}
sqlBuffer.append(") a group by time order by time asc");
return tdTemplate.query(sqlBuffer.toString(), new BeanPropertyRowMapper<>(TimeData.class), args.toArray());
}
@Override
public List<TimeData> getDeviceDownMessageStatsWithUid(String uid, Long start, Long end) {
String sql = "select time,count(*) as data from(" +
"select TIMETRUNCATE(time,1h) as time from thing_model_message " +
"where (type='property' and identifier!='report') or type='service' or type= 'config' ";
StringBuilder sqlBuffer = new StringBuilder();
sqlBuffer.append(sql);
List<Object> args = new ArrayList<>();
if (ObjectUtil.isNotEmpty(uid)) {
sqlBuffer.append(" and uid=?");
args.add(uid);
}
if (ObjectUtil.isNotEmpty(start) && ObjectUtil.isNotEmpty(end)) {
sqlBuffer.append(" and time>=? and time<=?");
args.add(start);
args.add(end);
}
sqlBuffer.append(") a group by time order by time asc");
return tdTemplate.query(sqlBuffer.toString(), new BeanPropertyRowMapper<>(TimeData.class), args.toArray());
}
@Override @Override
public void add(ThingModelMessage msg) { public void add(ThingModelMessage msg) {
//使用deviceId作表名 //使用deviceId作表名

View File

@ -66,8 +66,10 @@ public class StatsController {
mainStats.setNeverOnlineTotal(deviceInfoData.findNeverUsedDevices().size()); mainStats.setNeverOnlineTotal(deviceInfoData.findNeverUsedDevices().size());
mainStats.setReportTotal(thingModelMessageData.count()); mainStats.setReportTotal(thingModelMessageData.count());
//上报数据统计 //上行数据统计
mainStats.setReportDataStats(thingModelMessageData.getDeviceMessageStatsWithUid(null, now - 48 * 3600 * 1000, now)); mainStats.setDeviceUpMessageStats(thingModelMessageData.getDeviceUpMessageStatsWithUid(null, null, null));
// 下行数据统计
mainStats.setDeviceDownMessageStats(thingModelMessageData.getDeviceDownMessageStatsWithUid(null, null, null));
//产品数量统计 //产品数量统计
mainStats.setDeviceStatsOfCategory(deviceInfoData.getDeviceStatsByCategory("")); mainStats.setDeviceStatsOfCategory(deviceInfoData.getDeviceStatsByCategory(""));
} else { } else {

View File

@ -61,6 +61,18 @@ public class MainStats {
*/ */
private List<TimeData> reportDataStats; private List<TimeData> reportDataStats;
/**
*
*/
private List<TimeData> deviceUpMessageStats;
/**
*
*/
private List<TimeData> deviceDownMessageStats;
/** /**
* *
*/ */