|
@@ -14,18 +14,22 @@ import com.sckj.iron.service.impl.*;
|
|
|
import com.sckj.iron.validate.IronLoginValidate;
|
|
|
import com.sckj.iron.validate.TIronDataSearchScreenValidate;
|
|
|
import com.sckj.iron.vo.IronLoginVo;
|
|
|
+import com.sckj.l2.dto.L2Properties;
|
|
|
import com.sckj.l2.dto.TL2DataDTO;
|
|
|
import com.sckj.l2.dto.TrendDTO;
|
|
|
import com.sckj.l2.dto.TrendRequest;
|
|
|
import com.sckj.l2.entity.TL2Data;
|
|
|
import com.sckj.l2.service.impl.TL2DataServiceImpl;
|
|
|
+import com.sckj.opc.entity.OPCData;
|
|
|
import com.sckj.opc.service.OPCDataServiceImpl;
|
|
|
import com.sckj.warn.dto.WarnDTO;
|
|
|
import com.sckj.warn.service.impl.TExceptionLogServiceImpl;
|
|
|
import io.swagger.annotations.Api;
|
|
|
import io.swagger.annotations.ApiOperation;
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
import org.apache.commons.lang3.ObjectUtils;
|
|
|
import org.springframework.beans.BeanUtils;
|
|
|
+import org.springframework.beans.factory.annotation.Autowired;
|
|
|
import org.springframework.validation.annotation.Validated;
|
|
|
import org.springframework.web.bind.annotation.PostMapping;
|
|
|
import org.springframework.web.bind.annotation.RequestBody;
|
|
@@ -36,7 +40,10 @@ import javax.annotation.Resource;
|
|
|
import javax.servlet.http.HttpServletRequest;
|
|
|
import javax.servlet.http.HttpServletResponse;
|
|
|
import java.io.IOException;
|
|
|
-import java.util.List;
|
|
|
+import java.text.SimpleDateFormat;
|
|
|
+import java.util.*;
|
|
|
+import java.util.concurrent.CompletableFuture;
|
|
|
+import java.util.concurrent.ExecutionException;
|
|
|
import java.util.stream.Collectors;
|
|
|
import java.util.stream.Stream;
|
|
|
|
|
@@ -45,6 +52,7 @@ import java.util.stream.Stream;
|
|
|
* @Date 2024-11-18 上午 09:44
|
|
|
* @Description 可视化大屏登录
|
|
|
*/
|
|
|
+@Slf4j
|
|
|
@RestController
|
|
|
@RequestMapping("api/visualscreen")
|
|
|
@Api(tags = "可视化大屏")
|
|
@@ -75,6 +83,8 @@ public class TIronVisualScreenController {
|
|
|
TIronTestServiceImpl iTIronTestService;
|
|
|
|
|
|
private static final int DATA_COUNT = 6;
|
|
|
+ @Autowired
|
|
|
+ private L2Properties l2Properties;
|
|
|
|
|
|
@NotLogin
|
|
|
@PostMapping("/login")
|
|
@@ -278,5 +288,212 @@ public class TIronVisualScreenController {
|
|
|
return AjaxResult.success(one);
|
|
|
}
|
|
|
|
|
|
+ @NotPower
|
|
|
+ @PostMapping("/getIronTrends")
|
|
|
+ @ApiOperation(value = "获取趋势所有数据")
|
|
|
+ public AjaxResult getIronTrends(@RequestBody TrendRequest queryDateType) {
|
|
|
+ // 1. 计算起止时间
|
|
|
+ int hours = queryDateType.getQueryDateType();
|
|
|
+ java.util.Date endTime = new java.util.Date();
|
|
|
+ java.util.Calendar cal = java.util.Calendar.getInstance();
|
|
|
+ cal.setTime(endTime);
|
|
|
+ cal.add(java.util.Calendar.HOUR_OF_DAY, -hours);
|
|
|
+ java.util.Date startTime = cal.getTime();
|
|
|
+
|
|
|
+ // 2. 异步查询所有数据
|
|
|
+ CompletableFuture<List<OPCData>> opcDataFuture = CompletableFuture.supplyAsync(() ->
|
|
|
+ opcDataService.lambdaQuery()
|
|
|
+ .in(OPCData::getPointName, Arrays.asList(
|
|
|
+ "BF4_1_IRONNOTCH_MIR_TEMP", // 温度
|
|
|
+ "BF4_1_IRONNOTCH_RAILLINE_ACPIRON_SPEED1", // 1车流速
|
|
|
+ "BF4_1_IRONNOTCH_RAILLINE_ACPIRON_SPEED2", // 2车流速
|
|
|
+ "BF4_1TH_2_TPC_TWT", // 1车铁水重量
|
|
|
+ "BF4_1TH_1_TPC_TWT" // 2车铁水重量
|
|
|
+ ))
|
|
|
+ .between(OPCData::getServerTime, startTime, endTime)
|
|
|
+ .orderByAsc(OPCData::getServerTime)
|
|
|
+ .list()
|
|
|
+ );
|
|
|
+
|
|
|
+ CompletableFuture<List<TL2Data>> l2DataFuture = CompletableFuture.supplyAsync(() ->
|
|
|
+ tl2DataService.lambdaQuery()
|
|
|
+ .between(TL2Data::getIronStarttime,
|
|
|
+ new SimpleDateFormat("yyyyMMddHHmmss").format(startTime),
|
|
|
+ new SimpleDateFormat("yyyyMMddHHmmss").format(endTime))
|
|
|
+ .orderByAsc(TL2Data::getIronStarttime)
|
|
|
+ .list()
|
|
|
+ );
|
|
|
+
|
|
|
+ // 3. 等待所有查询完成并转换数据
|
|
|
+ try {
|
|
|
+ CompletableFuture.allOf(opcDataFuture, l2DataFuture).join();
|
|
|
+
|
|
|
+ // 4. 按pointName分类OPC数据并转换为DTO
|
|
|
+ try {
|
|
|
+ Map<String, List<OPCData>> opcDataMap = opcDataFuture.get().stream()
|
|
|
+ .collect(Collectors.groupingBy(OPCData::getPointName));
|
|
|
+
|
|
|
+ List<TL2Data> l2DataList = l2DataFuture.get();
|
|
|
+
|
|
|
+ // 并行转换所有数据
|
|
|
+ CompletableFuture<List<IronTrendL1DTO>> tempListFuture = CompletableFuture.supplyAsync(() ->
|
|
|
+ opcDataMap.getOrDefault("BF4_1_IRONNOTCH_MIR_TEMP", new ArrayList<>())
|
|
|
+ .stream().map(item -> {
|
|
|
+ IronTrendL1DTO dto = new IronTrendL1DTO();
|
|
|
+ dto.setData(item.getData());
|
|
|
+ dto.setCreateTime(item.getSourceTime());
|
|
|
+ return dto;
|
|
|
+ }).collect(Collectors.toList())
|
|
|
+ );
|
|
|
+
|
|
|
+ CompletableFuture<List<IronTrendL1DTO>> speed1ListFuture = CompletableFuture.supplyAsync(() ->
|
|
|
+ opcDataMap.getOrDefault("BF4_1_IRONNOTCH_RAILLINE_ACPIRON_SPEED1", new ArrayList<>())
|
|
|
+ .stream().map(item -> {
|
|
|
+ IronTrendL1DTO dto = new IronTrendL1DTO();
|
|
|
+ dto.setData(item.getData());
|
|
|
+ dto.setCreateTime(item.getSourceTime());
|
|
|
+ return dto;
|
|
|
+ }).collect(Collectors.toList())
|
|
|
+ );
|
|
|
+
|
|
|
+ CompletableFuture<List<IronTrendL1DTO>> speed2ListFuture = CompletableFuture.supplyAsync(() ->
|
|
|
+ opcDataMap.getOrDefault("BF4_1_IRONNOTCH_RAILLINE_ACPIRON_SPEED2", new ArrayList<>())
|
|
|
+ .stream().map(item -> {
|
|
|
+ IronTrendL1DTO dto = new IronTrendL1DTO();
|
|
|
+ dto.setData(item.getData());
|
|
|
+ dto.setCreateTime(item.getSourceTime());
|
|
|
+ return dto;
|
|
|
+ }).collect(Collectors.toList())
|
|
|
+ );
|
|
|
+
|
|
|
+ CompletableFuture<List<IronTrendL1DTO>> weight1ListFuture = CompletableFuture.supplyAsync(() ->
|
|
|
+ opcDataMap.getOrDefault("BF4_1TH_2_TPC_TWT", new ArrayList<>())
|
|
|
+ .stream().map(item -> {
|
|
|
+ IronTrendL1DTO dto = new IronTrendL1DTO();
|
|
|
+ dto.setData(item.getData());
|
|
|
+ dto.setCreateTime(item.getSourceTime());
|
|
|
+ return dto;
|
|
|
+ }).collect(Collectors.toList())
|
|
|
+ );
|
|
|
+
|
|
|
+ CompletableFuture<List<IronTrendL1DTO>> weight2ListFuture = CompletableFuture.supplyAsync(() ->
|
|
|
+ opcDataMap.getOrDefault("BF4_1TH_1_TPC_TWT", new ArrayList<>())
|
|
|
+ .stream().map(item -> {
|
|
|
+ IronTrendL1DTO dto = new IronTrendL1DTO();
|
|
|
+ dto.setData(item.getData());
|
|
|
+ dto.setCreateTime(item.getSourceTime());
|
|
|
+ return dto;
|
|
|
+ }).collect(Collectors.toList())
|
|
|
+ );
|
|
|
+
|
|
|
+ CompletableFuture<List<IronTrendL2DTO>> elemenListFuture = CompletableFuture.supplyAsync(() ->
|
|
|
+ l2DataList.stream().map(item -> {
|
|
|
+ IronTrendL2DTO dto = new IronTrendL2DTO();
|
|
|
+ try {
|
|
|
+ dto.setElementS(item.getElementS() != null ? Double.parseDouble(item.getElementS()) : null);
|
|
|
+ } catch (NumberFormatException e) {
|
|
|
+ dto.setElementS(null);
|
|
|
+ }
|
|
|
+ try {
|
|
|
+ dto.setElementSi(item.getElementSi() != null ? Double.parseDouble(item.getElementSi()) : null);
|
|
|
+ } catch (NumberFormatException e) {
|
|
|
+ dto.setElementSi(null);
|
|
|
+ }
|
|
|
+ dto.setCreateTime(item.getIronStarttime());
|
|
|
+ return dto;
|
|
|
+ }).collect(Collectors.toList())
|
|
|
+ );
|
|
|
+
|
|
|
+ // 等待所有转换完成
|
|
|
+ CompletableFuture.allOf(
|
|
|
+ tempListFuture,
|
|
|
+ speed1ListFuture,
|
|
|
+ speed2ListFuture,
|
|
|
+ weight1ListFuture,
|
|
|
+ weight2ListFuture,
|
|
|
+ elemenListFuture
|
|
|
+ ).join();
|
|
|
+
|
|
|
+ // 5. 封装返回
|
|
|
+ try {
|
|
|
+ List<IronTrendL1DTO> tempList = tempListFuture.get();
|
|
|
+ List<IronTrendL1DTO> speed1List = speed1ListFuture.get();
|
|
|
+ List<IronTrendL1DTO> speed2List = speed2ListFuture.get();
|
|
|
+ List<IronTrendL1DTO> weight1List = weight1ListFuture.get();
|
|
|
+ List<IronTrendL1DTO> weight2List = weight2ListFuture.get();
|
|
|
+ List<IronTrendL2DTO> elemenList = elemenListFuture.get();
|
|
|
+
|
|
|
+ // 1. 收集所有时间点
|
|
|
+ java.util.Set<String> allTimes = new java.util.TreeSet<>();
|
|
|
+ java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
|
|
+ tempList.forEach(e -> allTimes.add(e.getCreateTime() != null ? sdf.format(e.getCreateTime()) : null));
|
|
|
+ speed1List.forEach(e -> allTimes.add(e.getCreateTime() != null ? sdf.format(e.getCreateTime()) : null));
|
|
|
+ speed2List.forEach(e -> allTimes.add(e.getCreateTime() != null ? sdf.format(e.getCreateTime()) : null));
|
|
|
+ weight1List.forEach(e -> allTimes.add(e.getCreateTime() != null ? sdf.format(e.getCreateTime()) : null));
|
|
|
+ weight2List.forEach(e -> allTimes.add(e.getCreateTime() != null ? sdf.format(e.getCreateTime()) : null));
|
|
|
+ elemenList.forEach(e -> allTimes.add(e.getCreateTime()));
|
|
|
+ allTimes.removeIf(Objects::isNull);
|
|
|
+ java.util.List<String> xAxis = new java.util.ArrayList<>(allTimes);
|
|
|
+
|
|
|
+ // 2. 构建series
|
|
|
+ java.util.List<java.util.Map<String, Object>> series = new java.util.ArrayList<>();
|
|
|
+ series.add(buildSeries("温度", tempList, xAxis));
|
|
|
+ series.add(buildSeries("1车流速", speed1List, xAxis));
|
|
|
+ series.add(buildSeries("2车流速", speed2List, xAxis));
|
|
|
+ series.add(buildSeries("1车铁水重量", weight1List, xAxis));
|
|
|
+ series.add(buildSeries("2车铁水重量", weight2List, xAxis));
|
|
|
+ series.add(buildSeries("硫", elemenList, xAxis, "elementS"));
|
|
|
+ series.add(buildSeries("硅", elemenList, xAxis, "elementSi"));
|
|
|
+
|
|
|
+ java.util.Map<String, Object> result = new java.util.HashMap<>();
|
|
|
+ result.put("xAxis", xAxis);
|
|
|
+ result.put("series", series);
|
|
|
+ return AjaxResult.success(result);
|
|
|
+ } catch (InterruptedException | ExecutionException e) {
|
|
|
+ log.error("获取或转换趋势数据异常", e);
|
|
|
+ return AjaxResult.failed(500, "获取或转换趋势数据异常: " + e.getMessage(), null);
|
|
|
+ }
|
|
|
+
|
|
|
+ } catch (InterruptedException | ExecutionException e) {
|
|
|
+ log.error("获取或转换趋势数据异常", e);
|
|
|
+ return AjaxResult.failed(500, "获取或转换趋势数据异常: " + e.getMessage(), null);
|
|
|
+ }
|
|
|
+
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("获取趋势数据异常", e);
|
|
|
+ return AjaxResult.failed(500, "获取趋势数据异常: " + e.getMessage(), null);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 工具方法
|
|
|
+ private java.util.Map<String, Object> buildSeries(String name, java.util.List<IronTrendL1DTO> list, java.util.List<String> xAxis) {
|
|
|
+ java.util.Map<String, Object> map = new java.util.HashMap<>();
|
|
|
+ map.put("name", name);
|
|
|
+ java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
|
|
+ java.util.Map<String, Object> timeValueMap = list.stream()
|
|
|
+ .filter(e -> e.getCreateTime() != null)
|
|
|
+ .collect(java.util.stream.Collectors.toMap(
|
|
|
+ e -> sdf.format(e.getCreateTime()),
|
|
|
+ IronTrendL1DTO::getData,
|
|
|
+ (v1, v2) -> v1
|
|
|
+ ));
|
|
|
+ java.util.List<Object> data = xAxis.stream().map(timeValueMap::get).collect(java.util.stream.Collectors.toList());
|
|
|
+ map.put("data", data);
|
|
|
+ return map;
|
|
|
+ }
|
|
|
+ private java.util.Map<String, Object> buildSeries(String name, java.util.List<IronTrendL2DTO> list, java.util.List<String> xAxis, String field) {
|
|
|
+ java.util.Map<String, Object> map = new java.util.HashMap<>();
|
|
|
+ map.put("name", name);
|
|
|
+ java.util.Map<String, Object> timeValueMap = list.stream()
|
|
|
+ .filter(e -> e.getCreateTime() != null)
|
|
|
+ .collect(java.util.stream.Collectors.toMap(
|
|
|
+ IronTrendL2DTO::getCreateTime,
|
|
|
+ e -> "elementS".equals(field) ? e.getElementS() : e.getElementSi(),
|
|
|
+ (v1, v2) -> v1
|
|
|
+ ));
|
|
|
+ java.util.List<Object> data = xAxis.stream().map(timeValueMap::get).collect(java.util.stream.Collectors.toList());
|
|
|
+ map.put("data", data);
|
|
|
+ return map;
|
|
|
+ }
|
|
|
|
|
|
}
|