wangxiaofei пре 2 недеља
родитељ
комит
33c6993532

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

@@ -1,6 +1,7 @@
 package com.sckj.iron.controller;
 
 import com.sckj.common.aop.Log;
+import com.sckj.common.aop.NotPower;
 import com.sckj.common.core.AjaxResult;
 import com.sckj.common.core.PageResult;
 import com.sckj.common.validate.commons.IdValidate;
@@ -66,6 +67,14 @@ public class TIronTestController {
         return AjaxResult.success();
     }
 
+    @Log(title = "出铁诊断刷新")
+    @PostMapping("/refreshIronTest")
+    @ApiOperation(value="出铁诊断更新")
+    @NotPower
+    public AjaxResult<Object> refreshIronTest(int type, String startTime, String endTime) {
+        iTIronTestService.refreshIronTest(type,startTime,endTime);
+        return AjaxResult.success();
+    }
 
 
 }

+ 12 - 5
taphole-iron/src/main/java/com/sckj/iron/dto/TIronTestDTO.java

@@ -3,12 +3,19 @@ package com.sckj.iron.dto;
 import com.alibaba.excel.annotation.ExcelIgnore;
 import com.alibaba.excel.annotation.ExcelProperty;
 import com.alibaba.excel.annotation.write.style.ColumnWidth;
+import com.alibaba.excel.annotation.write.style.HeadFontStyle;
+import com.alibaba.excel.annotation.write.style.HeadRowHeight;
+import com.alibaba.excel.annotation.write.style.HeadStyle;
+import com.alibaba.excel.enums.poi.FillPatternTypeEnum;
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
 
 import java.io.Serializable;
 
+@HeadStyle(fillPatternType = FillPatternTypeEnum.NO_FILL,fillForegroundColor = -1)
+@HeadFontStyle(fontHeightInPoints = 16)
+@HeadRowHeight(40)
 @Data
 @ApiModel("出铁诊断实体")
 public class TIronTestDTO implements Serializable {
@@ -20,11 +27,7 @@ public class TIronTestDTO implements Serializable {
     @ColumnWidth(25)
     private String tapholeId;
 
-    @ApiModelProperty(value = "出铁详情")
-    @ExcelIgnore
-    private String ironDetail;
-
-    @ApiModelProperty(value = "出铁时间")
+    @ApiModelProperty(value = "出铁量")
     @ExcelProperty("出铁量(t)")
     @ColumnWidth(30)
     private String ironWeight;
@@ -54,4 +57,8 @@ public class TIronTestDTO implements Serializable {
     @ColumnWidth(30)
     private String createTime;
 
+    @ApiModelProperty(value = "出铁详情")
+    @ExcelIgnore
+    private String ironDetail;
+
 }

+ 3 - 0
taphole-iron/src/main/java/com/sckj/iron/entity/TIronTest.java

@@ -89,4 +89,7 @@ public class TIronTest implements Serializable {
     @ColumnWidth(30)
     private String createTime;
 
+    @ApiModelProperty(value = "实时出铁编号")
+    private String ironDataId;
+
 }

+ 271 - 5
taphole-iron/src/main/java/com/sckj/iron/service/impl/TIronTestServiceImpl.java

@@ -1,16 +1,19 @@
 package com.sckj.iron.service.impl;
 
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.github.pagehelper.PageHelper;
 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.*;
 import com.sckj.common.validate.commons.PageValidate;
+import com.sckj.iron.constant.ParamsConstants;
+import com.sckj.iron.dto.IronTestItem;
 import com.sckj.iron.dto.TIronTestDTO;
+import com.sckj.iron.entity.TIronParam;
 import com.sckj.iron.entity.TIronTest;
 import com.sckj.iron.mapper.TIronTestMapper;
 import com.sckj.iron.validate.TIronTestCreateValidate;
@@ -19,6 +22,9 @@ import com.sckj.iron.validate.TIronTestSearchValidate;
 import com.sckj.iron.validate.TIronTestUpdateValidate;
 import com.sckj.iron.vo.TIronTestDetailVo;
 import com.sckj.iron.vo.TIronTestListedVo;
+import com.sckj.l2.entity.TL2Data;
+import com.sckj.l2.service.impl.TL2DataServiceImpl;
+import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.ObjectUtils;
 import org.springframework.beans.BeanUtils;
 import org.springframework.stereotype.Service;
@@ -27,8 +33,10 @@ import org.springframework.util.Assert;
 import javax.annotation.Resource;
 import javax.servlet.http.HttpServletResponse;
 import java.io.IOException;
-import java.util.LinkedList;
-import java.util.List;
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+import java.util.*;
+import java.util.stream.Collectors;
 
 /**
  * 出铁诊断实现类
@@ -36,6 +44,7 @@ import java.util.List;
  * @author LikeAdmin
  */
 @Service
+@Slf4j
 public class TIronTestServiceImpl extends ServiceImpl<TIronTestMapper, TIronTest> {
 
     @Resource
@@ -156,7 +165,7 @@ public class TIronTestServiceImpl extends ServiceImpl<TIronTestMapper, TIronTest
     }
 
     public TIronTest getLatest() {
-        return this.lambdaQuery().orderByDesc(TIronTest::getCreateTime).list().stream().findFirst().orElseThrow(()->new OperateException("未查询到数据"));
+        return this.lambdaQuery().orderByDesc(TIronTest::getCreateTime).list().stream().findFirst().orElseThrow(() -> new OperateException("未查询到数据"));
     }
 
 
@@ -206,4 +215,261 @@ public class TIronTestServiceImpl extends ServiceImpl<TIronTestMapper, TIronTest
     }
 
 
+    @Resource
+    TIronParamServiceImpl ironParamService;
+
+    @Resource
+    TL2DataServiceImpl tl2DataService;
+
+    public void refreshIronTest(Integer type, String startTime, String endTime) {
+        if (ObjectUtils.isEmpty(type)) {
+            throw new OperateException("type必传,传0(更新本表)或者1(将L2更新过来)!");
+        }
+        if (ObjectUtils.isEmpty(startTime) || ObjectUtils.isEmpty(endTime)) {
+            throw new OperateException("请选择开始时间和结束时间!");
+        }
+
+        //将L2的数据添加到诊断中
+        Map<String, String> mIronParams = ironParamService.lambdaQuery().eq(TIronParam::getStatus, "1").in(TIronParam::getParamType, "iron_judge").orderByAsc(TIronParam::getSort).list()
+                .stream().collect(Collectors.toMap(
+                        TIronParam::getParamName,
+                        TIronParam::getParamValue,
+                        (existing, replacement) -> existing // 合并函数
+                ));
+
+        switch (type) {
+            case 0:
+                //将诊断详情中的数据复制到各个项目中
+                QueryWrapper<TIronTest> queryWrapper = new QueryWrapper<>();
+                queryWrapper.lambda()
+                        .between(TIronTest::getCreateTime, startTime, endTime)
+                        .orderByDesc(TIronTest::getCreateTime);
+                List<TIronTest> list = list(queryWrapper);
+                for (TIronTest ironTest : list) {
+                    String ironDetail = ironTest.getIronDetail();
+                    if (ObjectUtils.isNotEmpty(ironDetail)) {
+                        LambdaUpdateWrapper<TIronTest> updateWrapper = new LambdaUpdateWrapper<>();
+                        updateWrapper.eq(TIronTest::getId, ironTest.getId());
+                        List<IronTestItem> ironTestItems = GsonUtils.fromJsonToList(ironDetail, IronTestItem.class);
+
+                        int ironCosttime = 0;
+                        double ironWeight = 0;
+                        double avgSpeed = 0;
+                        double avgTemp = 0;
+
+                        for (IronTestItem ironTestItem : ironTestItems) {
+                            switch (ironTestItem.getTypeName()) {
+                                case "出铁量":
+                                    ironWeight = (double) ironTestItem.getValue();
+                                    break;
+                                case "出铁时间":
+                                    ironCosttime = (int) ironTestItem.getValue();
+                                    break;
+                                case "铁水平均流速":
+                                    avgSpeed = new BigDecimal(String.valueOf(ironTestItem.getValue())).setScale(2, RoundingMode.HALF_UP).doubleValue();
+                                    break;
+                                case "铁水平均温度":
+                                    avgTemp = (double) ironTestItem.getValue();
+                                    break;
+                                default:
+                                    System.out.println("编号:" + ironTest.getId() + "," + "未确认的类型:" + ironTestItem.getTypeName() + ",值:" + ironTestItem.getValue());
+                                    break;
+                            }
+                        }
+                        //按照主键每个更新
+
+                        TIronTest updateInfo = runnableTappingTest(mIronParams, ironCosttime, ironWeight, avgSpeed, avgTemp, null,null);
+                        updateInfo.setId(ironTest.getId());
+                        boolean saveResult = updateById(updateInfo);
+                        log.info("💾 诊断结果更新{} - 记录ID: {}", saveResult ? "成功" : "失败", updateInfo.getId());
+                        log.info("🔬 ====== 出铁诊断分析完成 ======");
+                    }
+                }
+
+                break;
+            case 1:
+                //将L2的数据添加到诊断中
+
+                List<TL2Data> list1 = tl2DataService.lambdaQuery().between(TL2Data::getCreateTime, startTime, endTime)
+                        .orderByDesc(TL2Data::getCreateTime).list();
+
+                //删除这个时间段的数据
+                LambdaUpdateWrapper<TIronTest> deleteWrapper = new LambdaUpdateWrapper<>();
+                deleteWrapper.between(TIronTest::getCreateTime, startTime, endTime);
+                update(deleteWrapper);
+
+                for (TL2Data tl2Data : list1) {
+                    double ironWeight = tl2Data.getCalcWeight();
+                    int ironCosttime = tl2Data.getIronCosttime();
+                    double avgTemp = tl2Data.getAvgTemp();
+                    double avgSpeed = BigDecimal.valueOf(ironWeight).divide(BigDecimal.valueOf(ironCosttime), 2, BigDecimal.ROUND_HALF_UP).doubleValue();
+                    TIronTest ironTest = runnableTappingTest(mIronParams, ironCosttime, ironWeight, avgSpeed, avgTemp, tl2Data.getIronNo(),tl2Data.getCreateTime());
+                    boolean saveResult = save(ironTest);
+                    log.info("💾 诊断结果保存{} - 记录ID: {}", saveResult ? "成功" : "失败", ironTest.getId());
+                    log.info("🔬 ====== 出铁诊断分析完成 ======");
+                }
+                break;
+        }
+    }
+
+
+    private TIronTest runnableTappingTest(Map<String, String> mIronParams, int actualIronTime, double actualIronWeight, double actualIronSpeed, double avgTemp, Long ironNo, Date createTime) {
+        try {
+            // 获取诊断标准参数
+            log.info("📊 获取诊断标准参数...");
+            String standardSpeed = mIronParams.get(ParamsConstants.iron_speed);
+            String standardIronTime = mIronParams.get(ParamsConstants.iron_time);
+            String standardTemp = mIronParams.get(ParamsConstants.ironwater_temp);
+            String standardIronWeight = mIronParams.get(ParamsConstants.iron_weight);
+            Integer standardOpenHour = Integer.parseInt(ParamsConstants.open_hour);
+            double stdIronSpeedMin = Double.parseDouble(standardSpeed.split("-")[0]);
+            double stdIronSpeedMax = Double.parseDouble(standardSpeed.split("-")[1]);
+            int stdIronTimeMin = Integer.parseInt(standardIronTime.split("-")[0]);
+            int stdIronTimeMax = Integer.parseInt(standardIronTime.split("-")[1]);
+            int stdTempMin = Integer.parseInt(standardTemp.split("-")[0]);
+            int stdTempMax = Integer.parseInt(standardTemp.split("-")[1]);
+            double stdIronWeightMin = Double.parseDouble(standardIronWeight.split("-")[0]);
+            double stdIronWeightMax = Double.parseDouble(standardIronWeight.split("-")[1]);
+
+            log.info("✅ 标准参数获取完成:");
+            log.info("   出铁时间范围: {}-{} 分钟", stdIronTimeMin, stdIronTimeMax);
+            log.info("   出铁重量范围: {}-{} 吨", stdIronWeightMin, stdIronWeightMax);
+            log.info("   铁水流速范围: {}-{} t/min", stdIronSpeedMin, stdIronSpeedMax);
+            log.info("   铁水温度范围: {}-{} ℃", stdTempMin, stdTempMax);
+
+            log.info("📈 实际出铁数据统计:");
+            log.info("   出铁时长: {} 分钟", actualIronTime);
+            log.info("   总出铁量: {} 吨", actualIronWeight);
+            log.info("   平均流速: {} t/min", String.format("%.2f", actualIronSpeed));
+            log.info("   平均温度: {} ℃", avgTemp);
+
+            // 诊断分析
+            int ironNormalCount = 0;
+            StringBuilder sb = new StringBuilder();
+            final String ironTimeTip = "出铁时间";
+            final String ironWeightTip = "出铁量";
+            final String ironSpeedTip = "铁水平均流速";
+            final String ironTempTip = "铁水平均温度";
+
+            IronTestItem.IronTestItemBuilder ironTime = IronTestItem.builder()
+                    .unit("min").typeName(ironTimeTip).status(1)
+                    .value(actualIronTime).desc(ironTimeTip + "正常");
+            IronTestItem.IronTestItemBuilder ironWeight = IronTestItem.builder()
+                    .unit("t").typeName(ironWeightTip).status(1)
+                    .value(actualIronWeight).desc(ironWeightTip + "正常");
+            IronTestItem.IronTestItemBuilder ironSpeed = IronTestItem.builder()
+                    .unit("t/min").typeName(ironSpeedTip).status(1)
+                    .value(actualIronSpeed).desc(ironSpeedTip + "正常");
+            IronTestItem.IronTestItemBuilder ironTemp = IronTestItem.builder()
+                    .unit("℃").typeName(ironTempTip).status(1)
+                    .value(avgTemp).desc(ironTempTip + "正常");
+
+            // 出铁时间诊断
+            if (actualIronTime < stdIronTimeMin) {
+                sb.append(ironTimeTip).append("过短,");
+                ironTime.status(0).desc(ironTimeTip + "过短");
+                log.warn("⚠️ 出铁时间异常: 实际 {} 分钟 < 标准最小 {} 分钟", actualIronTime, stdIronTimeMin);
+            } else if (actualIronTime > stdIronTimeMax) {
+                sb.append(ironTimeTip).append("过长,");
+                ironTime.status(0).desc(ironTimeTip + "过长");
+                log.warn("⚠️ 出铁时间异常: 实际 {} 分钟 > 标准最大 {} 分钟", actualIronTime, stdIronTimeMax);
+            } else {
+                sb.append(ironTimeTip).append("正常,");
+                ironTime.status(1).desc(ironTimeTip + "正常");
+                ironNormalCount++;
+                log.info("✅ 出铁时间正常: {} 分钟", actualIronTime);
+            }
+
+            // 出铁重量诊断
+            if (actualIronWeight < stdIronWeightMin) {
+                sb.append(ironWeightTip).append("过少,");
+                ironWeight.status(0).desc(ironWeightTip + "过少");
+                log.warn("⚠️ 出铁重量异常: 实际 {} 吨 < 标准最小 {} 吨", actualIronWeight, stdIronWeightMin);
+            } else if (actualIronWeight > stdIronWeightMax) {
+                sb.append(ironWeightTip).append("过多,");
+                ironWeight.status(0).desc(ironWeightTip + "过多");
+                log.warn("⚠️ 出铁重量异常: 实际 {} 吨 > 标准最大 {} 吨", actualIronWeight, stdIronWeightMax);
+            } else {
+                sb.append(ironWeightTip).append("正常,");
+                ironWeight.status(1).desc(ironWeightTip + "正常");
+                ironNormalCount++;
+                log.info("✅ 出铁重量正常: {} 吨", actualIronWeight);
+            }
+
+            // 铁水流速诊断
+            if (actualIronSpeed < stdIronSpeedMin) {
+                sb.append(ironSpeedTip).append("过慢,");
+                ironSpeed.status(0).desc(ironSpeedTip + "过慢");
+                log.warn("⚠️ 铁水流速异常: 实际 {} t/min < 标准最小 {} t/min",
+                        String.format("%.2f", actualIronSpeed), stdIronSpeedMin);
+            } else if (actualIronSpeed > stdIronSpeedMax) {
+                sb.append(ironSpeedTip).append("过快,");
+                ironSpeed.status(0).desc(ironSpeedTip + "过快");
+                log.warn("⚠️ 铁水流速异常: 实际 {} t/min > 标准最大 {} t/min",
+                        String.format("%.2f", actualIronSpeed), stdIronSpeedMax);
+            } else {
+                sb.append(ironSpeedTip).append("正常,");
+                ironSpeed.status(1).desc(ironSpeedTip + "正常");
+                ironNormalCount++;
+                log.info("✅ 铁水流速正常: {} t/min", String.format("%.2f", actualIronSpeed));
+            }
+
+            // 铁水温度诊断
+            if (avgTemp < stdTempMin) {
+                sb.append(ironTempTip).append("过低。");
+                ironTemp.status(0).desc(ironTempTip + "过低");
+                log.warn("⚠️ 铁水温度异常: 实际 {} ℃ < 标准最小 {} ℃", avgTemp, stdTempMin);
+            } else if (avgTemp > stdTempMax) {
+                sb.append(ironTempTip).append("过高。");
+                ironTemp.status(0).desc(ironTempTip + "过高");
+                log.warn("⚠️ 铁水温度异常: 实际 {} ℃ > 标准最大 {} ℃", avgTemp, stdTempMax);
+            } else {
+                sb.append(ironTempTip).append("正常。");
+                ironTemp.status(1).desc(ironTempTip + "正常");
+                ironNormalCount++;
+                log.info("✅ 铁水温度正常: {} ℃", avgTemp);
+            }
+
+            // 生成诊断结果
+            TIronTest ironTest = new TIronTest();
+            ironTest.setTapholeId("1");
+            ironTest.setAvgSpeed(actualIronSpeed + "");
+            ironTest.setAvgTemp(avgTemp + "");
+            ironTest.setIronWeight(actualIronWeight + "");
+            ironTest.setIronCosttime(actualIronTime);
+            if (ObjectUtils.isNotEmpty(ironNo)) {
+                ironTest.setIronNo(String.valueOf(ironNo));
+            }
+            if (ObjectUtils.isNotEmpty(createTime)) {
+                ironTest.setCreateTime(LocalDateUtils.formatDate(createTime));
+            }
+
+            String testStatus = (ironNormalCount >= 4) ? "1" : "0";
+            ironTest.setTestStatus(testStatus);
+            ironTest.setTestDesc(sb.toString());
+
+
+            List<IronTestItem> ironTestList = new ArrayList<>();
+            ironTestList.add(ironWeight.build());
+            ironTestList.add(ironTime.build());
+            ironTestList.add(ironSpeed.build());
+            ironTestList.add(ironTemp.build());
+
+            String ironDetailJson = GsonUtils.toJson(ironTestList);
+            ironTest.setIronDetail(ironDetailJson);
+
+            log.info("📊 诊断结果汇总:");
+            log.info("   正常指标数: {}/4", ironNormalCount);
+            log.info("   整体状态: {}", "1".equals(testStatus) ? "优秀" : "异常");
+            log.info("   详细诊断: {}", sb.toString());
+
+            return ironTest;
+
+        } catch (Exception e) {
+            log.error("❌ 出铁诊断分析异常", e);
+            e.printStackTrace();
+        }
+        return null;
+    }
+
 }

+ 201 - 118
taphole-iron/src/main/java/com/sckj/iron/socketio/DeviceEventListener.java

@@ -236,8 +236,6 @@ public class DeviceEventListener extends AbstractEventListener { //
     //redis保存最多数量数据
     private static final int MAX_REDIS_COUNT = 50;
 
-    //上次出铁量
-//    private OPCData mIronOPCData;
 
     //实时出铁数据
     private TIronData mTIronData;
@@ -275,6 +273,9 @@ public class DeviceEventListener extends AbstractEventListener { //
     //是否出渣,默认不出渣
     private AtomicBoolean isChuz = new AtomicBoolean(Boolean.FALSE);
 
+    //是否已到堵口时间,默认未到堵口时间
+    private AtomicBoolean isClosureTime = new AtomicBoolean(Boolean.FALSE);
+
 
     //系统启动后
     @EventListener(ApplicationReadyEvent.class)
@@ -348,43 +349,42 @@ public class DeviceEventListener extends AbstractEventListener { //
      * 出铁参数
      */
     private void getIronParams() {
-        List<TIronParam> mIronParams = ironParamService.lambdaQuery().eq(TIronParam::getStatus, "1").in(TIronParam::getParamType, "iron_judge", "iron_judge_extra", "server_info").orderByAsc(TIronParam::getSort).list();
-        if (ObjectUtils.isNotEmpty(mIronParams)) {
-            for (TIronParam mIronParam : mIronParams) {
-                if (Objects.equals(mIronParam.getParamName(), ParamsConstants.iron_speed)) {
-                    StandardConstans.STANDARD_SPEED = mIronParam.getParamValue();
-                    mContext.setVariable(ExpressionConstants.stdSpeedMin, Double.parseDouble(StandardConstans.STANDARD_SPEED.split("-")[0]));
-                    mContext.setVariable(ExpressionConstants.stdSpeedMax, Double.parseDouble(StandardConstans.STANDARD_SPEED.split("-")[1]));
-                } else if (Objects.equals(mIronParam.getParamName(), ParamsConstants.pressure_diff_value)) {
-                    StandardConstans.STANDARD_PRESSURE_DIFF = Double.parseDouble(mIronParam.getParamValue());
-                    mContext.setVariable(ExpressionConstants.stdPressureDiff, StandardConstans.STANDARD_PRESSURE_DIFF);
-                } else if (Objects.equals(mIronParam.getParamName(), ParamsConstants.iron_time)) {
-                    StandardConstans.STANDARD_IRON_TIME = mIronParam.getParamValue();
-                    mContext.setVariable(ExpressionConstants.stdIronTimeMin, Integer.parseInt(StandardConstans.STANDARD_IRON_TIME.split("-")[0]));
-                    mContext.setVariable(ExpressionConstants.stdIronTimeMax, Integer.parseInt(StandardConstans.STANDARD_IRON_TIME.split("-")[1]));
-                } else if (Objects.equals(mIronParam.getParamName(), ParamsConstants.server_url)) {
-                    SERVER_URL = mIronParam.getParamValue();
-                    mContext.setVariable(ExpressionConstants.stdServerUrl, SERVER_URL);
-                } else if (Objects.equals(mIronParam.getParamName(), ParamsConstants.ironwater_temp)) {
-                    StandardConstans.STANDARD_TEMP = mIronParam.getParamValue();
-                    mContext.setVariable(ExpressionConstants.stdTempMin, Integer.parseInt(StandardConstans.STANDARD_TEMP.split("-")[0]));
-                    mContext.setVariable(ExpressionConstants.stdTempMax, Integer.parseInt(StandardConstans.STANDARD_TEMP.split("-")[1]));
-                } else if (Objects.equals(mIronParam.getParamName(), ParamsConstants.open_hour)) {
-                    StandardConstans.STANDARD_OPEN_HOUR = Integer.parseInt(mIronParam.getParamValue());
-                    mContext.setVariable(ExpressionConstants.stdOpenHour, StandardConstans.STANDARD_OPEN_HOUR);
-                } else if (Objects.equals(mIronParam.getParamName(), ParamsConstants.iron_weight)) {
-                    StandardConstans.STANDARD_IRON_WEIGHT = mIronParam.getParamValue();
-                    mContext.setVariable(ExpressionConstants.stdIronWeightMin, Double.parseDouble(StandardConstans.STANDARD_IRON_WEIGHT.split("-")[0]));
-                    mContext.setVariable(ExpressionConstants.stdIronWeightMax, Double.parseDouble(StandardConstans.STANDARD_IRON_WEIGHT.split("-")[1]));
-                } else if (Objects.equals(mIronParam.getParamName(), ParamsConstants.open_machine_value)) {
-                    StandardConstans.STANDARD_OPEN_MACHINE_LOCATION = Double.parseDouble(mIronParam.getParamValue());
-                } else if (Objects.equals(mIronParam.getParamName(), ParamsConstants.mud_machine_value)) {
-                    StandardConstans.STANDARD_MUD_MACHINE_PRESSURE = Double.parseDouble(mIronParam.getParamValue());
-                }else if (Objects.equals(mIronParam.getParamName(), ParamsConstants.warn_count)) {
-                    StandardConstans.WARN_COUNT = Integer.parseInt(mIronParam.getParamValue());
-                }
-            }
-        }
+        Map<String, String> mIronParams = ironParamService.lambdaQuery().eq(TIronParam::getStatus, "1").in(TIronParam::getParamType, "iron_judge", "iron_judge_extra", "server_info").orderByAsc(TIronParam::getSort).list()
+                .stream().collect(Collectors.toMap(
+                        TIronParam::getParamName,
+                        TIronParam::getParamValue,
+                        (existing, replacement) -> existing // 合并函数
+                ));
+
+        StandardConstans.STANDARD_SPEED = mIronParams.get(ParamsConstants.iron_speed);
+        mContext.setVariable(ExpressionConstants.stdSpeedMin, Double.parseDouble(StandardConstans.STANDARD_SPEED.split("-")[0]));
+        mContext.setVariable(ExpressionConstants.stdSpeedMax, Double.parseDouble(StandardConstans.STANDARD_SPEED.split("-")[1]));
+
+        StandardConstans.STANDARD_IRON_TIME = mIronParams.get(ParamsConstants.iron_time);
+        mContext.setVariable(ExpressionConstants.stdIronTimeMin, Integer.parseInt(StandardConstans.STANDARD_IRON_TIME.split("-")[0]));
+        mContext.setVariable(ExpressionConstants.stdIronTimeMax, Integer.parseInt(StandardConstans.STANDARD_IRON_TIME.split("-")[1]));
+
+        StandardConstans.STANDARD_TEMP = mIronParams.get(ParamsConstants.ironwater_temp);
+        mContext.setVariable(ExpressionConstants.stdTempMin, Integer.parseInt(StandardConstans.STANDARD_TEMP.split("-")[0]));
+        mContext.setVariable(ExpressionConstants.stdTempMax, Integer.parseInt(StandardConstans.STANDARD_TEMP.split("-")[1]));
+
+        StandardConstans.STANDARD_IRON_WEIGHT = mIronParams.get(ParamsConstants.iron_weight);
+        mContext.setVariable(ExpressionConstants.stdIronWeightMin, Double.parseDouble(StandardConstans.STANDARD_IRON_WEIGHT.split("-")[0]));
+        mContext.setVariable(ExpressionConstants.stdIronWeightMax, Double.parseDouble(StandardConstans.STANDARD_IRON_WEIGHT.split("-")[1]));
+
+        StandardConstans.STANDARD_OPEN_HOUR = Integer.parseInt(ParamsConstants.open_hour);
+        mContext.setVariable(ExpressionConstants.stdOpenHour, StandardConstans.STANDARD_OPEN_HOUR);
+
+        StandardConstans.STANDARD_PRESSURE_DIFF = Double.parseDouble(mIronParams.get(ParamsConstants.pressure_diff_value));
+        mContext.setVariable(ExpressionConstants.stdPressureDiff, StandardConstans.STANDARD_PRESSURE_DIFF);
+
+        SERVER_URL = mIronParams.get(ParamsConstants.server_url);
+        mContext.setVariable(ExpressionConstants.stdServerUrl, SERVER_URL);
+
+        StandardConstans.STANDARD_OPEN_MACHINE_LOCATION = Double.parseDouble(mIronParams.get(ParamsConstants.open_machine_value));
+        StandardConstans.STANDARD_MUD_MACHINE_PRESSURE = Double.parseDouble(mIronParams.get(ParamsConstants.mud_machine_value));
+        StandardConstans.WARN_COUNT = Integer.parseInt(mIronParams.get(ParamsConstants.warn_count));
+
     }
 
     /***
@@ -405,7 +405,6 @@ public class DeviceEventListener extends AbstractEventListener { //
      */
     @Subscribe
     public void onMessageEvent(OPCData opcData) {
-       // log.info("subscribe info:{}", opcData);
 
         if (ObjectUtils.isNotEmpty(opcData) && ObjectUtils.isNotEmpty(opcData.getIdentifier())) {
             //将每一个opc配置的唯一编号添加到环境变量中,方便在表达式中使用
@@ -492,7 +491,6 @@ public class DeviceEventListener extends AbstractEventListener { //
                 mTIronData.getIronStarttime());
 
 
-
     }
 
     private AtomicDouble mLastSpeed = new AtomicDouble(0);
@@ -536,15 +534,15 @@ public class DeviceEventListener extends AbstractEventListener { //
                             if (latest2DataList.size() >= 2) {
                                 //铁量差 = 理论出铁量 - 实际出铁量
                                 TL2Data tl2Data1Last = latest2DataList.get(0);
-                                BigDecimal theoryWeightLast = new BigDecimal(tl2Data1Last.getTheoryWeight()).setScale(2, RoundingMode.HALF_UP);
-                                BigDecimal ironWeightLast = new BigDecimal(tl2Data1Last.getIronWeight()).setScale(2, RoundingMode.HALF_UP);
+                                BigDecimal theoryWeightLast = BigDecimal.valueOf(tl2Data1Last.getTheoryWeight()).setScale(2, RoundingMode.HALF_UP);
+                                BigDecimal ironWeightLast = BigDecimal.valueOf(tl2Data1Last.getIronWeight()).setScale(2, RoundingMode.HALF_UP);
                                 BigDecimal tlcLast = theoryWeightLast.subtract(ironWeightLast).setScale(2, RoundingMode.HALF_UP);
 
                                 TL2Data tl2Data1Grand = latest2DataList.get(1);
                                 //
-                                BigDecimal theoryWeightGrand = new BigDecimal(tl2Data1Grand.getTheoryWeight()).setScale(2, RoundingMode.HALF_UP);
+                                BigDecimal theoryWeightGrand = BigDecimal.valueOf(tl2Data1Grand.getTheoryWeight()).setScale(2, RoundingMode.HALF_UP);
                                 //
-                                BigDecimal ironWeightGrand = new BigDecimal(tl2Data1Grand.getIronWeight()).setScale(2, RoundingMode.HALF_UP);
+                                BigDecimal ironWeightGrand = BigDecimal.valueOf(tl2Data1Grand.getIronWeight()).setScale(2, RoundingMode.HALF_UP);
 
                                 BigDecimal tlcGrand = theoryWeightGrand.subtract(ironWeightGrand).setScale(2, RoundingMode.HALF_UP);
 
@@ -623,19 +621,27 @@ public class DeviceEventListener extends AbstractEventListener { //
      * 剩余出铁时间 = (理论铁量(1300)-累计出铁量)/流速
      */
     private void getCloseTime() {
-        if(ironLoading1.get() <= 0){
+        log.info("开始计算预计剩余出铁时间");
+
+        if (ironLoading1.get() <= 0) {
+            log.info("当前铁口状态: 非出铁状态, 跳过计算");
             return;
         }
+
         RealtimeData realtimeData = new RealtimeData();
         realtimeData.setDesc("距离堵口预计还剩");
         realtimeData.setUnit("分钟");
         int diffCloseTime = 0;
+
         //实时出铁时间
         int ironElapsedMinute = getIronElapsedMinute();
+        log.info("当前已出铁时间: {}分钟", ironElapsedMinute);
 
-        if(ironElapsedMinute <= 0){
+        if (ironElapsedMinute <= 0) {
+            log.info("出铁时间小于等于0, 无法计算剩余时间, 设置剩余时间为0");
             realtimeData.setValue(diffCloseTime);
             PushData.send2CloseTime(realtimeData);
+            log.info("推送剩余出铁时间数据完成, 剩余时间: {}分钟", diffCloseTime);
             return;
         }
 
@@ -647,15 +653,37 @@ public class DeviceEventListener extends AbstractEventListener { //
         BigDecimal avgSpeed = totalWeight.divide(BigDecimal.valueOf(ironElapsedMinute), 2, RoundingMode.HALF_UP);
         //剩余重量
         BigDecimal diffWeight = BigDecimal.valueOf(Math.max(stdIronWeightMax - totalWeight.doubleValue(), 0));
-        if(avgSpeed.compareTo(BigDecimal.ZERO) <= 0){
+
+        log.info("剩余时间计算参数: 标准最大铁量={}吨, 当前总铁量={}吨, 平均流速={}吨/分钟, 剩余铁量={}吨",
+                stdIronWeightMax, totalWeight, avgSpeed, diffWeight);
+
+        if (avgSpeed.compareTo(BigDecimal.ZERO) <= 0) {
+            log.warn("平均流速小于等于0 ({}/分钟), 无法计算剩余时间, 设置剩余时间为0", avgSpeed);
             realtimeData.setValue(diffCloseTime);
             PushData.send2CloseTime(realtimeData);
+            log.info("推送剩余出铁时间数据完成, 剩余时间: {}分钟", diffCloseTime);
             return;
         }
+
         //计算剩余时间
         diffCloseTime = diffWeight.divide(avgSpeed, 2, RoundingMode.HALF_UP).intValue();
+        log.info("剩余出铁时间计算完成: {}分钟", diffCloseTime);
+
         realtimeData.setValue(diffCloseTime);
         PushData.send2CloseTime(realtimeData);
+        log.info("推送剩余出铁时间数据完成");
+
+        //堵口前30分钟左右,计算打泥量
+        if (diffCloseTime <= 30 && !isClosureTime.get()) {
+            //表示已经计算过打泥量了
+            isClosureTime.set(true);
+
+            // 打泥量选择模型
+            TIronSchedule scheduleHitMud = scheduleMap.get(TaskNameConstants.TASKNAME_HIT_MUD);
+            if (scheduleHitMud != null && "1".equals(scheduleHitMud.getStatus())) {
+                scheduledTaskManager.addTask(scheduleHitMud.getName(), scheduleHitMud.getDelay(), scheduleHitMud.getPeriod(), TimeUnit.SECONDS, runnableHitmud());
+            }
+        }
     }
 
     private void getExceptionList() {
@@ -689,21 +717,6 @@ public class DeviceEventListener extends AbstractEventListener { //
             // 记录查询结果详情
             log.info("异常列表获取完成,共{}条记录", list != null ? list.size() : 0);
 
-//            if (list != null && !list.isEmpty()) {
-//                log.info("异常记录详情:");
-//                for (int i = 0; i < Math.min(list.size(), 5); i++) {
-//                    TExceptionLogBigScreenVo vo = list.get(i);
-//                    log.info("  记录[{}]: 异常类型={}, 异常描述={}, 发生时间={}, 铁次ID={}",
-//                            i + 1,
-//                            vo.getExceptionTypeName(),
-//                            vo.getExceptionDesc(),
-//                            vo.getCreateTime(),
-//                            vo.getTapholeName());
-//                }
-//
-//            } else {
-//                log.info("当前查询条件下无异常记录");
-//            }
 
             PushData.send2Exception(list);
             log.info("异常列表已推送至前端");
@@ -751,6 +764,7 @@ public class DeviceEventListener extends AbstractEventListener { //
             mIronTempLowCount.set(0);
 
             isChuz.set(Boolean.FALSE);
+            isClosureTime.set(Boolean.FALSE);
 
             getIronTimeNo();
 
@@ -778,38 +792,34 @@ public class DeviceEventListener extends AbstractEventListener { //
             if (tappingTimeoutWarn != null && "1".equals(tappingTimeoutWarn.getStatus())) {
                 scheduledTaskManager.addTask(tappingTimeoutWarn.getName(), tappingTimeoutWarn.getDelay(), tappingTimeoutWarn.getPeriod(), TimeUnit.SECONDS, runnableTappingTimeout());
             }
-            // 出铁重量报警
+
+            // 出铁超重报警
             TIronSchedule tappingWeightoutWarn = scheduleMap.get(TaskNameConstants.TAPPING_WEIGHTOUT_WARN);
             if (tappingWeightoutWarn != null && "1".equals(tappingWeightoutWarn.getStatus())) {
                 scheduledTaskManager.addTask(tappingWeightoutWarn.getName(), tappingWeightoutWarn.getDelay(), tappingWeightoutWarn.getPeriod(), TimeUnit.SECONDS, runnableTappingWeightout());
             }
 
-            // 打泥量选择模型
-            TIronSchedule scheduleHitMud = scheduleMap.get(TaskNameConstants.TASKNAME_HIT_MUD);
-            if (scheduleHitMud != null && "1".equals(scheduleHitMud.getStatus())) {
-                scheduledTaskManager.addTask(scheduleHitMud.getName(), scheduleHitMud.getDelay(), scheduleHitMud.getPeriod(), TimeUnit.SECONDS, runnableHitmud());
-            }
 
             // 堵口预测时间
-            TIronSchedule schedulClosurePredict = scheduleMap.get(TaskNameConstants.TASKNAME_CLOSURE_PREDICT);
-            TIronModel modelClosurePredict = modelMap.get(ModelConstants.closure_predict);
-            if (null != modelClosurePredict && schedulClosurePredict != null && "1".equals(modelClosurePredict.getStatus()) && "1".equals(schedulClosurePredict.getStatus())) {
-                String modelExpression = modelClosurePredict.getModelExpression();
-                if (null != modelExpression) {
-                    ClosurePredictInfo mClosurePredictInfo = GsonUtils.fromJson(modelExpression, ClosurePredictInfo.class);
-                    if (null != mClosurePredictInfo) {
-                        if ("1".equals(schedulClosurePredict.getStatus())) {
-                            mTotalCloseTime = new Random().nextInt(mClosurePredictInfo.getPredMax() - mClosurePredictInfo.getPredMin() + 1) + mClosurePredictInfo.getPredMin();
-                            RedisUtils.addFixedElement(RedisConstants.TOTAL_CLOSE_TIME, mTotalCloseTime);
-                            mLastSpeed.set(0);
-                            mMaxSpeed.set(0);
-                            mDiffCloseTime.set(0);
-                            log.info("预计总时间:{}", mTotalCloseTime);
-                            scheduledTaskManager.addTask(schedulClosurePredict.getName(), schedulClosurePredict.getDelay(), schedulClosurePredict.getPeriod(), TimeUnit.SECONDS, runnableClosurePredict(mClosurePredictInfo));
-                        }
-                    }
-                }
-            }
+//            TIronSchedule schedulClosurePredict = scheduleMap.get(TaskNameConstants.TASKNAME_CLOSURE_PREDICT);
+//            TIronModel modelClosurePredict = modelMap.get(ModelConstants.closure_predict);
+//            if (null != modelClosurePredict && schedulClosurePredict != null && "1".equals(modelClosurePredict.getStatus()) && "1".equals(schedulClosurePredict.getStatus())) {
+//                String modelExpression = modelClosurePredict.getModelExpression();
+//                if (null != modelExpression) {
+//                    ClosurePredictInfo mClosurePredictInfo = GsonUtils.fromJson(modelExpression, ClosurePredictInfo.class);
+//                    if (null != mClosurePredictInfo) {
+//                        if ("1".equals(schedulClosurePredict.getStatus())) {
+//                            mTotalCloseTime = new Random().nextInt(mClosurePredictInfo.getPredMax() - mClosurePredictInfo.getPredMin() + 1) + mClosurePredictInfo.getPredMin();
+//                            RedisUtils.addFixedElement(RedisConstants.TOTAL_CLOSE_TIME, mTotalCloseTime);
+//                            mLastSpeed.set(0);
+//                            mMaxSpeed.set(0);
+//                            mDiffCloseTime.set(0);
+//                            log.info("预计总时间:{}", mTotalCloseTime);
+//                            scheduledTaskManager.addTask(schedulClosurePredict.getName(), schedulClosurePredict.getDelay(), schedulClosurePredict.getPeriod(), TimeUnit.SECONDS, runnableClosurePredict(mClosurePredictInfo));
+//                        }
+//                    }
+//                }
+//            }
 
         }
     }
@@ -841,6 +851,10 @@ public class DeviceEventListener extends AbstractEventListener { //
             isChuz.set(Boolean.FALSE);
             log.info("✅ 设置是否出渣为False已关闭");
 
+            log.info("🔒 设置是否已经打泥为False...");
+            isClosureTime.set(Boolean.FALSE);
+            log.info("✅ 设置是否已经打泥为False已关闭");
+
             // 记录标准参数
             try {
                 int stdIronTimeMin = Integer.parseInt(mContext.lookupVariable(ExpressionConstants.stdIronTimeMin).toString());
@@ -900,6 +914,8 @@ public class DeviceEventListener extends AbstractEventListener { //
                 log.warn("⚠️ 出铁时间过短: 实际{}分钟 < 标准{}分钟", actualTime, stdIronTimeMin);
                 taskExecutor.submit(() -> {
                     log.info("📝 记录出铁时间过短异常...");
+                    PushData.send2Warn(WarnData.warnTapping("出铁时间过短",
+                            audioMap.get(ExceptionTypeEnum.IRON_TIME_SHORT.getCode())));
                     saveException(ExceptionTypeEnum.IRON_TIME_SHORT,
                             String.format("出铁时间%s分钟", actualTime));
                     getExceptionList();
@@ -968,7 +984,6 @@ public class DeviceEventListener extends AbstractEventListener { //
 
             try {
 
-
                 if ("1".equals(modelClosureWarn1.getStatus())
                         && "1".equals(modelClosureWarn2.getStatus())
                         && "1".equals(modelClosureWarn3.getStatus())
@@ -1111,16 +1126,20 @@ public class DeviceEventListener extends AbstractEventListener { //
                         log.info("提交出铁超时异常处理任务到线程池");
 
                         try {
-                            PushData.send2Warn(WarnData.warnTapping("出铁超时", audioMap.get(ExceptionTypeEnum.IRON_TIME_LONG.getCode())));
-                            // 记录异常信息
-                            String exceptionMessage = String.format("出铁时间:%s分钟", currentIronTime);
-                            saveException(ExceptionTypeEnum.IRON_TIME_LONG, exceptionMessage);
-                            log.info("已记录出铁超时异常: {}", exceptionMessage);
+                            try {
+                                PushData.send2Warn(WarnData.warnTapping("出铁超时", audioMap.get(ExceptionTypeEnum.IRON_TIME_LONG.getCode())));
+                                // 记录异常信息
+                                String exceptionMessage = String.format("出铁时间:%s分钟", currentIronTime);
+                                saveException(ExceptionTypeEnum.IRON_TIME_LONG, exceptionMessage);
+                                log.info("已记录出铁超时异常: {}", exceptionMessage);
 
-                            // 推送预警列表更新
-                            getExceptionList();
-                            log.info("已推送出铁超时预警列表更新");
+                                // 推送预警列表更新
+                                getExceptionList();
+                                log.info("已推送出铁超时预警列表更新");
+                            } catch (Exception e) {
 
+                            }
+                            scheduledTaskManager.cancelTask(scheduleMap.get(TaskNameConstants.TASKNAME_TAPPING_TIMEOUT_WARN).getName());
                         } catch (Exception e) {
                             log.error("处理出铁超时异常时发生错误", e);
                         }
@@ -1135,7 +1154,7 @@ public class DeviceEventListener extends AbstractEventListener { //
                 log.error("执行出铁超时检查时发生异常", e);
             } finally {
                 log.info("出铁超时检查任务完成");
-                scheduledTaskManager.cancelTask(scheduleMap.get(TaskNameConstants.TASKNAME_TAPPING_TIMEOUT_WARN).getName());
+
             }
         };
     }
@@ -1148,11 +1167,11 @@ public class DeviceEventListener extends AbstractEventListener { //
             try {
                 // 获取标准最大出铁重量配置
                 double stdIronWeightMax = Double.parseDouble(mContext.lookupVariable(ExpressionConstants.stdIronWeightMax).toString());
-                log.info("获取标准最大出铁重量: {} 分钟", stdIronWeightMax);
+                log.info("获取标准最大出铁重量: {} t", stdIronWeightMax);
 
                 // 获取当前出铁重量
                 double currentIronTime = mTotalWeight.get().doubleValue();
-                log.info("当前出铁重量: {} 分钟", currentIronTime);
+                log.info("当前出铁重量: {} t", currentIronTime);
 
                 // 检查是否重量
                 if (currentIronTime > stdIronWeightMax) {
@@ -1160,13 +1179,19 @@ public class DeviceEventListener extends AbstractEventListener { //
 
 
                     taskExecutor.submit(() -> {
-                        PushData.send2Warn(WarnData.warnTapping("出铁量过多", audioMap.get(ExceptionTypeEnum.IRON_WEIGHT_MANY.getCode())));
-                        saveException(ExceptionTypeEnum.IRON_WEIGHT_MANY, String.format("出铁量%s吨", mTotalWeight));
-                        //推送预警列表
-                        getExceptionList();
+                        try {
+                            PushData.send2Warn(WarnData.warnTapping("出铁量过多", audioMap.get(ExceptionTypeEnum.IRON_WEIGHT_MANY.getCode())));
+                            saveException(ExceptionTypeEnum.IRON_WEIGHT_MANY, String.format("出铁量%s吨", mTotalWeight));
+                            //推送预警列表
+                            getExceptionList();
+                        } catch (Exception e) {
+
+                        }
+                        scheduledTaskManager.cancelTask(scheduleMap.get(TaskNameConstants.TAPPING_WEIGHTOUT_WARN).getName());
                     });
 
                     log.info("出铁重量异常处理任务已提交");
+
                 } else {
                     log.info("出铁重量正常 - 当前: {} t, 标准: {} t", currentIronTime, stdIronWeightMax);
                 }
@@ -1175,16 +1200,15 @@ public class DeviceEventListener extends AbstractEventListener { //
                 log.error("执行出铁超时检查时发生异常", e);
             } finally {
                 log.info("出铁超重量检查任务完成");
-                scheduledTaskManager.cancelTask(scheduleMap.get(TaskNameConstants.TAPPING_WEIGHTOUT_WARN).getName());
             }
         };
     }
 
     //堵口时间预测
-    @NotNull
-    private Runnable runnableClosurePredict(ClosurePredictInfo mClosurePredictInfo) {
-        return () -> {
-            if (mMaxSpeed.get() > 0 && ironLoading1.get() > 0) {
+//    @NotNull
+//    private Runnable runnableClosurePredict(ClosurePredictInfo mClosurePredictInfo) {
+//        return () -> {
+//            if (mMaxSpeed.get() > 0 && ironLoading1.get() > 0) {
 //                if (this.mLastSpeed.get() == 0) {
 //
 //                } else if (mMaxSpeed.get() > this.mLastSpeed.get()) {
@@ -1196,11 +1220,10 @@ public class DeviceEventListener extends AbstractEventListener { //
 //                }
 //                this.mLastSpeed.set(mMaxSpeed.get());
 //                RedisUtils.addFixedElement(RedisConstants.DIFF_CLOSE_TIME, mDiffCloseTime.get());
-                getCloseTime();
-            }
-
-        };
-    }
+//            }
+//
+//        };
+//    }
 
     //打泥量预测
     @NotNull
@@ -1213,7 +1236,7 @@ public class DeviceEventListener extends AbstractEventListener { //
             log.info("获取打泥量模型配置: {}", modelHitMud != null ? modelHitMud.getModelName() : "null");
 
             // 获取最新的出铁数据
-            TL2Data tappingData = tl2DataService.getTapped1LatestData();
+            TL2Data tappingData = tl2DataService.getLatestData("1");
             log.info("获取最新出铁数据: {}", tappingData != null ? "数据存在" : "数据为空");
 
             // 数据有效性检查
@@ -1270,6 +1293,54 @@ public class DeviceEventListener extends AbstractEventListener { //
                 BigDecimal bigDecimal = new BigDecimal(result.toString());
                 mCalcHitMud = bigDecimal.toBigInteger().toString();
 
+
+                // 记录标准参数
+                try {
+                    int stdIronTimeMin = Integer.parseInt(mContext.lookupVariable(ExpressionConstants.stdIronTimeMin).toString());
+                    int stdIronTimeMax = Integer.parseInt(mContext.lookupVariable(ExpressionConstants.stdIronTimeMax).toString());
+                    double stdIronWeightMin = Double.parseDouble(mContext.lookupVariable(ExpressionConstants.stdIronWeightMin).toString());
+                    double stdIronWeightMax = Double.parseDouble(mContext.lookupVariable(ExpressionConstants.stdIronWeightMax).toString());
+
+                    log.info("📋 标准参数: 时间范围={}-{}分钟, 重量范围={}-{}吨", stdIronTimeMin, stdIronTimeMax, stdIronWeightMin, stdIronWeightMax);
+
+                    // 1.出铁量 1000-1300t     1000以下,出铁时间变短,打泥量+5;1300以上-5
+                    if (mTotalWeight.get().doubleValue() < stdIronWeightMin) {
+                        bigDecimal = bigDecimal.add(BigDecimal.valueOf(5));
+                    } else if (mTotalWeight.get().doubleValue() > stdIronWeightMax) {
+                        bigDecimal = bigDecimal.subtract(BigDecimal.valueOf(5));
+                    }
+
+                    // 2.出铁时间 150-180min   150以下,打泥量+5;180以上-5
+                    if (getIronElapsedMinute() < stdIronTimeMin) {
+                        bigDecimal = bigDecimal.add(BigDecimal.valueOf(5));
+                    } else if (getIronElapsedMinute() > stdIronTimeMax) {
+                        bigDecimal = bigDecimal.subtract(BigDecimal.valueOf(5));
+                    }
+
+                    mCalcHitMud = bigDecimal.toBigInteger().toString();
+
+                } catch (Exception e) {
+                    log.warn("⚠️ 获取标准参数失败: {}", e.getMessage());
+                }
+
+
+                List<TL2Data> latestTwoDatas = tl2DataService.getLatestTwoDatas("1");
+                if (ObjectUtils.isNotEmpty(latestTwoDatas) && latestTwoDatas.size() >= 2) {
+                    BigDecimal mudWeight1 = BigDecimal.valueOf(latestTwoDatas.get(0).getMudWeight());
+                    BigDecimal mudWeight2 = BigDecimal.valueOf(latestTwoDatas.get(2).getMudWeight());
+
+                    if (mudWeight1.intValue() == 55 && mudWeight2.intValue() == 55) {
+                        // 前2次1号铁口的打泥量    前两次55L,建议本次也是55L
+                        mCalcHitMud = "55";
+                    } else {
+                        if (bigDecimal.compareTo(mudWeight1) > 0 && bigDecimal.compareTo(mudWeight2) > 0) {
+                            mCalcHitMud = mudWeight1.add(mudWeight2).divide(BigDecimal.valueOf(2), 0, RoundingMode.HALF_UP).toPlainString();
+                        }
+                    }
+
+                }
+
+
                 log.info("打泥量计算完成: {} L", mCalcHitMud);
 
                 // 推送结果
@@ -1495,6 +1566,13 @@ public class DeviceEventListener extends AbstractEventListener { //
                 TL2Data latestData = tl2DataService.getLatestData();
                 TIronTest ironTest = new TIronTest();
                 ironTest.setTapholeId("1");
+                ironTest.setAvgSpeed(actualIronSpeed + "");
+                ironTest.setAvgTemp(avgTemp + "");
+                ironTest.setIronWeight(actualIronWeight + "");
+                ironTest.setIronCosttime(actualIronTime);
+                if(ObjectUtils.isNotEmpty(mTIronData)){
+                    ironTest.setIronDataId(mTIronData.getId());
+                }
 
                 String testStatus = (ironNormalCount >= 4) ? "1" : "0";
                 ironTest.setTestStatus(testStatus);
@@ -1707,7 +1785,7 @@ public class DeviceEventListener extends AbstractEventListener { //
                         } catch (Exception e) {
                             e.printStackTrace();
                             log.error("      ❌ 保存出铁记录失败: {}", e.getMessage(), e);
-                        }finally {
+                        } finally {
                             mTIronData = null;
                         }
 
@@ -2096,7 +2174,6 @@ public class DeviceEventListener extends AbstractEventListener { //
                 lastChuzTemps.add(temp);
                 log.info("   ├─ 添加新温度后队列: {}", lastChuzTemps);
 
-             //   boolean isRising = false;
                 log.info("📈 【温度趋势分析】");
                 log.info("   ├─ 出铁状态 (ironLoading1): {}", ironLoading1.get());
 
@@ -2270,7 +2347,7 @@ public class DeviceEventListener extends AbstractEventListener { //
         }
 
         if (ObjectUtils.isEmpty(fixedLatestElement)) {
-            fixedLatestElement = tl2DataService.getTapped1LatestData();
+            fixedLatestElement = tl2DataService.getLatestData("1");
         }
 
         if (ObjectUtils.isNotEmpty(fixedLatestElement)) {
@@ -2862,6 +2939,7 @@ public class DeviceEventListener extends AbstractEventListener { //
                                 }
                                 break;
                             case TaskNameConstants.TASKNAME_EXCEPTION_LIST:
+                                //告警列表
                                 if (schedule != null && "1".equals(schedule.getStatus())) {
                                     scheduledTaskManager.addTask(schedule.getName(), schedule.getDelay(), schedule.getPeriod(), TimeUnit.SECONDS, () -> {
                                         getExceptionList();
@@ -2871,6 +2949,7 @@ public class DeviceEventListener extends AbstractEventListener { //
                                 }
                                 break;
                             case TaskNameConstants.TASKNAME_OPCDASUBSCRIBE:
+                                //L1订阅
                                 if (schedule != null && "1".equals(schedule.getStatus())) {
                                     scheduledTaskManager.addTask(schedule.getName(), schedule.getDelay(), schedule.getPeriod(), TimeUnit.SECONDS, () -> {
                                         if ("prod".equals(activeProfiles)) {
@@ -2887,6 +2966,7 @@ public class DeviceEventListener extends AbstractEventListener { //
                                 }
                                 break;
                             case TaskNameConstants.TASKNAME_TAPPING_TEST:
+                                //出铁诊断
                                 if (schedule != null && "1".equals(schedule.getStatus())) {
                                     scheduledTaskManager.addTask(schedule.getName(), schedule.getDelay(), schedule.getPeriod(), TimeUnit.SECONDS, runnableTappingTest());
                                 } else {
@@ -2894,6 +2974,7 @@ public class DeviceEventListener extends AbstractEventListener { //
                                 }
                                 break;
                             case TaskNameConstants.TASKNAME_TAPPING_WARN:
+                                //出铁预警
                                 if (schedule != null && "1".equals(schedule.getStatus())) {
                                     scheduledTaskManager.addTask(schedule.getName(), schedule.getDelay(), schedule.getPeriod(), TimeUnit.SECONDS, runnableTappingWarn());
                                 } else {
@@ -2901,6 +2982,7 @@ public class DeviceEventListener extends AbstractEventListener { //
                                 }
                                 break;
                             case TaskNameConstants.TASKNAME_CLOSURE_WARN:
+                                //堵口预警
                                 if (schedule != null && "1".equals(schedule.getStatus())) {
                                     scheduledTaskManager.addTask(schedule.getName(), schedule.getDelay(), schedule.getPeriod(), TimeUnit.SECONDS, runnableClosureWarn());
                                 } else {
@@ -2908,6 +2990,7 @@ public class DeviceEventListener extends AbstractEventListener { //
                                 }
                                 break;
                             case TaskNameConstants.TASKNAME_OPEN_WARN:
+                                //开口预警
                                 if (schedule != null && "1".equals(schedule.getStatus())) {
                                     scheduledTaskManager.addTask(schedule.getName(), schedule.getDelay(), schedule.getPeriod(), TimeUnit.SECONDS, runnableHitmud());
                                 } else {

+ 7 - 15
taphole-l2/src/main/java/com/sckj/l2/service/impl/TL2DataServiceImpl.java

@@ -96,34 +96,26 @@ public class TL2DataServiceImpl extends ServiceImpl<TL2DataMapper, TL2Data> {
 
 
     /***
-     * 获取4高炉最新2条数据
+     * 获取4高炉(xxx铁口)最新2条数据
+     * @param tapholeId 铁口号(1 2 3 4),传空表示最新2条数据
      * @return
      */
-    public List<TL2Data> getLatestTwoDatas() {
+    public List<TL2Data> getLatestTwoDatas(String...tapholeId) {
         LambdaQueryWrapper<TL2Data> queryWrapper = new LambdaQueryWrapper<>();
-        queryWrapper.isNotNull(TL2Data::getIronNo).isNotNull(TL2Data::getIronWeight).isNotNull(TL2Data::getCalcWeight).orderByDesc(TL2Data::getIronNo).last("limit 2");
+        queryWrapper.eq(ObjectUtils.isNotEmpty(tapholeId),TL2Data::getTapholeId,tapholeId[0]).isNotNull(TL2Data::getIronNo).isNotNull(TL2Data::getIronWeight).isNotNull(TL2Data::getCalcWeight).orderByDesc(TL2Data::getIronNo).last("limit 2");
         List<TL2Data> list = list(queryWrapper);
         return list;
     }
 
-    /***
-     * 获取4高炉1号铁口最新1条数据
-     * @return
-     */
-    public TL2Data getTapped1LatestData() {
-        LambdaQueryWrapper<TL2Data> queryWrapper = new LambdaQueryWrapper<>();
-        queryWrapper.eq(TL2Data::getTapholeId,"1").isNotNull(TL2Data::getIronNo).orderByDesc(TL2Data::getIronNo).last("limit 1");
-        List<TL2Data> list = list(queryWrapper);
-        return ObjectUtils.isEmpty(list) ? null : list.get(0);
-    }
 
     /***
      * 获取4高炉最新1条数据
+     * @param tapholeId 铁口号(1 2 3 4),传空表示最新数据
      * @return
      */
-    public TL2Data getLatestData() {
+    public TL2Data getLatestData(String...tapholeId) {
         LambdaQueryWrapper<TL2Data> queryWrapper = new LambdaQueryWrapper<>();
-        queryWrapper.isNotNull(TL2Data::getIronNo).orderByDesc(TL2Data::getIronNo).last("limit 1");
+        queryWrapper.eq(ObjectUtils.isNotEmpty(tapholeId),TL2Data::getTapholeId,tapholeId[0]).isNotNull(TL2Data::getIronNo).orderByDesc(TL2Data::getIronNo).last("limit 1");
         List<TL2Data> list = list(queryWrapper);
         return ObjectUtils.isEmpty(list) ? null : list.get(0);
     }

+ 23 - 5
taphole-warn/src/main/java/com/sckj/warn/dto/TExceptionLogDTO.java

@@ -1,5 +1,11 @@
 package com.sckj.warn.dto;
 
+import com.alibaba.excel.annotation.ExcelProperty;
+import com.alibaba.excel.annotation.write.style.ColumnWidth;
+import com.alibaba.excel.annotation.write.style.HeadFontStyle;
+import com.alibaba.excel.annotation.write.style.HeadRowHeight;
+import com.alibaba.excel.annotation.write.style.HeadStyle;
+import com.alibaba.excel.enums.poi.FillPatternTypeEnum;
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
@@ -7,23 +13,35 @@ import lombok.Data;
 import java.io.Serializable;
 import java.util.Date;
 
+@HeadStyle(fillPatternType = FillPatternTypeEnum.NO_FILL,fillForegroundColor = -1)
+@HeadFontStyle(fontHeightInPoints = 16)
+@HeadRowHeight(40)
 @Data
 @ApiModel("异常情况记录实体")
 public class TExceptionLogDTO implements Serializable {
 
     private static final long serialVersionUID = 1L;
 
-    @ApiModelProperty(value = "告警时间")
-    private Date createTime;
+    @ApiModelProperty(value = "铁口号")
+    @ExcelProperty("铁口号")
+    @ColumnWidth(25)
+    private String tapholeId;
 
     @ApiModelProperty(value = "告警类型")
+    @ExcelProperty("告警类型")
+    @ColumnWidth(25)
     private String exceptionType;
 
-    @ApiModelProperty(value = "铁口号")
-    private String tapholeId;
-
     @ApiModelProperty(value = "告警明细")
+    @ExcelProperty("告警明细")
+    @ColumnWidth(100)
     private String exceptionDesc;
 
+    @ApiModelProperty(value = "告警时间")
+    @ExcelProperty("告警时间")
+    @ColumnWidth(25)
+    private Date createTime;
+
+
 
 }