|
@@ -0,0 +1,648 @@
|
|
|
+package com.sckj.iron.service.impl;
|
|
|
+
|
|
|
+import com.sckj.common.exception.OperateException;
|
|
|
+import com.sckj.iron.dto.IronTrendL1DTO;
|
|
|
+import com.sckj.iron.dto.IronTrendL2DTO;
|
|
|
+import com.sckj.iron.dto.RealtimeData;
|
|
|
+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 lombok.extern.slf4j.Slf4j;
|
|
|
+import org.springframework.stereotype.Service;
|
|
|
+
|
|
|
+import javax.annotation.Resource;
|
|
|
+import java.text.SimpleDateFormat;
|
|
|
+import java.util.*;
|
|
|
+import java.util.concurrent.CompletableFuture;
|
|
|
+import java.util.concurrent.ExecutionException;
|
|
|
+import java.util.stream.Collectors;
|
|
|
+
|
|
|
+@Slf4j
|
|
|
+@Service
|
|
|
+public class TIronVisualScreenServiceImpl {
|
|
|
+ @Resource
|
|
|
+ OPCDataServiceImpl opcDataService;
|
|
|
+
|
|
|
+
|
|
|
+ @Resource
|
|
|
+ TL2DataServiceImpl tl2DataService;
|
|
|
+
|
|
|
+
|
|
|
+ /***
|
|
|
+ * 实时数据图图例
|
|
|
+ * @param result
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public Map<String, Object> getIronLegend(Map<String, Object> result) {
|
|
|
+ java.util.Date startTime = new java.util.Date();
|
|
|
+ // 查询区间前的最近一条历史数据(前置值)
|
|
|
+ // OPC类
|
|
|
+// OPCData preTemp = opcDataService.lambdaQuery()
|
|
|
+// .eq(OPCData::getPointName, "BF4_1_IRONNOTCH_MIR_TEMP")
|
|
|
+// .isNotNull(OPCData::getData)
|
|
|
+// .le(OPCData::getServerTime, startTime)
|
|
|
+// .orderByDesc(OPCData::getServerTime)
|
|
|
+// .last("limit 1").one();
|
|
|
+// OPCData preSpeed1 = opcDataService.lambdaQuery()
|
|
|
+// .eq(OPCData::getPointName, "BF4_1_IRONNOTCH_RAILLINE_ACPIRON_SPEED1")
|
|
|
+// .isNotNull(OPCData::getData)
|
|
|
+// .le(OPCData::getServerTime, startTime)
|
|
|
+// .orderByDesc(OPCData::getServerTime)
|
|
|
+// .last("limit 1").one();
|
|
|
+// OPCData preSpeed2 = opcDataService.lambdaQuery()
|
|
|
+// .eq(OPCData::getPointName, "BF4_1_IRONNOTCH_RAILLINE_ACPIRON_SPEED2")
|
|
|
+// .isNotNull(OPCData::getData)
|
|
|
+// .le(OPCData::getServerTime, startTime)
|
|
|
+// .orderByDesc(OPCData::getServerTime)
|
|
|
+// .last("limit 1").one();
|
|
|
+// OPCData preWeight1 = opcDataService.lambdaQuery()
|
|
|
+// .eq(OPCData::getPointName, "BF4_1TH_1_MIR_NWT")
|
|
|
+// .isNotNull(OPCData::getData)
|
|
|
+// .le(OPCData::getServerTime, startTime)
|
|
|
+// .orderByDesc(OPCData::getServerTime)
|
|
|
+// .last("limit 1").one();
|
|
|
+// OPCData preWeight2 = opcDataService.lambdaQuery()
|
|
|
+// .eq(OPCData::getPointName, "BF4_1TH_2_MIR_NWT")
|
|
|
+// .isNotNull(OPCData::getData)
|
|
|
+// .le(OPCData::getServerTime, startTime)
|
|
|
+// .orderByDesc(OPCData::getServerTime)
|
|
|
+// .last("limit 1").one();
|
|
|
+
|
|
|
+ // tappingMap补齐每一分钟,前面无数据用前置值补齐
|
|
|
+ // 先查区间前最近一条tapping
|
|
|
+// Integer preTappingVal = 0;
|
|
|
+// OPCData preTapping = opcDataService.lambdaQuery()
|
|
|
+// .eq(OPCData::getPointName, "BF4_1_IRONNOTCH_TAPPING")
|
|
|
+// .isNotNull(OPCData::getData)
|
|
|
+// .lt(OPCData::getServerTime, startTime)
|
|
|
+// .orderByDesc(OPCData::getServerTime)
|
|
|
+// .last("limit 1").one();
|
|
|
+
|
|
|
+ // L2类
|
|
|
+ TL2Data preL2 = tl2DataService.lambdaQuery()
|
|
|
+ .le(TL2Data::getIronStarttime, new SimpleDateFormat("yyyyMMddHHmmss").format(startTime))
|
|
|
+ .orderByDesc(TL2Data::getIronStarttime)
|
|
|
+ .last("limit 1").one();
|
|
|
+
|
|
|
+// result.put("ironTemp", preTemp.getData());
|
|
|
+// result.put("ironSpeed", Double.parseDouble(preSpeed1.getData().toString()) + Double.parseDouble(preSpeed2.getData().toString()));
|
|
|
+ result.put("elementS", RealtimeData.builder().desc("铁水成分-硫").value(preL2.getElementS()).build());
|
|
|
+ result.put("elementSi", RealtimeData.builder().desc("铁水成分-硅").value(preL2.getElementSi()).build());
|
|
|
+ result.put("mudWeight", RealtimeData.builder().desc("泥炮量").value(preL2.getMudWeight()).unit("L").build());
|
|
|
+ result.put("pollMm",RealtimeData.builder().desc("钻杆直径").value(preL2.getPollMm()).unit("mm").build());
|
|
|
+ result.put("openDepth", RealtimeData.builder().desc("开口深度").value(preL2.getOpenDepth()).unit("mm").build());
|
|
|
+// result.put("ironCosttime", preL2.getIronCosttime());
|
|
|
+// result.put("ironWeight", Double.parseDouble(preWeight1.getData().toString()) + Double.parseDouble(preWeight2.getData().toString()));
|
|
|
+
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+ /***
|
|
|
+ * 实时折线图数据,
|
|
|
+ * BF4_1_IRONNOTCH_TAPPING表示出铁状态,数值只有0和1,1表示正在出铁,0表示未出铁
|
|
|
+ * BF4_1TH_1_MIR_NWT表示四高炉1TH-1号车铁水净重,BF4_1TH_2_MIR_NWT表示四高炉1TH-2号车铁水净重,这2车一开始的重量为0,然后装入铁水重量不断增加,直到满载,然后减为0,然后继续增加,以此往复
|
|
|
+ *
|
|
|
+ * @param queryDateType
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public Map<String, Object> getIronChart(TrendRequest queryDateType) {
|
|
|
+ // 1. 计算起止时间
|
|
|
+ int hours = Objects.isNull(queryDateType.getQueryHourBefore()) ? 8 : queryDateType.getQueryHourBefore();
|
|
|
+ //给固定时间,24小时之内
|
|
|
+ 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_1_MIR_NWT", // 四高炉1TH-1号车铁水净重
|
|
|
+ "BF4_1TH_2_MIR_NWT", // 四高炉1TH-2号车铁水净重
|
|
|
+ "BF4_1_IRONNOTCH_TAPPING", // 1号铁口出铁状态
|
|
|
+ "BF4_1TH_2_TPC_CARNO", // 1TH-2号车混铁车车号
|
|
|
+ "BF4_1TH_1_TPC_CARNO" // 1TH-1号车混铁车车号
|
|
|
+ ))
|
|
|
+ .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())
|
|
|
+ );
|
|
|
+
|
|
|
+ //1TH-1号车受铁速度
|
|
|
+ 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())
|
|
|
+ );
|
|
|
+
|
|
|
+ //1TH-2号车受铁速度
|
|
|
+ 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())
|
|
|
+ );
|
|
|
+
|
|
|
+ //BF4_1TH_1_MIR_NWT 1号车净重
|
|
|
+ CompletableFuture<List<IronTrendL1DTO>> weight1ListFuture = CompletableFuture.supplyAsync(() ->
|
|
|
+ opcDataMap.getOrDefault("BF4_1TH_1_MIR_NWT", new ArrayList<>())
|
|
|
+ .stream().map(item -> {
|
|
|
+ IronTrendL1DTO dto = new IronTrendL1DTO();
|
|
|
+ dto.setData(item.getData());
|
|
|
+ dto.setCreateTime(item.getSourceTime());
|
|
|
+ return dto;
|
|
|
+ }).collect(Collectors.toList())
|
|
|
+ );
|
|
|
+
|
|
|
+ //BF4_1TH_2_MIR_NWT 2号车净重
|
|
|
+ CompletableFuture<List<IronTrendL1DTO>> weight2ListFuture = CompletableFuture.supplyAsync(() ->
|
|
|
+ opcDataMap.getOrDefault("BF4_1TH_2_MIR_NWT", new ArrayList<>())
|
|
|
+ .stream().map(item -> {
|
|
|
+ IronTrendL1DTO dto = new IronTrendL1DTO();
|
|
|
+ dto.setData(item.getData());
|
|
|
+ dto.setCreateTime(item.getSourceTime());
|
|
|
+ return dto;
|
|
|
+ }).collect(Collectors.toList())
|
|
|
+ );
|
|
|
+
|
|
|
+ //L2
|
|
|
+ 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.setIronStarttime(item.getIronStarttime());
|
|
|
+ dto.setIronEndtime(item.getIronEndtime());
|
|
|
+ dto.setPollMm(item.getPollMm());
|
|
|
+ dto.setOpenDepth(item.getOpenDepth());
|
|
|
+ dto.setMudWeight(item.getMudWeight());
|
|
|
+ dto.setIronCosttime(item.getIronCosttime());
|
|
|
+ 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.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:00");
|
|
|
+ java.util.List<String> xAxis = new java.util.ArrayList<>();
|
|
|
+ java.util.Calendar cursor = java.util.Calendar.getInstance();
|
|
|
+ cursor.setTime(startTime);
|
|
|
+ while (!cursor.getTime().after(endTime)) {
|
|
|
+ xAxis.add(sdf.format(cursor.getTime()));
|
|
|
+ cursor.add(java.util.Calendar.MINUTE, 1);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 查询区间前的最近一条历史数据(前置值)
|
|
|
+ // OPC类
|
|
|
+ OPCData preTemp = opcDataService.lambdaQuery()
|
|
|
+ .eq(OPCData::getPointName, "BF4_1_IRONNOTCH_MIR_TEMP")
|
|
|
+ .isNotNull(OPCData::getData)
|
|
|
+ .lt(OPCData::getServerTime, startTime)
|
|
|
+ .orderByDesc(OPCData::getServerTime)
|
|
|
+ .last("limit 1").one();
|
|
|
+ OPCData preSpeed1 = opcDataService.lambdaQuery()
|
|
|
+ .eq(OPCData::getPointName, "BF4_1_IRONNOTCH_RAILLINE_ACPIRON_SPEED1")
|
|
|
+ .isNotNull(OPCData::getData)
|
|
|
+ .lt(OPCData::getServerTime, startTime)
|
|
|
+ .orderByDesc(OPCData::getServerTime)
|
|
|
+ .last("limit 1").one();
|
|
|
+ OPCData preSpeed2 = opcDataService.lambdaQuery()
|
|
|
+ .eq(OPCData::getPointName, "BF4_1_IRONNOTCH_RAILLINE_ACPIRON_SPEED2")
|
|
|
+ .isNotNull(OPCData::getData)
|
|
|
+ .lt(OPCData::getServerTime, startTime)
|
|
|
+ .orderByDesc(OPCData::getServerTime)
|
|
|
+ .last("limit 1").one();
|
|
|
+ OPCData preWeight1 = opcDataService.lambdaQuery()
|
|
|
+ .eq(OPCData::getPointName, "BF4_1TH_1_MIR_NWT")
|
|
|
+ .isNotNull(OPCData::getData)
|
|
|
+ .lt(OPCData::getServerTime, startTime)
|
|
|
+ .orderByDesc(OPCData::getServerTime)
|
|
|
+ .last("limit 1").one();
|
|
|
+ OPCData preWeight2 = opcDataService.lambdaQuery()
|
|
|
+ .eq(OPCData::getPointName, "BF4_1TH_2_MIR_NWT")
|
|
|
+ .isNotNull(OPCData::getData)
|
|
|
+ .lt(OPCData::getServerTime, startTime)
|
|
|
+ .orderByDesc(OPCData::getServerTime)
|
|
|
+ .last("limit 1").one();
|
|
|
+
|
|
|
+ // tappingMap补齐每一分钟,前面无数据用前置值补齐
|
|
|
+ // 先查区间前最近一条tapping
|
|
|
+ Integer preTappingVal = 0;
|
|
|
+ OPCData preTapping = opcDataService.lambdaQuery()
|
|
|
+ .eq(OPCData::getPointName, "BF4_1_IRONNOTCH_TAPPING")
|
|
|
+ .isNotNull(OPCData::getData)
|
|
|
+ .lt(OPCData::getServerTime, startTime)
|
|
|
+ .orderByDesc(OPCData::getServerTime)
|
|
|
+ .last("limit 1").one();
|
|
|
+
|
|
|
+ // L2类
|
|
|
+ TL2Data preL2 = tl2DataService.lambdaQuery()
|
|
|
+ .lt(TL2Data::getIronStarttime, new SimpleDateFormat("yyyyMMddHHmmss").format(startTime))
|
|
|
+ .orderByDesc(TL2Data::getIronStarttime)
|
|
|
+ .last("limit 1").one();
|
|
|
+
|
|
|
+ // 2. 构建每分钟补全的二维数组
|
|
|
+ java.util.Map<String, Object> result = new java.util.LinkedHashMap<>();
|
|
|
+// result.put("ironTemp", buildMinuteArray(tempList, xAxis, preTemp != null ? preTemp.getData() : null));
|
|
|
+// result.put("ironSpeed", buildMinuteArrayForSpeed(xAxis, speed1List, speed2List, preSpeed1 != null ? preSpeed1.getData() : null, preSpeed2 != null ? preSpeed2.getData() : null));
|
|
|
+// result.put("elementS", buildMinuteArray(elemenList, xAxis, "elementS", preL2 != null ? preL2.getElementS() : null));
|
|
|
+// result.put("elementSi", buildMinuteArray(elemenList, xAxis, "elementSi", preL2 != null ? preL2.getElementSi() : null));
|
|
|
+// result.put("mudWeight", buildMinuteArray(elemenList, xAxis, "mudWeight", preL2 != null ? preL2.getMudWeight() : null));
|
|
|
+// result.put("pollMm", buildMinuteArray(elemenList, xAxis, "pollMm", preL2 != null ? preL2.getPollMm() : null));
|
|
|
+// result.put("openDepth", buildMinuteArray(elemenList, xAxis, "openDepth", preL2 != null ? preL2.getOpenDepth() : null));
|
|
|
+// result.put("ironCosttime", buildMinuteArray(elemenList, xAxis, "ironCosttime", preL2 != null ? preL2.getIronCosttime() : null));
|
|
|
+
|
|
|
+ // 统计出铁累计重量递增曲线
|
|
|
+ if (preTapping != null && preTapping.getData() != null) {
|
|
|
+ Object v = preTapping.getData();
|
|
|
+ if (v instanceof Number) preTappingVal = ((Number) v).intValue();
|
|
|
+ else if (v instanceof String) {
|
|
|
+ String str = ((String) v).trim();
|
|
|
+ if (!str.isEmpty()) {
|
|
|
+ try {
|
|
|
+ preTappingVal = Integer.parseInt(str);
|
|
|
+ } catch (Exception ignore) {
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // 构建每分钟tappingMap
|
|
|
+ Map<String, Integer> tappingMap = new LinkedHashMap<>();
|
|
|
+ List<OPCData> tappingList = opcDataMap.getOrDefault("BF4_1_IRONNOTCH_TAPPING", new ArrayList<>());
|
|
|
+ Map<String, Integer> rawTappingMap = new LinkedHashMap<>();
|
|
|
+ for (OPCData item : tappingList) {
|
|
|
+ if (item.getServerTime() != null && item.getData() != null) {
|
|
|
+ String min = sdf.format(item.getServerTime());
|
|
|
+ Integer val = null;
|
|
|
+ Object v = item.getData();
|
|
|
+ if (v instanceof Number) val = ((Number) v).intValue();
|
|
|
+ else if (v instanceof String) {
|
|
|
+ String str = ((String) v).trim();
|
|
|
+ if (!str.isEmpty()) {
|
|
|
+ try {
|
|
|
+ val = Integer.parseInt(str);
|
|
|
+ } catch (Exception ignore) {
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (val != null) rawTappingMap.put(min, val);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ Integer last = preTappingVal;
|
|
|
+ for (String t : xAxis) {
|
|
|
+ Integer v = rawTappingMap.getOrDefault(t, last);
|
|
|
+ tappingMap.put(t, v);
|
|
|
+ if (v != null) last = v;
|
|
|
+ }
|
|
|
+ // weight1Map/weight2Map
|
|
|
+ Map<String, Double> weight1Map = new LinkedHashMap<>();
|
|
|
+ Map<String, Double> weight2Map = new LinkedHashMap<>();
|
|
|
+ for (IronTrendL1DTO e : weight1List) {
|
|
|
+ if (e.getCreateTime() != null) {
|
|
|
+ String min = sdf.format(e.getCreateTime());
|
|
|
+ Object v = e.getData();
|
|
|
+ Double value = null;
|
|
|
+ if (v instanceof Number) value = ((Number) v).doubleValue();
|
|
|
+ else if (v instanceof String) {
|
|
|
+ String str = ((String) v).trim();
|
|
|
+ if (!str.isEmpty()) {
|
|
|
+ try {
|
|
|
+ value = Double.parseDouble(str);
|
|
|
+ } catch (Exception ignore) {
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (value != null) weight1Map.put(min, value);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ for (IronTrendL1DTO e : weight2List) {
|
|
|
+ if (e.getCreateTime() != null) {
|
|
|
+ String min = sdf.format(e.getCreateTime());
|
|
|
+ Object v = e.getData();
|
|
|
+ Double value = null;
|
|
|
+ if (v instanceof Number) value = ((Number) v).doubleValue();
|
|
|
+ else if (v instanceof String) {
|
|
|
+ String str = ((String) v).trim();
|
|
|
+ if (!str.isEmpty()) {
|
|
|
+ try {
|
|
|
+ value = Double.parseDouble(str);
|
|
|
+ } catch (Exception ignore) {
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (value != null) weight2Map.put(min, value);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // 计算铁水流量总和
|
|
|
+// double totalIronFlow = calculateTotalIronFlow(xAxis, weight1Map, weight2Map);
|
|
|
+// result.put("铁水流量", totalIronFlow);
|
|
|
+
|
|
|
+ // 铁水流量分钟累计显示,分别处理weight1Map和weight2Map,不合并为totalWeightMap
|
|
|
+ int ironWeightScale = 2; // 可调整为0、1、2等
|
|
|
+ List<List<Object>> ironFlowArr = buildIronFlowMinuteArrayV3(xAxis, tappingMap, weight1Map, weight2Map, ironWeightScale);
|
|
|
+ result.put("ironWeight", ironFlowArr);
|
|
|
+
|
|
|
+ return result;
|
|
|
+ } catch (InterruptedException | ExecutionException e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ throw new OperateException("获取或转换趋势数据异常: " + e.getMessage());
|
|
|
+ }
|
|
|
+
|
|
|
+ } catch (InterruptedException | ExecutionException e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ throw new OperateException("获取或转换趋势数据异常: " + e.getMessage());
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ throw new OperateException("获取趋势数据异常: " + e.getMessage());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 新增工具方法:L1类型
|
|
|
+ private java.util.List<java.util.List<Object>> buildMinuteArray(java.util.List<IronTrendL1DTO> list, java.util.List<String> xAxis, Object preValue) {
|
|
|
+ java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:00");
|
|
|
+ java.util.Map<String, Object> timeValueMap = new java.util.LinkedHashMap<>();
|
|
|
+ for (IronTrendL1DTO e : list) {
|
|
|
+ if (e.getCreateTime() != null) {
|
|
|
+ String min = sdf.format(e.getCreateTime());
|
|
|
+ timeValueMap.put(min, e.getData());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ java.util.List<java.util.List<Object>> arr = new java.util.ArrayList<>();
|
|
|
+ Object last = preValue;
|
|
|
+ for (String t : xAxis) {
|
|
|
+ Object v = timeValueMap.getOrDefault(t, last);
|
|
|
+ arr.add(java.util.Arrays.asList(t, v));
|
|
|
+ if (v != null) last = v;
|
|
|
+ }
|
|
|
+ return arr;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 合并铁水流速专用
|
|
|
+ private java.util.List<java.util.List<Object>> buildMinuteArrayForSpeed(java.util.List<String> xAxis, java.util.List<IronTrendL1DTO> speed1List, java.util.List<IronTrendL1DTO> speed2List, Object pre1, Object pre2) {
|
|
|
+ java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:00");
|
|
|
+ java.util.Map<String, Double> speed1Map = new java.util.LinkedHashMap<>();
|
|
|
+ java.util.Map<String, Double> speed2Map = new java.util.LinkedHashMap<>();
|
|
|
+ for (IronTrendL1DTO e : speed1List) {
|
|
|
+ if (e.getCreateTime() != null) {
|
|
|
+ String min = sdf.format(e.getCreateTime());
|
|
|
+ Object v = e.getData();
|
|
|
+ Double value = null;
|
|
|
+ if (v instanceof Number) value = ((Number) v).doubleValue();
|
|
|
+ else if (v instanceof String) {
|
|
|
+ try {
|
|
|
+ value = Double.parseDouble((String) v);
|
|
|
+ } catch (Exception ignore) {
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (value != null) speed1Map.put(min, value);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ for (IronTrendL1DTO e : speed2List) {
|
|
|
+ if (e.getCreateTime() != null) {
|
|
|
+ String min = sdf.format(e.getCreateTime());
|
|
|
+ Object v = e.getData();
|
|
|
+ Double value = null;
|
|
|
+ if (v instanceof Number) value = ((Number) v).doubleValue();
|
|
|
+ else if (v instanceof String) {
|
|
|
+ try {
|
|
|
+ value = Double.parseDouble((String) v);
|
|
|
+ } catch (Exception ignore) {
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (value != null) speed2Map.put(min, value);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ java.util.List<java.util.List<Object>> arr = new java.util.ArrayList<>();
|
|
|
+ Double last = null;
|
|
|
+ Double pre1Val = null, pre2Val = null;
|
|
|
+ if (pre1 != null) {
|
|
|
+ if (pre1 instanceof Number) pre1Val = ((Number) pre1).doubleValue();
|
|
|
+ else if (pre1 instanceof String) {
|
|
|
+ String str = ((String) pre1).trim();
|
|
|
+ if (!str.isEmpty()) {
|
|
|
+ try {
|
|
|
+ pre1Val = Double.parseDouble(str);
|
|
|
+ } catch (Exception ignore) {
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (pre2 != null) {
|
|
|
+ if (pre2 instanceof Number) pre2Val = ((Number) pre2).doubleValue();
|
|
|
+ else if (pre2 instanceof String) {
|
|
|
+ String str = ((String) pre2).trim();
|
|
|
+ if (!str.isEmpty()) {
|
|
|
+ try {
|
|
|
+ pre2Val = Double.parseDouble(str);
|
|
|
+ } catch (Exception ignore) {
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (pre1Val != null && pre2Val != null) last = pre1Val + pre2Val;
|
|
|
+ else if (pre1Val != null) last = pre1Val;
|
|
|
+ else if (pre2Val != null) last = pre2Val;
|
|
|
+ for (String t : xAxis) {
|
|
|
+ Double cur1 = speed1Map.getOrDefault(t, null);
|
|
|
+ Double cur2 = speed2Map.getOrDefault(t, null);
|
|
|
+ Double sum = null;
|
|
|
+ if (cur1 != null && cur2 != null) sum = cur1 + cur2;
|
|
|
+ else if (cur1 != null) sum = cur1;
|
|
|
+ else if (cur2 != null) sum = cur2;
|
|
|
+ else sum = last;
|
|
|
+ arr.add(java.util.Arrays.asList(t, sum));
|
|
|
+ if (sum != null) last = sum;
|
|
|
+ }
|
|
|
+ return arr;
|
|
|
+ }
|
|
|
+
|
|
|
+ // L2类型,增加preValue参数
|
|
|
+ private java.util.List<java.util.List<Object>> buildMinuteArray(java.util.List<IronTrendL2DTO> list, java.util.List<String> xAxis, String field, Object preValue) {
|
|
|
+ java.util.Map<String, Object> timeValueMap = new java.util.LinkedHashMap<>();
|
|
|
+ for (IronTrendL2DTO e : list) {
|
|
|
+ String min = e.getIronStarttime();
|
|
|
+ if (min != null) {
|
|
|
+ Object v = null;
|
|
|
+ switch (field) {
|
|
|
+ case "elementS":
|
|
|
+ v = e.getElementS();
|
|
|
+ break;
|
|
|
+ case "elementSi":
|
|
|
+ v = e.getElementSi();
|
|
|
+ break;
|
|
|
+ case "mudWeight":
|
|
|
+ v = e.getMudWeight();
|
|
|
+ break;
|
|
|
+ case "pollMm":
|
|
|
+ v = e.getPollMm();
|
|
|
+ break;
|
|
|
+ case "openDepth":
|
|
|
+ v = e.getOpenDepth();
|
|
|
+ break;
|
|
|
+ case "ironCosttime":
|
|
|
+ v = e.getIronCosttime();
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ timeValueMap.put(min, v);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ java.util.List<java.util.List<Object>> arr = new java.util.ArrayList<>();
|
|
|
+ Object last = preValue;
|
|
|
+ for (String t : xAxis) {
|
|
|
+ Object v = timeValueMap.getOrDefault(t, last);
|
|
|
+ arr.add(java.util.Arrays.asList(t, v));
|
|
|
+ if (v != null) last = v;
|
|
|
+ }
|
|
|
+ return arr;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ // 新增:铁水流量分钟累计显示方法V3,分别处理weight1Map和weight2Map
|
|
|
+ private List<List<Object>> buildIronFlowMinuteArrayV3(List<String> xAxis, Map<String, Integer> tappingMap, Map<String, Double> weight1Map, Map<String, Double> weight2Map, int scale) {
|
|
|
+ List<List<Object>> arr = new ArrayList<>();
|
|
|
+ double accWeight = 0;
|
|
|
+ // 1号车状态
|
|
|
+ double max1 = 0, last1 = 0;
|
|
|
+ boolean inCycle1 = false;
|
|
|
+ // 2号车状态
|
|
|
+ double max2 = 0, last2 = 0;
|
|
|
+ boolean inCycle2 = false;
|
|
|
+ for (int i = 0; i < xAxis.size(); i++) {
|
|
|
+ String t = xAxis.get(i);
|
|
|
+ Integer tapping = tappingMap.getOrDefault(t, 0);
|
|
|
+ double w1 = weight1Map.getOrDefault(t, 0d);
|
|
|
+ double w2 = weight2Map.getOrDefault(t, 0d);
|
|
|
+
|
|
|
+ // 1号车逻辑
|
|
|
+ if (w1 > 0) {
|
|
|
+ if (!inCycle1) {
|
|
|
+ inCycle1 = true;
|
|
|
+ max1 = w1;
|
|
|
+ } else {
|
|
|
+ if (w1 > max1) max1 = w1;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // 2号车逻辑
|
|
|
+ if (w2 > 0) {
|
|
|
+ if (!inCycle2) {
|
|
|
+ inCycle2 = true;
|
|
|
+ max2 = w2;
|
|
|
+ } else {
|
|
|
+ if (w2 > max2) max2 = w2;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 检查1号车归零
|
|
|
+ boolean add1 = false;
|
|
|
+ if (inCycle1 && w1 == 0 && last1 > 0) {
|
|
|
+ add1 = true;
|
|
|
+ inCycle1 = false;
|
|
|
+ }
|
|
|
+ // 检查2号车归零
|
|
|
+ boolean add2 = false;
|
|
|
+ if (inCycle2 && w2 == 0 && last2 > 0) {
|
|
|
+ add2 = true;
|
|
|
+ inCycle2 = false;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 归零时把最大值加到累计值
|
|
|
+ if (add1 && max1 > 0) {
|
|
|
+ accWeight += max1;
|
|
|
+ max1 = 0;
|
|
|
+ }
|
|
|
+ if (add2 && max2 > 0) {
|
|
|
+ accWeight += max2;
|
|
|
+ max2 = 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ // tapping=1时,显示accWeight+max(max1,max2);tapping=0时,显示0
|
|
|
+ double value;
|
|
|
+ if (tapping == 1) {
|
|
|
+ double curMax = Math.max(max1, max2);
|
|
|
+ value = accWeight + curMax;
|
|
|
+ } else {
|
|
|
+ value = 0;
|
|
|
+ }
|
|
|
+ // 按scale参数四舍五入
|
|
|
+ double factor = Math.pow(10, scale);
|
|
|
+ value = Math.round(value * factor) / factor;
|
|
|
+ arr.add(Arrays.asList(t, value));
|
|
|
+ last1 = w1;
|
|
|
+ last2 = w2;
|
|
|
+ }
|
|
|
+ return arr;
|
|
|
+ }
|
|
|
+}
|