change - 设备曲线

main
wenjy 3 years ago
parent 1934c78dd2
commit ef06745bd7

@ -1,14 +1,23 @@
package com.ruoyi.web.controller.record;
import com.alibaba.fastjson.JSONArray;
import com.ruoyi.common.core.text.Convert;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.domain.BaseSensorInfo;
import com.ruoyi.system.domain.dto.BaseSensorInfoDto;
import com.ruoyi.system.service.IBaseSensorInfoService;
import com.ruoyi.system.service.IRecordSensorDataService;
import lombok.Data;
import org.apache.commons.collections.MapUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.*;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;
/**
*
@ -22,14 +31,25 @@ public class RecordSensorDataController {
@Autowired private IRecordSensorDataService iRecordSensorDataService;
@Autowired
private IBaseSensorInfoService baseSensorInfoService;
private String prefix = "record/recordSensorData";
private SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
@GetMapping("/getPage")
public String recordSensorData(@RequestParam("id") String id, ModelMap mmap) {
mmap.put("sensorId", id);
return prefix + "/recordSensorData";
}
@GetMapping("/getTemperatureTrend")
public String getTemperatureTrend(@RequestParam("id") String id, ModelMap mmap){
mmap.put("sensorId", id);
return prefix + "/temperatureTrend";
}
@PostMapping("/list")
@ResponseBody
public String _getList(BaseSensorInfoDto baseSensorInfoDto) {
@ -59,7 +79,115 @@ public class RecordSensorDataController {
List<Map<String, Object>> maps =
iRecordSensorDataService.selectSensorDataList(baseSensorInfoDto);
return JSONArray.toJSONString(maps);
}
@PostMapping("/getTemperatureTrendJson")
@ResponseBody
public String getTemperatureTrendJson(BaseSensorInfoDto baseSensorInfoDto){
baseSensorInfoDto.setTableName("record_" + baseSensorInfoDto.getSensorType());
Date date = new Date();
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
calendar.add(Calendar.DATE, -3);
date = calendar.getTime();
Map<String, Object> paramMap = new HashMap<String, Object>();
if (baseSensorInfoDto.getBeginCollectTime() == null) {
paramMap.put("beginCollectTime", date);
} else {
paramMap.put("beginCollectTime", baseSensorInfoDto.getBeginCollectTime());
}
if (baseSensorInfoDto.getEndCollectTime() == null) {
paramMap.put("endCollectTime", new Date());
} else {
paramMap.put("endCollectTime", baseSensorInfoDto.getEndCollectTime());
}
baseSensorInfoDto.setParams(paramMap);
List<BaseSensorInfoDto> baseSensorInfoDtos = baseSensorInfoService.selectBaseSensorInfoList(new BaseSensorInfo(baseSensorInfoDto.getSensorId()));
List<BaseSensorInfoDto> baseSensorInfoDtos1 = baseSensorInfoService.selectBaseSensorInfoList(new BaseSensorInfo(null,null,null,baseSensorInfoDtos.get(0).getMonitorunitId()));
List<Map<String, Object>> maps = new ArrayList<>();
for (BaseSensorInfoDto sensorInfoDto : baseSensorInfoDtos1) {
baseSensorInfoDto.setSensorId(sensorInfoDto.getSensorId());
maps.addAll(maps.size(),iRecordSensorDataService.selectTemperatureList(baseSensorInfoDto));
}
Map<String, List<Map<String, Object>>> sensorId = maps.stream().collect(Collectors.groupingBy(m -> (m.get("sensorName").toString())));
List<String> legend = new ArrayList<>();
List<String> xAxis = new ArrayList<>();
List<Series> series = new ArrayList<>();
for (Map.Entry<String, List<Map<String, Object>>> entry : sensorId.entrySet()) {
String mapKey = entry.getKey();
List<Map<String, Object>> mapValue = entry.getValue();
legend.add(entry.getKey());
List<BigDecimal> data = new ArrayList<>();
for (Map<String, Object> map : entry.getValue()) {
xAxis.add(map.get("collectTime").toString());
data.add(Convert.toBigDecimal(map.get("value")));
}
series.add(new Series(entry.getKey(),"line","Total",data));
}
List<String> collect = xAxis.stream().distinct().collect(Collectors.toList());
String s = JSONArray.toJSONString(new Root(legend, collect, series));
System.out.println("曲线趋势数据格式打印:"+s);
return s;
}
}
@Data
class Root{
public Root() {
}
public Root(List<String> legend, List<String> xAxis, List<Series> series) {
this.legend = legend;
this.xAxis = xAxis;
this.series = series;
}
private List<String> legend;
private List<String> xAxis;
private List<Series> series;
}
@Data
class Series{
public Series() {
}
public Series(String name, String type, String stack, List<BigDecimal> data) {
this.name = name;
this.type = type;
this.stack = stack;
this.data = data;
}
private String name;
private String type;
private String stack;
private List<BigDecimal> data;
}

@ -49,7 +49,7 @@ const createDeviceModule = function (sensor,params) {
case "temperature":
html += `<div style="padding-left: 20px;padding-top: 10px;font-size: 105%;color: #00f9ff;width: 100%;height: 15%;;display: flex;flex-direction: column;justify-content: center;">${sensor.sensorName}</div>`;
html += '<div style="position: absolute;width: 98%;height: 65%;border-top: 1px dashed #1CA2E7;border-bottom: 1px dashed #1CA2E7;left:1%;overflow-x: hidden; overflow-y: auto;display: flex;flex-direction: column;justify-content: center;">';
html += '<div onclick="temperatureTrend(\''+sensor.sensorId+",temperature"+ '\')" style="position: absolute;width: 98%;height: 65%;border-top: 1px dashed #1CA2E7;border-bottom: 1px dashed #1CA2E7;left:1%;overflow-x: hidden; overflow-y: auto;display: flex;flex-direction: column;justify-content: center;">';
for (let i=0; i<params.length; i++) {
html += `<div style="padding-left: 20px;padding-top: 10px;font-size: 105%;color: #00f9ff;width: 100%;" id="${sensor.sensorId+params[i].paramTitle}">${params[i].paramText+""+(sensor[params[i].paramTitle] == null ? "-" : sensor[params[i].paramTitle])}</div>`;
}
@ -182,3 +182,16 @@ Date.prototype.format = function(fmt) {
}
return fmt;
}
//温度传感器折线图
const temperatureTrend = function (sensorId) {
Dialog({
title: "趋势分析",
width: 1100,
iframeContent: {
src: "/record/recordSensorData/getTemperatureTrend?id="+sensorId,
height: 600
},
showButton: false
});
}

@ -0,0 +1,314 @@
<!DOCTYPE html>
<html lang="zh" xmlns:th="http://www.thymeleaf.org" xmlns:shiro="http://www.pollix.at/thymeleaf/shiro">
<head>
<th:block th:include="include :: header('传感器数据趋势')"/>
</head>
<body class="gray-bg">
<div class="container-div">
<div class="row">
<div class="col-sm-12 search-collapse">
<form id="formId">
<div class="select-list">
<ul>
<li>
<input type="hidden" id="sensorId" name="sensorId"/>
</li>
<li class="select-time">
<label>采集时间:</label>
<input type="text" class="time-input" id="startTime" placeholder="开始时间"
name="beginCollectTime"/>
<span>-</span>
<input type="text" class="time-input" id="endTime" placeholder="结束时间"
name="endCollectTime"/>
</li>
<li>
<label>显示内容:</label>
<select id="optionStatus">
<!--<option value="0">所有</option>-->
<option value="temperatureTrend">趋势分析</option>
<option value="historyTable">历史数据</option>
</select>
</li>
<li>
<a class="btn btn-primary btn-rounded btn-sm" onclick="searchOnclick()"><i
class="fa fa-search"></i>&nbsp;搜索</a>
<a class="btn btn-warning btn-rounded btn-sm" onclick="$.form.reset()"><i
class="fa fa-refresh"></i>&nbsp;重置</a>
<a class="btn btn-warning btn-rounded btn-sm" onclick="exportData()">
<i class="fa fa-download"></i> 导出
</a>
</li>
</ul>
</div>
</form>
</div>
<div class="col-sm-12 select-table" style="height:400px" id="temperatureTrend">
<div style="width: 100%;height: 100%;" id="trendEcharts"></div>
</div>
<div class="col-sm-12 select-table table-striped" id="historyTable">
<table id="bootstrap-table"></table>
</div>
</div>
</div>
<th:block th:include="include :: footer"/>
<th:block th:include="include :: datetimepicker-js"/>
<!--表格导出-->
<th:block th:include="include :: bootstrap-table-export-js" />
<th:block th:include="include :: FileSaver-xlsx-Base64-js" />
<th:block th:include="include :: echarts-js" />
<script th:inline="javascript">
var prefix = ctx + "record/recordSensorData";
$(() => {
$("#historyTable").hide();
window.onload = function () {
document.getElementById('optionStatus').addEventListener('change',function(){
$("#temperatureTrend").hide();
$("#historyTable").hide();
$("#"+this.value).show();
},false);
}
tableRefresh();
temperatureTrend();
})
const searchOnclick = function(){
tableRefresh();
temperatureTrend();
}
/*曲线趋势*/
const temperatureTrend = function (){
let sensorId = [[${sensorId}]].split(",");
let formData = new FormData();
formData.append("sensorId", sensorId[0]);
formData.append("sensorType", sensorId[1]);
formData.append("beginCollectTime", $("#startTime").val());
formData.append("endCollectTime", $("#endTime").val());
$.ajax({
type: "post",
url: "/record/recordSensorData/getTemperatureTrendJson",
contentType: "application/json;charset=utf-8",
dataType: "json",
data: formData,
json: 'callback',
processData: false,
contentType: false,
success: function (json) {
lineCharts(json,document.getElementById("trendEcharts"));
},
error: function () {
alert("错误");
}
})
}
const tableRefresh = function () {
let sensorId = [[${sensorId}]].split(",");
let formData = new FormData();
formData.append("sensorId", sensorId[0]);
formData.append("sensorType", sensorId[1]);
formData.append("beginCollectTime", $("#startTime").val());
formData.append("endCollectTime", $("#endTime").val());
$.ajax({
type: "post",
url: "/record/recordSensorData/list",
contentType: "application/json;charset=utf-8",
dataType: "json",
data: formData,
json: 'callback',
processData: false,
contentType: false,
success: function (json) {
const sensorTypeArray = getparamsFunction(sensorId[1]);
const columnsArray = [];
if (sensorTypeArray.length > 0) {
columnsArray.push({
field: "uid",
title: "设备UID",
width: 160,
height: 60,
colspan: 1,
rowspan: 1,
align: "center"
});
columnsArray.push({
field: "sensorId",
title: "传感器编号",
width: 160,
height: 60,
colspan: 1,
rowspan: 1,
align: "center"
});
columnsArray.push({
field: "datatype",
title: "类型",
width: 160,
height: 60,
colspan: 1,
rowspan: 1,
align: "center"
});
if (json.length > 0) {
const jsonObj = Object.keys(json[0]);
for (let i = 0; i < jsonObj.length; i++) {//Object.keys(obj) key
let property = jsonObj[i];
if (property != "uid" && property != "sensorId" && property != "collectTime" && property != "datatype") {
columnsArray.push({
field: property,
title: typeof (sensorTypeArray.find(x => x.paramTitle.includes(property))) == "undefined" ? property : sensorTypeArray.find(x => x.paramTitle.includes(property)).paramText,
width: 140,
align: "center"
});
}
}
}
columnsArray.push({
field: "collectTime",
title: "采集时间",
width: 160,
height: 60,
colspan: 1,
rowspan: 1,
align: "center",
formatter: function(value, row, index) {
return value.replace("T"," ");
}
});
}
$('#bootstrap-table').bootstrapTable('destroy');
$('#bootstrap-table').bootstrapTable({
data: json,
striped: true,
cache: false,
pageNumber: 1,
pagination: true,
showColumns: true,
sidePagination: 'client',
pageSize: 10,
pageList: [5, 10, 15, 20, 25, 50],
showRefresh: true,
columns: columnsArray
});
columnsArray.push();
},
error: function () {
alert("错误");
}
})
}
const getparamsFunction = function (sensorTypeId) {
var returnData;
let formData = new FormData();
formData.append("sensorTypeId", sensorTypeId);
$.ajax({
type: "post",
url: "/base/sysParamConfig/getParameterNotVisibleFlag",
data: formData,
contentType: "application/json;charset=utf-8",
dataType: "json",
json: 'callback',
processData: false,
contentType: false,
async: false,
success: function (json) {
returnData = json;
},
error: function () {
alert("错误");
}
});
return returnData;
}
//echarts折线图
const lineCharts =function (res, id) {
let charts = echarts.init(id);
let options = {
tooltip: {
trigger: 'axis'
},
legend: {
data:res.legend
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true
},
toolbox: {
feature: {
saveAsImage: {}
}
},
xAxis: {
type: 'category',
boundaryGap: false,
data:res.xAxis
},
yAxis: {
type: 'value'
},
series: res.series
};
charts.setOption(options);
$(window).resize(charts.resize);
}
// 自定义按钮导出数据
function exportData(){
$('#bootstrap-table').tableExport({
type: 'excel',
exportDataType: "basic",
fileName: '历史数据报表',//下载文件名称
});
}
<!-- laydate示例 -->
layui.use('laydate', function () {
var laydate = layui.laydate;
laydate.render({
elem: '#startTime',
type: 'datetime',
trigger: 'click'
});
laydate.render({
elem: '#endTime',
type: 'datetime',
trigger: 'click'
});
});
</script>
</body>
</html>

@ -13,4 +13,6 @@ import java.util.Map;
public interface RecordSensorDataMapper {
List<Map<String, Object>> selectSensorDataList(BaseSensorInfoDto baseSensorInfoDto);
List<Map<String, Object>> selectTemperatureList(BaseSensorInfoDto baseSensorInfoDto);
}

@ -13,4 +13,6 @@ public interface IRecordSensorDataService {
List<Map<String, Object>> selectSensorDataList(BaseSensorInfoDto baseSensorInfoDto);
List<Map<String, Object>> selectTemperatureList(BaseSensorInfoDto baseSensorInfoDto);
}

@ -24,4 +24,9 @@ public class RecordSensorDataServiceImpl implements IRecordSensorDataService {
public List<Map<String, Object>> selectSensorDataList(BaseSensorInfoDto baseSensorInfoDto) {
return recordSensorDataMapper.selectSensorDataList(baseSensorInfoDto);
}
@Override
public List<Map<String, Object>> selectTemperatureList(BaseSensorInfoDto baseSensorInfoDto) {
return recordSensorDataMapper.selectTemperatureList(baseSensorInfoDto);
}
}

@ -36,5 +36,18 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
order by collectTime desc
</select>
<select id="selectTemperatureList" fetchSize="50000" parameterType="BaseSensorInfoDto" resultType="map">
select t1.sensorId,t2.Sensor_Name as sensorName,t1.value,DATE_FORMAT(t1.collectTime,'%Y-%m-%d %H:%i') as collectTime
from record_temperature t1
left join base_sensor_info t2 on t1.sensorId = t2.Sensor_Id
<where>
<if test="sensorId != null and sensorId != ''">and t1.sensorId = #{sensorId}</if>
<if test="params.beginCollectTime != null and params.endCollectTime != null ">and t1.collectTime between #{params.beginCollectTime} and #{params.endCollectTime}
</if>
</where>
group by DATE_FORMAT(t1.collectTime,'%Y-%m-%d %H:%i')
order by DATE_FORMAT(t1.collectTime,'%Y-%m-%d %H:%i') desc
</select>
</mapper>
Loading…
Cancel
Save