Browse Source

1.实时折线图、图例图完善

wangxiaofei 2 months ago
parent
commit
20d0c7ce3a

+ 49 - 4
taphole-common/src/main/java/com/sckj/common/util/TimeUtils.java

@@ -5,12 +5,8 @@ import java.lang.management.ManagementFactory;
 import java.text.DateFormat;
 import java.text.ParsePosition;
 import java.text.SimpleDateFormat;
-import java.time.Instant;
-import java.time.LocalDateTime;
-import java.time.ZoneId;
 import java.util.*;
 import java.util.regex.Pattern;
-import java.time.format.DateTimeFormatter;
 
 public class TimeUtils {
 
@@ -539,4 +535,53 @@ public class TimeUtils {
         // long sec = diff % nd % nh % nm / ns;
         return day + "天" + hour + "小时" + min + "分钟";
     }
+
+    /***
+     * yyyyMMddHHmmss -> yyyy-MM-dd HH:mm:ss
+     * @param input
+     * @return
+     */
+    public static String formatPartialDateString(String input) {
+        if (input == null || input.isEmpty()) {
+            return "";
+        }
+
+        StringBuilder result = new StringBuilder();
+        int len = input.length();
+
+        // 年 (yyyy)
+        if (len >= 4) {
+            result.append(input.substring(0, 4));
+        } else {
+            return input; // 不足4位直接返回原字符串
+        }
+
+        // 月 (MM)
+        if (len >= 6) {
+            result.append("-").append(input.substring(4, 6));
+        }
+
+        // 日 (dd)
+        if (len >= 8) {
+            result.append("-").append(input.substring(6, 8));
+        }
+
+        // 时 (HH)
+        if (len >= 10) {
+            result.append(" ").append(input.substring(8, 10));
+        }
+
+        // 分 (mm)
+        if (len >= 12) {
+            result.append(":").append(input.substring(10, 12));
+        }
+
+        // 秒 (ss)
+        if (len >= 14) {
+            result.append(":").append(input.substring(12, 14));
+        }
+
+        return result.toString();
+    }
+
 }

+ 1 - 1
taphole-iron/src/main/java/com/sckj/iron/constant/ExpressionConstants.java

@@ -1,7 +1,7 @@
 package com.sckj.iron.constant;
 
 /***
- * 表达式Context变量名
+ * SPEL表达式Context变量名
  * 单位:s
  */
 public class ExpressionConstants {

+ 6 - 0
taphole-iron/src/main/java/com/sckj/iron/constant/StepConstans.java

@@ -33,4 +33,10 @@ public class StepConstans {
 
     //上上次实际铁量
     public static final String sscsj = "sscsj";
+
+    //上次铁次号
+    public static final String sctch = "sctch";
+
+    //上上次铁次号
+    public static final String ssctch = "ssctch";
 }

+ 9 - 9
taphole-iron/src/main/java/com/sckj/iron/controller/TIronVisualScreenController.java

@@ -233,15 +233,15 @@ public class TIronVisualScreenController {
     public AjaxResult getIronLegend() {
         Map<String, Object> result = tIronVisualScreenService.getIronLegend(new HashMap<>());
         //生产随机数据
-        result.put("ironCosttime",  RealtimeData.builder().desc("出铁时间").value((Math.random() * 100) + 200).unit("min").build());
-        result.put("elementS", RealtimeData.builder().desc("铁水成分-硫").value((Math.random() * 1)).build());
-        result.put("elementSi", RealtimeData.builder().desc("铁水成分-硅").value((Math.random() * 1) + 1).build());
-        result.put("mudWeight",  RealtimeData.builder().desc("泥炮量").value((Math.random() * 60) + 1).unit("L").build());
-        result.put("pollMm",RealtimeData.builder().desc("钻杆直径").value((Math.random() * 60) + 1).unit("mm").build());
-        result.put("openDepth", RealtimeData.builder().desc("开口深度").value((Math.random() * 100) + 1).unit("mm").build());
-        result.put("ironTemp", RealtimeData.builder().desc("铁水温度").value((Math.random() * 100) + 1400).unit("℃").build());
-        result.put("ironSpeed", RealtimeData.builder().desc("铁水流速").value((Math.random() * 10) + 10).unit("t/s").build());
-        result.put("ironWeight", RealtimeData.builder().desc("铁水流量").value((Math.random() * 100) + 1100).unit("t").build());
+//        result.put("ironCosttime",  RealtimeData.builder().desc("出铁时间").value((Math.random() * 100) + 200).unit("min").build());
+//        result.put("elementS", RealtimeData.builder().desc("铁水成分-硫").value((Math.random() * 1)).build());
+//        result.put("elementSi", RealtimeData.builder().desc("铁水成分-硅").value((Math.random() * 1) + 1).build());
+//        result.put("mudWeight",  RealtimeData.builder().desc("泥炮量").value((Math.random() * 60) + 1).unit("L").build());
+//        result.put("pollMm",RealtimeData.builder().desc("钻杆直径").value((Math.random() * 60) + 1).unit("mm").build());
+//        result.put("openDepth", RealtimeData.builder().desc("开口深度").value((Math.random() * 100) + 1).unit("mm").build());
+//        result.put("ironTemp", RealtimeData.builder().desc("铁水温度").value((Math.random() * 100) + 1400).unit("℃").build());
+//        result.put("ironSpeed", RealtimeData.builder().desc("铁水流速").value((Math.random() * 10) + 10).unit("t/s").build());
+//        result.put("ironWeight", RealtimeData.builder().desc("铁水流量").value((Math.random() * 100) + 1100).unit("t").build());
         return AjaxResult.success(result);
     }
 

+ 6 - 15
taphole-iron/src/main/java/com/sckj/iron/dto/RealtimeData.java

@@ -2,10 +2,7 @@ package com.sckj.iron.dto;
 
 import io.swagger.annotations.ApiModelProperty;
 import io.swagger.annotations.ApiOperation;
-import lombok.AllArgsConstructor;
-import lombok.Builder;
-import lombok.Data;
-import lombok.NoArgsConstructor;
+import lombok.*;
 import org.springframework.stereotype.Component;
 
 /***
@@ -18,11 +15,10 @@ import org.springframework.stereotype.Component;
 @AllArgsConstructor
 @Data
 @Component
+@ToString
 @ApiOperation("实时数据信息")
 public class RealtimeData {
 
-//    private String key;
-
     @ApiModelProperty("数据值")
     private Object value;
 
@@ -35,13 +31,8 @@ public class RealtimeData {
     @ApiModelProperty("时间")
     private String time;
 
-    @Override
-    public String toString() {
-        return "RealtimeData{" +
-                "value=" + value +
-                ", unit='" + unit + '\'' +
-                ", desc='" + desc + '\'' +
-                ", time='" + time + '\'' +
-                '}';
-    }
+    @ApiModelProperty("其他属性")
+    private Object extra;
+
+
 }

+ 216 - 155
taphole-iron/src/main/java/com/sckj/iron/service/impl/TIronVisualScreenServiceImpl.java

@@ -1,6 +1,7 @@
 package com.sckj.iron.service.impl;
 
 import com.sckj.common.exception.OperateException;
+import com.sckj.common.util.TimeUtils;
 import com.sckj.iron.dto.IronTrendL1DTO;
 import com.sckj.iron.dto.IronTrendL2DTO;
 import com.sckj.iron.dto.RealtimeData;
@@ -10,6 +11,7 @@ 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.apache.commons.lang3.ObjectUtils;
 import org.springframework.stereotype.Service;
 
 import javax.annotation.Resource;
@@ -30,6 +32,9 @@ public class TIronVisualScreenServiceImpl {
     TL2DataServiceImpl tl2DataService;
 
 
+    private static final SimpleDateFormat sdfMinute = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:00");
+
+
     /***
      * 实时数据图图例
      * @param result
@@ -37,48 +42,6 @@ public class TIronVisualScreenServiceImpl {
      */
     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()
@@ -86,15 +49,67 @@ public class TIronVisualScreenServiceImpl {
                 .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("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()));
+
+        // 1. 计算起止时间
+        int hours = 24;
+        //给固定时间,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);
+        startTime = cal.getTime();
+        List<OPCData> list = opcDataService.lambdaQuery()
+                .in(OPCData::getPointName, Arrays.asList(
+                        "BF4_1TH_2_TPC_CARNO",                      // 1TH-2号车混铁车车号
+                        "BF4_1TH_1_TPC_CARNO"                       // 1TH-1号车混铁车车号
+                ))
+                .between(OPCData::getServerTime, startTime, endTime)
+                .orderByAsc(OPCData::getServerTime)
+                .list();
+        if (ObjectUtils.isNotEmpty(list)) {
+            RealtimeData ironWeight = (RealtimeData) result.getOrDefault("ironWeight", RealtimeData.builder().desc("铁水流量").unit("t").value(0).build());
+            List<Map<String, Object>> collect = list.stream().map(item -> {
+                Map<String, Object> map = new HashMap<>();
+                map.put("data", item.getData());
+                map.put("createTime", sdfMinute.format(item.getSourceTime()));
+                return map;
+            }).collect(Collectors.toList());
+
+            Map<String, Object> extraMap = new HashMap<>();
+            extraMap.put("mark", collect);
+            ironWeight.setExtra(extraMap);
+
+            result.put("ironWeight", ironWeight);
+        }
+
+        List<TL2Data> list1 = tl2DataService.lambdaQuery()
+                .between(TL2Data::getIronStarttime,
+                        new SimpleDateFormat("yyyyMMddHHmmss").format(startTime),
+                        new SimpleDateFormat("yyyyMMddHHmmss").format(endTime))
+                .orderByAsc(TL2Data::getIronStarttime)
+                .list();
+
+        if (ObjectUtils.isNotEmpty(list1)) {
+            RealtimeData ironCosttime = (RealtimeData) result.getOrDefault("ironCosttime", RealtimeData.builder().desc("出铁时间").unit("min").value(0).build());
+            List<Map<String, Object>> collect = list1.stream().map(item -> {
+                Map<String, Object> map = new HashMap<>();
+                map.put("data", String.format("第%s次出铁(%s号铁口)%s分钟",item.getIronNo(),item.getTapholeId(),item.getIronCosttime()));
+                map.put("createTime", TimeUtils.formatPartialDateString(item.getIronStarttime()));
+                return map;
+            }).collect(Collectors.toList());
+
+            Map<String, Object> extraMap = new HashMap<>();
+            extraMap.put("mark", collect);
+            ironCosttime.setExtra(extraMap);
+
+            result.put("ironCosttime", ironCosttime);
+        }
+
 
         return result;
     }
@@ -255,12 +270,11 @@ public class TIronVisualScreenServiceImpl {
                     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()));
+                        xAxis.add(sdfMinute.format(cursor.getTime()));
                         cursor.add(java.util.Calendar.MINUTE, 1);
                     }
 
@@ -315,14 +329,13 @@ public class TIronVisualScreenServiceImpl {
 
                     // 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));
+                    result.put("ironTemp", buildMinuteArray(tempList, xAxis, preTemp != null ? preTemp.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));
+
 
                     // 统计出铁累计重量递增曲线
                     if (preTapping != null && preTapping.getData() != null) {
@@ -344,7 +357,7 @@ public class TIronVisualScreenServiceImpl {
                     Map<String, Integer> rawTappingMap = new LinkedHashMap<>();
                     for (OPCData item : tappingList) {
                         if (item.getServerTime() != null && item.getData() != null) {
-                            String min = sdf.format(item.getServerTime());
+                            String min = sdfMinute.format(item.getServerTime());
                             Integer val = null;
                             Object v = item.getData();
                             if (v instanceof Number) val = ((Number) v).intValue();
@@ -366,53 +379,56 @@ public class TIronVisualScreenServiceImpl {
                         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);
+                    int ironWeightScale = 2; // 可调整为0、1、2等
+                    List<List<Object>> ironFlowArr = buildIronFlowMinuteArray(xAxis, tappingMap, weight1List, weight2List, ironWeightScale);
+                    result.put("ironWeight", ironFlowArr);
+
+                    // 处理铁水流速,出铁中按原逻辑,出铁结束后为0
+                    List<List<Object>> ironSpeedArr = buildMinuteArrayForSpeed(xAxis, speed1List, speed2List, preSpeed1 != null ? preSpeed1.getData() : null, preSpeed2 != null ? preSpeed2.getData() : null);
+                    for (int i = 0; i < xAxis.size(); i++) {
+                        String t = xAxis.get(i);
+                        Integer tapping = tappingMap.getOrDefault(t, 0);
+                        if (tapping == 0 && ironSpeedArr.get(i).size() > 1) {
+                            ironSpeedArr.get(i).set(1, 0);
                         }
                     }
-                    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);
+                    result.put("ironSpeed", ironSpeedArr);
+
+//                    List<List<Object>> ironCosttime =  buildMinuteArray(elemenList, xAxis, "ironCosttime", preL2 != null ? preL2.getIronCosttime() : null);
+//                    for (int i = 0; i < xAxis.size(); i++) {
+//                        String t = xAxis.get(i);
+//                        Integer tapping = tappingMap.getOrDefault(t, 0);
+//                        if (tapping == 0 && ironCosttime.get(i).size() > 1) {
+//                            ironCosttime.get(i).set(1, 0);
+//                        }
+//                    }
+//                    result.put("ironCosttime", ironCosttime);
+
+                    // 处理L2类数据,tapping=0时设为0
+                    List<List<Object>> elementSArr = buildMinuteArray(elemenList, xAxis, "elementS", preL2 != null ? preL2.getElementS() : null);
+                    List<List<Object>> elementSiArr = buildMinuteArray(elemenList, xAxis, "elementSi", preL2 != null ? preL2.getElementSi() : null);
+                    List<List<Object>> mudWeightArr = buildMinuteArray(elemenList, xAxis, "mudWeight", preL2 != null ? preL2.getMudWeight() : null);
+                    List<List<Object>> pollMmArr = buildMinuteArray(elemenList, xAxis, "pollMm", preL2 != null ? preL2.getPollMm() : null);
+                    List<List<Object>> openDepthArr = buildMinuteArray(elemenList, xAxis, "openDepth", preL2 != null ? preL2.getOpenDepth() : null);
+                    List<List<Object>> ironCosttimeArr = buildMinuteArray(elemenList, xAxis, "ironCosttime", preL2 != null ? preL2.getIronCosttime() : null);
+                    for (int i = 0; i < xAxis.size(); i++) {
+                        String t = xAxis.get(i);
+                        Integer tapping = tappingMap.getOrDefault(t, 0);
+                        if (tapping == 0) {
+                            if (elementSArr.get(i).size() > 1) elementSArr.get(i).set(1, 0);
+                            if (elementSiArr.get(i).size() > 1) elementSiArr.get(i).set(1, 0);
+                            if (mudWeightArr.get(i).size() > 1) mudWeightArr.get(i).set(1, 0);
+                            if (pollMmArr.get(i).size() > 1) pollMmArr.get(i).set(1, 0);
+                            if (openDepthArr.get(i).size() > 1) openDepthArr.get(i).set(1, 0);
+                            if (ironCosttimeArr.get(i).size() > 1) ironCosttimeArr.get(i).set(1, 0);
                         }
                     }
-                    // 计算铁水流量总和
-//                    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);
+                    result.put("elementS", elementSArr);
+                    result.put("elementSi", elementSiArr);
+                    result.put("mudWeight", mudWeightArr);
+                    result.put("pollMm", pollMmArr);
+                    result.put("openDepth", openDepthArr);
+                    result.put("ironCosttime", ironCosttimeArr);
 
                     return result;
                 } catch (InterruptedException | ExecutionException e) {
@@ -430,13 +446,13 @@ public class TIronVisualScreenServiceImpl {
         }
     }
 
+
     // 新增工具方法: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());
+                String min = sdfMinute.format(e.getCreateTime());
                 timeValueMap.put(min, e.getData());
             }
         }
@@ -450,14 +466,14 @@ public class TIronVisualScreenServiceImpl {
         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());
+                String min = sdfMinute.format(e.getCreateTime());
                 Object v = e.getData();
                 Double value = null;
                 if (v instanceof Number) value = ((Number) v).doubleValue();
@@ -472,7 +488,7 @@ public class TIronVisualScreenServiceImpl {
         }
         for (IronTrendL1DTO e : speed2List) {
             if (e.getCreateTime() != null) {
-                String min = sdf.format(e.getCreateTime());
+                String min = sdfMinute.format(e.getCreateTime());
                 Object v = e.getData();
                 Double value = null;
                 if (v instanceof Number) value = ((Number) v).doubleValue();
@@ -526,6 +542,8 @@ public class TIronVisualScreenServiceImpl {
             arr.add(java.util.Arrays.asList(t, sum));
             if (sum != null) last = sum;
         }
+
+
         return arr;
     }
 
@@ -571,7 +589,46 @@ public class TIronVisualScreenServiceImpl {
 
 
     // 新增:铁水流量分钟累计显示方法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) {
+    private List<List<Object>> buildIronFlowMinuteArray(List<String> xAxis, Map<String, Integer> tappingMap, List<IronTrendL1DTO> weight1List, List<IronTrendL1DTO> weight2List, int scale) {
+        // 先转为map,key为分钟字符串
+        Map<String, Double> weight1Map = new LinkedHashMap<>();
+        for (IronTrendL1DTO e : weight1List) {
+            if (e.getCreateTime() != null) {
+                String min = sdfMinute.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);
+            }
+        }
+        Map<String, Double> weight2Map = new LinkedHashMap<>();
+        for (IronTrendL1DTO e : weight2List) {
+            if (e.getCreateTime() != null) {
+                String min = sdfMinute.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);
+            }
+        }
         List<List<Object>> arr = new ArrayList<>();
         double accWeight = 0;
         // 1号车状态
@@ -586,60 +643,64 @@ public class TIronVisualScreenServiceImpl {
             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;
+            if (tapping == 1) {
+                // 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;
+                // 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;
-            }
+                // 检查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;
-            }
+                // 归零时把最大值加到累计值
+                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;
+                // tapping=1时,显示accWeight+max(max1,max2)
+                double value = accWeight + Math.max(max1, max2);
+                double factor = Math.pow(10, scale);
+                value = Math.round(value * factor) / factor;
+                arr.add(Arrays.asList(t, value));
             } else {
-                value = 0;
+                // tapping=0时,重置所有累计和周期最大值
+                accWeight = 0;
+                max1 = 0;
+                max2 = 0;
+                inCycle1 = false;
+                inCycle2 = false;
+                double value = 0;
+                arr.add(Arrays.asList(t, value));
             }
-            // 按scale参数四舍五入
-            double factor = Math.pow(10, scale);
-            value = Math.round(value * factor) / factor;
-            arr.add(Arrays.asList(t, value));
             last1 = w1;
             last2 = w2;
         }

+ 18 - 48
taphole-iron/src/main/java/com/sckj/iron/socketio/DeviceEventListener.java

@@ -503,7 +503,13 @@ public class DeviceEventListener extends EventListener { //
                 if (NODE.equalsIgnoreCase(stepDTO.getNodeType())) {
                     //处理子项
                     for (IronStepVO child : stepDTO.getChilds()) {
-                        if (StepConstans.STEP_TLC.equals(child.getIdentifier())) {
+                        if ("glyc".equals(child.getIdentifier())) {
+                            for (IronStepVO grandChild : child.getChilds()) {
+                                if ("ls".equals(grandChild.getIdentifier())) {
+                                    mContext.setVariable("ls",RedisUtils.getFixedLatestElement("materialSpeed"));
+                                }
+                            }
+                        } else  if (StepConstans.STEP_TLC.equals(child.getIdentifier())) {
                             if (latest2DataList.size() >= 2) {
                                 //铁量差 = 理论出铁量 - 实际出铁量
                                 TL2Data tl2Data1Last = latest2DataList.get(0);
@@ -532,6 +538,10 @@ public class DeviceEventListener extends EventListener { //
                                         grandChild.setData(ironWeightLast);
                                     } else if (StepConstans.sscsj.equals(grandChild.getIdentifier())) {
                                         grandChild.setData(ironWeightGrand);
+                                    }else if (StepConstans.sctch.equals(grandChild.getIdentifier())) {
+                                        grandChild.setData(tl2Data1Last.getIronNo());
+                                    }else if (StepConstans.ssctch.equals(grandChild.getIdentifier())) {
+                                        grandChild.setData(tl2Data1Grand.getIronNo());
                                     }
                                 }
 
@@ -629,8 +639,7 @@ public class DeviceEventListener extends EventListener { //
                     //堵口预警
                     String modelExpression1 = modelClosureWarn1.getModelExpression();
                     Expression expression1 = mParser.parseExpression(modelExpression1);
-                    StandardEvaluationContext context = new StandardEvaluationContext();
-                    boolean result1 = expression1.getValue(context, Boolean.class);
+                    boolean result1 = expression1.getValue(mContext, Boolean.class);
                     String modelKey1 = modelClosureWarn1.getModelName();
                     int triggerCount1 = modelClosureWarn1.getTriggerCondCount() != null ? modelClosureWarn1.getTriggerCondCount() : 1;
                     if (result1) {
@@ -652,7 +661,7 @@ public class DeviceEventListener extends EventListener { //
 
                     String modelExpression2 = modelClosureWarn2.getModelExpression();
                     Expression expression2 = mParser.parseExpression(modelExpression2);
-                    boolean result2 = expression2.getValue(context, Boolean.class);
+                    boolean result2 = expression2.getValue(mContext, Boolean.class);
                     String modelKey2 = modelClosureWarn2.getModelName();
                     int triggerCount2 = modelClosureWarn2.getTriggerCondCount() != null ? modelClosureWarn2.getTriggerCondCount() : 1;
                     if (result2) {
@@ -674,7 +683,7 @@ public class DeviceEventListener extends EventListener { //
 
                     String modelExpression3 = modelClosureWarn3.getModelExpression();
                     Expression expression3 = mParser.parseExpression(modelExpression3);
-                    boolean result3 = expression3.getValue(context, Boolean.class);
+                    boolean result3 = expression3.getValue(mContext, Boolean.class);
                     String modelKey3 = modelClosureWarn3.getModelName();
                     int triggerCount3 = modelClosureWarn3.getTriggerCondCount() != null ? modelClosureWarn3.getTriggerCondCount() : 1;
                     if (result3) {
@@ -950,56 +959,18 @@ public class DeviceEventListener extends EventListener { //
                 RealtimeData realtimeData = new RealtimeData();
                 realtimeData.setValue(opcData.getData());
                 realtimeData.setUnit("t/min");
-
-                RealtimeData ironSpeed = (RealtimeData) mRealtimeData.get(IRON_SPEED);
-                List<RealtimeData> speeds = null;
-
-                if (ObjectUtils.isEmpty(ironSpeed)) {
-                    ironSpeed = new RealtimeData();
-                    ironSpeed.setDesc("铁水流速");
-
-                    // 初始化包含两个默认元素的 List
-                    speeds = new ArrayList<>();
-                    speeds.add(null); // index 0
-                    speeds.add(null); // index 1
-
-                    ironSpeed.setValue(speeds);
-                    mRealtimeData.put(IRON_SPEED, ironSpeed);
-                    mRealtimeLegend.put(IRON_SPEED, ironSpeed);
-                } else {
-                    speeds = (List<RealtimeData>) ironSpeed.getValue();
-                }
+                realtimeData.setDesc("铁水流速");
 
                 if (opcData.getPointName().contains(SubscribeTagConstants.TAG_CAR11(opcData.getServerType()))) {
-                    realtimeData.setDesc("1号车");
-                    if (speeds.size() > 0) {
-                        speeds.set(0, realtimeData);
-                    } else {
-                        speeds.add(realtimeData); // 如果不够长度,就添加
-                    }
                     speed1 = new AtomicDouble(Double.parseDouble(opcData.getData().toString()));
                 } else {
-                    realtimeData.setDesc("2号车");
-                    if (speeds.size() > 1) {
-                        speeds.set(1, realtimeData);
-                    } else {
-                        while (speeds.size() < 1) speeds.add(null); // 补足长度
-                        speeds.add(realtimeData);
-                    }
                     speed2 = new AtomicDouble(Double.parseDouble(opcData.getData().toString()));
                 }
                 mMaxSpeed = Math.max(speed1.get(), speed2.get());
                 mContext.setVariable(ExpressionConstants.rtIronSpeed, mMaxSpeed);
 
-                //只在两个都有数据的时候才添加
-                if (ObjectUtils.isNotEmpty(speeds)
-                        && ObjectUtils.isNotEmpty(speeds.get(0)) && ObjectUtils.isNotEmpty(speeds.get(0).getValue())
-                        && ObjectUtils.isNotEmpty(speeds.get(1)) && ObjectUtils.isNotEmpty(speeds.get(1).getValue())
-                ) {
-                    ironSpeed.setTime(LocalDateUtils.formatDate(opcData.getServerTime()));
-                }
-
-
+                mRealtimeData.put(IRON_SPEED, realtimeData);
+                mRealtimeLegend.put(IRON_SPEED, realtimeData);
             } else if (opcData.getPointName().contains(SubscribeTagConstants.TAG_TAPHOLE1_STATUS(opcData.getServerType()))) {
                 RealtimeData realtimeData = new RealtimeData();
                 realtimeData.setValue(opcData.getData());
@@ -1175,7 +1146,7 @@ public class DeviceEventListener extends EventListener { //
         // 实时计算总和并推送
         mTotalWeight = ironWeight11Current.add(ironWeight12Current);
         RealtimeData ironWeight = new RealtimeData();
-        ironWeight.setDesc("铁水累计流量");
+        ironWeight.setDesc("铁水流量");
         ironWeight.setUnit("t");
         ironWeight.setValue(mTotalWeight);
         ironWeight.setTime(LocalDateUtils.formatDate(opcData.getServerTime()));
@@ -1448,7 +1419,6 @@ public class DeviceEventListener extends EventListener { //
             stepDTO.setData(message.getData());
 
             if (Objects.equals("001001", stepDTO.getStepId())
-                    && Objects.equals("ylgc", stepDTO.getIdentifier())
                     && Objects.equals(1, stepDTO.getData())
             ) {
                 stepLogId = UUID.randomUUID().toString().replace("-", "");

+ 1 - 1
taphole-iron/src/main/java/com/sckj/iron/vo/IronStepVO.java

@@ -37,7 +37,7 @@ public class IronStepVO {
     private String stepCondition;
 
     //
-    @ApiModelProperty(value = "通过结果(1通过、0未通过)")
+    @ApiModelProperty(value = "通过结果(1通过、0未通过)")
     private int passResult;
 
     @ApiModelProperty(value = "确认方式(1自动 2手动)")

+ 5 - 46
taphole-l2/src/main/java/com/sckj/l2/service/impl/TL2DataServiceImpl.java

@@ -9,6 +9,7 @@ import com.sckj.common.core.PageResult;
 import com.sckj.common.exception.OperateException;
 import com.sckj.common.util.ExcelUtils;
 import com.sckj.common.util.StringUtils;
+import com.sckj.common.util.TimeUtils;
 import com.sckj.common.validate.commons.PageValidate;
 import com.sckj.l2.entity.TL2Data;
 import com.sckj.l2.mapper.TL2DataMapper;
@@ -63,56 +64,14 @@ public class TL2DataServiceImpl extends ServiceImpl<TL2DataMapper, TL2Data> {
         for (TL2Data item : iPage.getRecords()) {
             TL2DataListedVo vo = new TL2DataListedVo();
             BeanUtils.copyProperties(item, vo);
-            vo.setIronStarttime(formatPartialDateString(vo.getIronStarttime()));
-            vo.setIronEndtime(formatPartialDateString(vo.getIronEndtime()));
+            vo.setIronStarttime(TimeUtils.formatPartialDateString(vo.getIronStarttime()));
+            vo.setIronEndtime(TimeUtils.formatPartialDateString(vo.getIronEndtime()));
             list.add(vo);
         }
 
         return PageResult.iPageHandle(iPage.getTotal(), iPage.getCurrent(), iPage.getSize(), list);
     }
 
-    public static String formatPartialDateString(String input) {
-        if (input == null || input.isEmpty()) {
-            return "";
-        }
-
-        StringBuilder result = new StringBuilder();
-        int len = input.length();
-
-        // 年 (yyyy)
-        if (len >= 4) {
-            result.append(input.substring(0, 4));
-        } else {
-            return input; // 不足4位直接返回原字符串
-        }
-
-        // 月 (MM)
-        if (len >= 6) {
-            result.append("-").append(input.substring(4, 6));
-        }
-
-        // 日 (dd)
-        if (len >= 8) {
-            result.append("-").append(input.substring(6, 8));
-        }
-
-        // 时 (HH)
-        if (len >= 10) {
-            result.append(" ").append(input.substring(8, 10));
-        }
-
-        // 分 (mm)
-        if (len >= 12) {
-            result.append(":").append(input.substring(10, 12));
-        }
-
-        // 秒 (ss)
-        if (len >= 14) {
-            result.append(":").append(input.substring(12, 14));
-        }
-
-        return result.toString();
-    }
 
     /**
      * 出铁数据详情
@@ -131,8 +90,8 @@ public class TL2DataServiceImpl extends ServiceImpl<TL2DataMapper, TL2Data> {
 
         TL2DataDetailVo vo = new TL2DataDetailVo();
         BeanUtils.copyProperties(model, vo);
-        vo.setIronStarttime(formatPartialDateString(vo.getIronStarttime()));
-        vo.setIronEndtime(formatPartialDateString(vo.getIronEndtime()));
+        vo.setIronStarttime(TimeUtils.formatPartialDateString(vo.getIronStarttime()));
+        vo.setIronEndtime(TimeUtils.formatPartialDateString(vo.getIronEndtime()));
         return vo;
     }
 

+ 1 - 0
taphole-opc/src/main/java/com/sckj/opc/dataservice/OPCDAServiceImpl.java

@@ -226,6 +226,7 @@ public class OPCDAServiceImpl {
                                             .pointName(pointName)
                                             .dataType(opcPoint.getDataType())
                                             .identifier(opcPoint.getIdentifier())
+                                            .saveDb(opcPoint.getSaveDb())
                                             .build();
                                     //post给其他模块使用
                                     asyncEventBus.post(opcData);