2 Commit-ok ae5036c87a ... 3dd7ae253f

Szerző SHA1 Üzenet Dátum
  王苗苗 3dd7ae253f 多指标/单指标断点 多指标/单指标连续不变 本地决策调整 5 napja
  王苗苗 be92d5b994 进水氨氮显示值 拼接最近8小时的浓度处理 6 napja

+ 48 - 0
slibra-common/src/main/java/com/slibra/common/constant/MyConstants.java

@@ -438,6 +438,16 @@ public class MyConstants {
     //2025年03月06日09:49:32 方案改成markdown格式
     public static final String SINGLE_BREAKPOINT_ANSWER_PREFIX = "数据发生断点问题,经排查网络连接没有问题,但可能是现场的";
     public static final String SINGLE_BREAKPOINT_ANSWER_SUFFIX = "仪表出现了故障,或者仪表的数据输出模块可能存在问题。这些问题可能导致仪表无法正确传输数据,需要检查仪表及其连接部分,确保数据能够正常采集和传输。";
+
+    public static final String SINGLE_BREAKPOINT_ANSWER_REPLACE_NEW = "## 解决方案 ##\n" +
+            "## 一、数据表现 ##\n" +
+            "**@@@0浓度**:@@@1\n" +
+            "**@@@0变化趋势**:连续发生数据断点/缺失;\n" +
+            "## 二、原因分析 ##\n" +
+            "@@@0在线仪表发生数据断点缺失问题,相关其他仪表数据均正常变化,排除数据传输和组态软件问题。定位为@@@0仪表可能存在故障。\n" +
+            "## 三、解决方案 ##\n" +
+            "建议检查@@@0仪表是否有故障情况,同时检查仪表的输出模块是否工作正常,确保数据的采集和传输。";
+
     public static final String SINGLE_BREAKPOINT_ANSWER_REPLACE = "## 解决方案 ##\n" +
             "## 一、数据表现 ##\n" +
             "**@@@0浓度**:`0`mg/L\n" +
@@ -449,6 +459,16 @@ public class MyConstants {
 
     public static final String MORE_BREAKPOINT_ANSWER = "数据发生断点问题,经排查可能是中控上位机系统出现了故障,或者数据传输网络和相关设备存在问题,也有可能是仪表站房发生了停电故障。这些因素都可能影响系统的正常运行,建议检查上位机系统、网络设备以及仪表站房的电力供应,确保各个环节都正常工作。";
 
+
+    public static final String MORE_BREAKPOINT_ANSWER_REPLACE_NEW = "## 解决方案 ##\n" +
+            "## 一、数据表现 ##\n" +
+            "**@@@0浓度**:@@@1\n" +
+            "**@@@0变化趋势**:连续发生数据断点/缺失;\n" +
+            "## 二、原因分析 ##\n" +
+            "@@@0在线仪表发生数据断点缺失问题,相关其他仪表数据也发现问题。定位为数据传输网络或相关设备出现了问题,或者中控上位机系统本身存在故障。\n" +
+            "## 三、解决方案 ##\n" +
+            "建议检查网络连接、设备状态以及中控上位机系统,确保它们正常工作以避免数据丢失或系统故障。";
+
     public static final String MORE_BREAKPOINT_ANSWER_REPLACE = "## 解决方案 ##\n" +
             "## 一、数据表现 ##\n" +
             "**@@@0浓度**:`0`mg/L\n" +
@@ -463,6 +483,15 @@ public class MyConstants {
     public static final String SINGLE_NO_CHANGE_ANSWER_TWO = "仪表可能存在堵塞或故障,或者仪表的数据输出模块可能出现问题,这可能导致数据无法正常传输。建议检查";
     public static final String SINGLE_NO_CHANGE_ANSWER_THREE = "仪表是否有堵塞情况,同时检查仪表的输出模块是否工作正常,确保数据的准确采集和传输。";
 
+    public static final String SINGLE_NO_CHANGE_ANSWER_REPLACE_NEW = "## 解决方案 ##\n" +
+            "## 一、数据表现 ##\n" +
+            "**@@@0浓度**:`@@@1`\n" +
+            "**@@@0变化趋势**:连续多个时段数据不变;\n" +
+            "## 二、原因分析 ##\n" +
+            "@@@0在线仪表连续数据不变,相关其他仪表数据均正常变化,排除数据传输和组态软件问题。定位为@@@0仪表可能存在堵塞或故障。\n" +
+            "## 三、解决方案 ##\n" +
+            "建议检查@@@0仪表是否有堵塞情况,同时检查仪表的输出模块是否工作正常,确保数据的准确采集和传输。";
+
     public static final String SINGLE_NO_CHANGE_ANSWER_REPLACE = "## 解决方案 ##\n" +
             "## 一、数据表现 ##\n" +
             "**@@@0浓度**:`@@@1`mg/L\n" +
@@ -474,6 +503,15 @@ public class MyConstants {
 
     public static final String MORE_NO_CHANGE_ANSWER = "数据发生连续不变,经排查可能是数据传输网络或相关设备出现了问题,或者中控上位机系统本身存在故障。这些问题可能影响数据的正常传输和系统的稳定运行。建议检查网络连接、设备状态以及中控上位机系统,确保它们正常工作以避免数据丢失或系统故障。";
 
+    public static final String MORE_NO_CHANGE_ANSWER_REPLACE_NEW = "## 解决方案 ##\n" +
+            "## 一、数据表现 ##\n" +
+            "**@@@0浓度**:`@@@1`\n" +
+            "**@@@0变化趋势**:连续多个时段数据不变;\n" +
+            "## 二、原因分析 ##\n" +
+            "@@@0在线仪表连续数据不变,相关其他仪表数据也发现问题。定位为数据传输网络或相关设备出现了问题,或者中控上位机系统本身存在故障。\n" +
+            "## 三、解决方案 ##\n" +
+            "建议检查网络连接、设备状态以及中控上位机系统,确保它们正常工作以避免数据丢失或系统故障。\n";
+
     public static final String MORE_NO_CHANGE_ANSWER_REPLACE = "## 解决方案 ##\n" +
             "## 一、数据表现 ##\n" +
             "**@@@0浓度**:`@@@1`mg/L\n" +
@@ -486,6 +524,16 @@ public class MyConstants {
     public static final String YCSG_ANSWER_ONE = "水质数据发生突变,突变增幅";
     public static final String YCSG_ANSWER_TWO = ",突变前数据";
     public static final String YCSG_ANSWER_THREE = ",建议检查仪表状态或进行人工取样校核。如果问题已经得到解决,请标记为已解决状态,无需进一步处理。但仍建议继续观察,以确保问题不再复发。";
+
+    public static final String YCSG_ANSWER_REPLACE_NEW = "## 解决方案 ##\n" +
+            "## 一、数据表现 ##\n" +
+            "**@@@0浓度**:`@@@1`\n" +
+            "**@@@0变化趋势**:连续发生单点突变;\n" +
+            "## 二、原因分析 ##\n" +
+            "@@@0在线仪表水质数据发生突变,突变增幅{@@@2},突变前数据{@@@3}。\n" +
+            "## 三、解决方案 ##\n" +
+            "建议检查仪表状态或进行人工取样校核。如果问题已经得到解决,请标记为已解决状态,无需进一步处理。但仍建议继续观察,以确保问题不再复发。";
+
     public static final String YCSG_ANSWER_REPLACE = "## 解决方案 ##\n" +
             "## 一、数据表现 ##\n" +
             "**@@@0浓度**:`@@@1`mg/L\n" +

+ 187 - 20
slibra-quartz/src/main/java/com/slibra/quartz/task/AsyncTask.java

@@ -1610,6 +1610,14 @@ public class AsyncTask {
             noChangeList.add(warningMoreExceed.getNoChangeWarningRecord());
         }
 
+        List<TXinyiIndustry> tXinyiIndustries = this.xinyiIndustryMapper.selectNIndustry(INT_4);
+        if(CollectionUtils.isEmpty(tXinyiIndustries) || tXinyiIndustries.size() < INT_4){
+            log.error("处理生化报警时,获取最近的4条工业库数据失败~~~~~~~");
+            return ;
+        }
+        //2025年04月18日09:47:11 因为本地决策的当前进水表现从原来的1个值变成了现在的4个值
+        //拼接决策的最近4小时的值
+        String last4Str = this.getJsNh3StrByList(tXinyiIndustries);
 
         //进水相关报警
 
@@ -1663,7 +1671,7 @@ public class AsyncTask {
                 //插入该类型报警
                 this.xinyiWarningRecordMapper.insertTXinyiWarningRecord(warningRecordBreakPointOne);
                 //同时处理决策 不用调用大模型,本地处理问答
-                addChatRecordByBreakPointsSingle(warningRecordBreakPointOne, tXinyiIndustry, normConfig, category);
+                addChatRecordByBreakPointsSingleNew(warningRecordBreakPointOne, tXinyiIndustry, normConfig, category, last4Str);
             }else{
                 log.info("工业库报警的时候,发现存在仪表故障(断点不变单个指标)的报警,并且已经有该类型报警了,不做任何处理");
                 //2025年03月06日10:52:57 逻辑调整:更新一直报警的那条记录的显示值
@@ -1677,7 +1685,7 @@ public class AsyncTask {
                 //更新数据库
                 this.xinyiWarningRecordMapper.updateTXinyiWarningRecord(xinyiWarningRecord);
                 //继续调用决策【本地模拟的决策】
-                addChatRecordByBreakPointsSingle(xinyiWarningRecord, tXinyiIndustry, normConfig, category);
+                addChatRecordByBreakPointsSingleNew(xinyiWarningRecord, tXinyiIndustry, normConfig, category, last4Str);
             }
             //额外判断当前的异常是哪个指标,并处理标识
             if(BusinessEnum.WarningCategoryEnum.CS_COD.getCode().equals(category)){
@@ -1721,7 +1729,7 @@ public class AsyncTask {
                     tXinyiWarningRecord.setSymbol(BusinessEnum.WarningSymbolEnum.YBGZ_DD_MORE_GYK.getCode());
                     this.xinyiWarningRecordMapper.insertTXinyiWarningRecord(tXinyiWarningRecord);
                     //同时处理决策 不用调用大模型,本地处理问答
-                    addChatRecordByBreakPointsMore(tXinyiWarningRecord, tXinyiIndustry, normConfig);
+                    addChatRecordByBreakPointsMoreNew(tXinyiWarningRecord, tXinyiIndustry, normConfig, last4Str);
                 }
             }else{//之前存在报警了 所以需要2个集合数据进行匹配,如果新的和原来的一样则不用做任何操作【持续报警】;如果不一样,则新的要报警,老报警要关闭
                 List<TXinyiWarningRecord> breakPointListNew = new ArrayList<>(breakPointList);//断点集合[需要新增的]
@@ -1752,7 +1760,7 @@ public class AsyncTask {
                         tXinyiWarningRecord.setSymbol(BusinessEnum.WarningSymbolEnum.YBGZ_DD_MORE_GYK.getCode());
                         this.xinyiWarningRecordMapper.insertTXinyiWarningRecord(tXinyiWarningRecord);
                         //同时处理决策 不用调用大模型,本地处理问答
-                        addChatRecordByBreakPointsMore(tXinyiWarningRecord, tXinyiIndustry, normConfig);
+                        addChatRecordByBreakPointsMoreNew(tXinyiWarningRecord, tXinyiIndustry, normConfig, last4Str);
                     }
                 }
                 //关闭老的报警
@@ -1785,7 +1793,7 @@ public class AsyncTask {
                         //更新数据库
                         this.xinyiWarningRecordMapper.updateTXinyiWarningRecord(tXinyiWarningRecord);
                         //继续调用决策【本地模拟的决策】
-                        addChatRecordByBreakPointsMore(tXinyiWarningRecord, tXinyiIndustry, normConfig);
+                        addChatRecordByBreakPointsMoreNew(tXinyiWarningRecord, tXinyiIndustry, normConfig, last4Str);
                     }
                 }
             }
@@ -1816,7 +1824,7 @@ public class AsyncTask {
                 //插入该类型报警
                 this.xinyiWarningRecordMapper.insertTXinyiWarningRecord(noChangeWarningRecord);
                 //同时处理决策 不用调用大模型,本地处理问答
-                addChatRecordByNoChangeSingle(noChangeWarningRecord, tXinyiIndustry, normConfig, category);
+                addChatRecordByNoChangeSingleNew(noChangeWarningRecord, tXinyiIndustry, normConfig, category, last4Str);
             }else{
                 log.info("工业库报警的时候,发现存在仪表故障(连续不变单个指标)的报警,并且已经有该类型报警了,不做任何处理");
                 //2025年03月06日10:52:57 逻辑调整:更新一直报警的那条记录的显示值
@@ -1830,7 +1838,7 @@ public class AsyncTask {
                 //更新数据库
                 this.xinyiWarningRecordMapper.updateTXinyiWarningRecord(xinyiWarningRecord);
                 //继续调用决策【本地模拟的决策】
-                addChatRecordByNoChangeSingle(xinyiWarningRecord, tXinyiIndustry, normConfig, category);
+                addChatRecordByNoChangeSingleNew(xinyiWarningRecord, tXinyiIndustry, normConfig, category, last4Str);
             }
             //额外判断当前的异常是哪个指标,并处理标识
             if(BusinessEnum.WarningCategoryEnum.CS_COD.getCode().equals(category)){
@@ -1874,7 +1882,7 @@ public class AsyncTask {
                     tXinyiWarningRecord.setSymbol(BusinessEnum.WarningSymbolEnum.YBGZ_LX_MORE.getCode());
                     this.xinyiWarningRecordMapper.insertTXinyiWarningRecord(tXinyiWarningRecord);
                     //同时处理决策 不用调用大模型,本地处理问答
-                    addChatRecordByNoChangeMore(tXinyiWarningRecord, tXinyiIndustry, normConfig);
+                    addChatRecordByNoChangeMoreNew(tXinyiWarningRecord, tXinyiIndustry, normConfig, last4Str);
                 }
             }else{//之前存在报警了 所以需要2个集合数据进行匹配,如果新的和原来的一样则不用做任何操作【持续报警】;如果不一样,则新的要报警,老报警要关闭
                 List<TXinyiWarningRecord> noChangeListNew = new ArrayList<>(noChangeList);//断点集合[需要新增的]
@@ -1905,7 +1913,7 @@ public class AsyncTask {
                         tXinyiWarningRecord.setSymbol(BusinessEnum.WarningSymbolEnum.YBGZ_LX_MORE.getCode());
                         this.xinyiWarningRecordMapper.insertTXinyiWarningRecord(tXinyiWarningRecord);
                         //同时处理决策 不用调用大模型,本地处理问答
-                        addChatRecordByNoChangeMore(tXinyiWarningRecord, tXinyiIndustry, normConfig);
+                        addChatRecordByNoChangeMoreNew(tXinyiWarningRecord, tXinyiIndustry, normConfig, last4Str);
                     }
                 }
                 //关闭老的报警
@@ -1939,7 +1947,7 @@ public class AsyncTask {
                         //更新数据库
                         this.xinyiWarningRecordMapper.updateTXinyiWarningRecord(tXinyiWarningRecord);
                         //继续调用决策【本地模拟的决策】
-                        addChatRecordByNoChangeMore(tXinyiWarningRecord, tXinyiIndustry, normConfig);
+                        addChatRecordByNoChangeMoreNew(tXinyiWarningRecord, tXinyiIndustry, normConfig, last4Str);
                     }
                 }
             }
@@ -4095,15 +4103,18 @@ public class AsyncTask {
         }
         TXinyiIndustry tXinyiIndustry1 = tXinyiIndustries.get(INDEX_1);//前一个小时
 
+        //拼接决策的最近8小时的值
+        String last8Str = this.getJsNh3StrByList(tXinyiIndustries);
+
         //单点突变-异常升高报警
-        if (existsJsNh3YCSG(jsBzz, currentVal, category, tXinyiIndustry, normConfig, cwrwfhz, tXinyiIndustries, nowDate))
+        if (existsJsNh3YCSG(jsBzz, currentVal, category, tXinyiIndustry, normConfig, cwrwfhz, tXinyiIndustries, nowDate, last8Str))
             return;
 
         //单点突变-异常偏低报警
         //2025年04月15日15:45:48 这种的暂时先不报
 
         //2025年04月16日14:35:48 新增高低值设备报警
-        if (existsJsNh3GDZ(jsBzz, currentVal, category, tXinyiIndustry, normConfig, cwrwfhz, tXinyiIndustries, nowDate))
+        if (existsJsNh3GDZ(jsBzz, currentVal, category, tXinyiIndustry, normConfig, cwrwfhz, tXinyiIndustries, nowDate, last8Str))
             return;
 
         //最开始的工艺报警  (超标准工艺报警) 2025年04月16日15:40:23 改成只有超标准才会报警,并且具体逻辑做拆分
@@ -4214,7 +4225,7 @@ public class AsyncTask {
         return tXinyiWarningRecord;
     }
 
-    private boolean existsJsNh3YCSG(BigDecimal jsBzz, BigDecimal currentVal, String category, TXinyiIndustry tXinyiIndustry, TXinyiNormConfig normConfig, BigDecimal cwrwfhz, List<TXinyiIndustry> tXinyiIndustries, Date nowDate) {
+    private boolean existsJsNh3YCSG(BigDecimal jsBzz, BigDecimal currentVal, String category, TXinyiIndustry tXinyiIndustry, TXinyiNormConfig normConfig, BigDecimal cwrwfhz, List<TXinyiIndustry> tXinyiIndustries, Date nowDate, String last8Str) {
         if(!CollectionUtils.isEmpty(tXinyiIndustries) && tXinyiIndustries.size() == INT_8){
             //查询同类型的历史报警
             TXinyiWarningRecord warningRecordYCSG = TXinyiWarningRecord.builder().type(0).category(category).symbol(BusinessEnum.WarningSymbolEnum.SJYC_YCSG.getCode()).status(0).build();
@@ -4241,11 +4252,11 @@ public class AsyncTask {
                     warningRecordYCSG.setCwrwxz(getCwrwxzByDetail(currentVal, normConfig, category, true));//根据当前值和类型以及是否超标处理
                     this.xinyiWarningRecordMapper.insertTXinyiWarningRecord(warningRecordYCSG);
                     //同时处理决策 不用调用大模型,本地处理问答
-                    addChatRecordByYCSG(warningRecordYCSG, tXinyiIndustry, normConfig, category, exceedVal, resultMap.get(LASTVAL));
+                    addChatRecordByYCSGNew(warningRecordYCSG, tXinyiIndustry, normConfig, category, exceedVal, resultMap.get(LASTVAL), last8Str);
                 }else{
                     log.info("工业库报警的时候,发现存在异常升高的报警,并且已经有该类型报警了,不做任何处理");
                     //2025年04月16日15:56:47 这种的继续报警,所以决策还需要再次调用一次
-                    addChatRecordByYCSG(warningRecordYCSG, tXinyiIndustry, normConfig, category, exceedVal, resultMap.get(LASTVAL));
+                    addChatRecordByYCSGNew(warningRecordYCSG, tXinyiIndustry, normConfig, category, exceedVal, resultMap.get(LASTVAL), last8Str);
                 }
                 //后续的报警不再进行
                 log.info("工业库报警的时候,发现存在{}异常升高的报警,后续报警不再处理", category);
@@ -4260,7 +4271,7 @@ public class AsyncTask {
     }
 
 
-    private boolean existsJsNh3GDZ(BigDecimal jsBzz, BigDecimal currentVal, String category, TXinyiIndustry tXinyiIndustry, TXinyiNormConfig normConfig, BigDecimal cwrwfhz, List<TXinyiIndustry> tXinyiIndustries, Date nowDate) {
+    private boolean existsJsNh3GDZ(BigDecimal jsBzz, BigDecimal currentVal, String category, TXinyiIndustry tXinyiIndustry, TXinyiNormConfig normConfig, BigDecimal cwrwfhz, List<TXinyiIndustry> tXinyiIndustries, Date nowDate, String last8Str) {
         if(!CollectionUtils.isEmpty(tXinyiIndustries) && tXinyiIndustries.size() == INT_8){
             //查询同类型的历史报警
             TXinyiWarningRecord warningRecordGDZ = TXinyiWarningRecord.builder().type(0).category(category).symbol(BusinessEnum.WarningSymbolEnum.SJYC_GDZ.getCode()).status(0).build();
@@ -4269,8 +4280,6 @@ public class AsyncTask {
             Map<String, BigDecimal> resultMap = existsGdzJsNh3(currentVal, category, tXinyiIndustries);
             BigDecimal exceedVal = resultMap.get(EXCEEDVAL);
             if(!Objects.isNull(exceedVal)){//这里不能只返回一个布尔类型的结果,因为还要获取百分比的值
-                //拼接决策的最近8小时的值
-                String last8Str = this.getJsNh3Str8(tXinyiIndustries);
                 //关闭同类型的其他报警
                 closeOtherWarningsByCategory(category, BusinessEnum.WarningSymbolEnum.SJYC_GDZ.getCode());
                 //触发报警 并且模拟大模型返回决策问答数据
@@ -4307,14 +4316,14 @@ public class AsyncTask {
         return false;
     }
 
-    private String getJsNh3Str8(List<TXinyiIndustry> tXinyiIndustries) {
+    private String getJsNh3StrByList(List<TXinyiIndustry> tXinyiIndustries) {
 //        return StringUtil.join(tXinyiIndustries.stream().map(TXinyiIndustry::getJsNh3).collect(Collectors.toList()) , "mg/L、");
         int size = tXinyiIndustries.size();
         StringBuilder sb = new StringBuilder();
         for (int i = 0; i < size; i++) {
             TXinyiIndustry tXinyiIndustry = tXinyiIndustries.get(i);
             if(i < size - 1)
-                sb.append(tXinyiIndustry.getJsNh3()).append("mg/L、");
+                sb.append(DecimalUtils.getAbsAndScale(tXinyiIndustry.getJsNh3(), INT_2)).append("mg/L、");
             else
                 sb.append("mg/L");
         }
@@ -5701,6 +5710,32 @@ public class AsyncTask {
         this.xinyiChatRecordMapper.insertTXinyiChatRecord(chatReq);
     }
 
+
+    private void addChatRecordByYCSGNew(TXinyiWarningRecord warningRecord, TXinyiIndustry tXinyiIndustry, TXinyiNormConfig normConfig, String category, BigDecimal exceedVal, BigDecimal lastVal, String last8Str) {
+        ChatReq chatReq = new ChatReq();
+        //保存聊天记录
+        //将问答更新到数据库中
+        chatReq.setSessionId(IdUtils.simpleUUID());
+        chatReq.setType(1);//0问答 1决策 2本地 3仿真预测
+        chatReq.setModule(3);
+            /*String userId = SecurityUtils.getUserId().toString();
+            String username = SecurityUtils.getUsername();*/
+        chatReq.setUserId(WARNING_DEFAULT_CREATE);
+        String showVal = this.buildShowValue(warningRecord, tXinyiIndustry, normConfig, DateUtils.getNowDate());
+        chatReq.setShowVal(showVal);//前端展示的数据和提问的数据不一致
+        chatReq.setQuestion(BusinessEnum.WarningSymbolEnum.SJYC_YCSG.getMsg());//本地问题
+//        chatReq.setAnswer(category + YCSG_ANSWER_ONE + exceedVal.multiply(BigDecimal_100) + "%" + YCSG_ANSWER_TWO + warningRecord.getWarningVal() + YCSG_ANSWER_THREE);
+//        chatReq.setAnswer(YCSG_ANSWER_REPLACE.replaceAll("@@@0", category).replaceAll("@@@1", String.valueOf(DecimalUtils.getAbsAndScale(warningRecord.getWarningVal(), INT_2))).replaceAll("@@@2", DecimalUtils.getAbsAndScale(exceedVal.multiply(BigDecimal_100), INT_1) + "%").replace("@@@3", String.valueOf(DecimalUtils.getAbsAndScale(lastVal, INDEX_2))));
+        chatReq.setAnswer(YCSG_ANSWER_REPLACE_NEW.replaceAll("@@@0", category).replaceAll("@@@1", last8Str).replaceAll("@@@2", DecimalUtils.getAbsAndScale(exceedVal.multiply(BigDecimal_100), INT_1) + "%").replace("@@@3", String.valueOf(DecimalUtils.getAbsAndScale(lastVal, INDEX_2))));
+        chatReq.setWarningId(String.valueOf(warningRecord.getId()));
+        chatReq.setCounts(1);//问答次数
+
+        chatReq.setCreateBy(WARNING_DEFAULT_CREATE);
+        chatReq.setCreateTime(DateUtils.getNowDate());
+        this.xinyiChatRecordMapper.insertTXinyiChatRecord(chatReq);
+    }
+
+
     private void addChatRecordByYCSG(TXinyiWarningRecord warningRecord, TXinyiIndustry tXinyiIndustry, TXinyiNormConfig normConfig, String category, BigDecimal exceedVal, BigDecimal lastVal) {
         ChatReq chatReq = new ChatReq();
         //保存聊天记录
@@ -5724,6 +5759,39 @@ public class AsyncTask {
         this.xinyiChatRecordMapper.insertTXinyiChatRecord(chatReq);
     }
 
+    /***
+     * 2025年04月18日09:50:50  因为本地决策的当前进水表现从原来的1个值变成了现在的4个值
+     * 单指标连续不变-本地决策-新的
+     * @param warningRecord
+     * @param tXinyiIndustry
+     * @param normConfig
+     * @param category
+     * @param last4Str
+     */
+    private void addChatRecordByNoChangeSingleNew(TXinyiWarningRecord warningRecord, TXinyiIndustry tXinyiIndustry, TXinyiNormConfig normConfig, String category, String last4Str) {
+        ChatReq chatReq = new ChatReq();
+        //保存聊天记录
+        //将问答更新到数据库中
+        chatReq.setSessionId(IdUtils.simpleUUID());
+        chatReq.setType(1);//0问答 1决策 2本地 3仿真预测
+        chatReq.setModule(3);
+            /*String userId = SecurityUtils.getUserId().toString();
+            String username = SecurityUtils.getUsername();*/
+        chatReq.setUserId(WARNING_DEFAULT_CREATE);
+        String showVal = this.buildShowValue(warningRecord, tXinyiIndustry, normConfig, DateUtils.getNowDate());
+        chatReq.setShowVal(showVal);//前端展示的数据和提问的数据不一致
+        chatReq.setQuestion(BusinessEnum.WarningSymbolEnum.YBGZ_LX_SINGLE.getMsg());//本地问题
+//        chatReq.setAnswer(SINGLE_NO_CHANGE_ANSWER_ONE + category + SINGLE_NO_CHANGE_ANSWER_TWO + category + SINGLE_NO_CHANGE_ANSWER_THREE);
+//        chatReq.setAnswer(SINGLE_NO_CHANGE_ANSWER_REPLACE.replaceAll("@@@0", category).replaceAll("@@@1", String.valueOf(DecimalUtils.getAbsAndScale(warningRecord.getWarningVal(), INDEX_2))));
+        chatReq.setAnswer(SINGLE_NO_CHANGE_ANSWER_REPLACE_NEW.replaceAll("@@@0", category).replaceAll("@@@1", last4Str));
+        chatReq.setWarningId(String.valueOf(warningRecord.getId()));
+        chatReq.setCounts(1);//问答次数
+
+        chatReq.setCreateBy(WARNING_DEFAULT_CREATE);
+        chatReq.setCreateTime(DateUtils.getNowDate());
+        this.xinyiChatRecordMapper.insertTXinyiChatRecord(chatReq);
+    }
+
     private void addChatRecordByNoChangeSingle(TXinyiWarningRecord warningRecord, TXinyiIndustry tXinyiIndustry, TXinyiNormConfig normConfig, String category) {
         ChatReq chatReq = new ChatReq();
         //保存聊天记录
@@ -5747,6 +5815,39 @@ public class AsyncTask {
         this.xinyiChatRecordMapper.insertTXinyiChatRecord(chatReq);
     }
 
+    /**
+     * 2025年04月18日09:50:50  因为本地决策的当前进水表现从原来的1个值变成了现在的4个值
+     * 拼装本地决策-单指标断点
+     * @param warningRecord
+     * @param tXinyiIndustry
+     * @param normConfig
+     * @param category
+     * @param last4Str
+     */
+    private void addChatRecordByBreakPointsSingleNew(TXinyiWarningRecord warningRecord, TXinyiIndustry tXinyiIndustry, TXinyiNormConfig normConfig, String category, String last4Str) {
+        ChatReq chatReq = new ChatReq();
+        //保存聊天记录
+        //将问答更新到数据库中
+        chatReq.setSessionId(IdUtils.simpleUUID());
+        chatReq.setType(1);//0问答 1决策 2本地 3仿真预测
+        chatReq.setModule(3);
+            /*String userId = SecurityUtils.getUserId().toString();
+            String username = SecurityUtils.getUsername();*/
+        chatReq.setUserId(WARNING_DEFAULT_CREATE);
+        String showVal = this.buildShowValue(warningRecord, tXinyiIndustry, normConfig, DateUtils.getNowDate());
+        chatReq.setShowVal(showVal);//前端展示的数据和提问的数据不一致
+        chatReq.setQuestion(BusinessEnum.WarningSymbolEnum.YBGZ_DD_SINGLE.getMsg());//本地问题
+//        chatReq.setAnswer(SINGLE_BREAKPOINT_ANSWER_PREFIX + category + SINGLE_BREAKPOINT_ANSWER_SUFFIX);
+//        chatReq.setAnswer(SINGLE_BREAKPOINT_ANSWER_REPLACE.replaceAll("@@@0", category));
+        chatReq.setAnswer(SINGLE_BREAKPOINT_ANSWER_REPLACE_NEW.replaceAll("@@@0", category).replaceAll("@@@1", last4Str));
+        chatReq.setWarningId(String.valueOf(warningRecord.getId()));
+        chatReq.setCounts(1);//问答次数
+
+        chatReq.setCreateBy(WARNING_DEFAULT_CREATE);
+        chatReq.setCreateTime(DateUtils.getNowDate());
+        this.xinyiChatRecordMapper.insertTXinyiChatRecord(chatReq);
+    }
+
     private void addChatRecordByBreakPointsSingle(TXinyiWarningRecord warningRecord, TXinyiIndustry tXinyiIndustry, TXinyiNormConfig normConfig, String category) {
         ChatReq chatReq = new ChatReq();
         //保存聊天记录
@@ -5771,6 +5872,39 @@ public class AsyncTask {
     }
 
 
+    /**
+     * 2025年04月18日09:50:50  因为本地决策的当前进水表现从原来的1个值变成了现在的4个值
+     * 多指标连续不变-本地决策-新的
+     *
+     * @param tXinyiWarningRecord
+     * @param tXinyiIndustry
+     * @param normConfig
+     * @param last4Str
+     */
+    private void addChatRecordByNoChangeMoreNew(TXinyiWarningRecord tXinyiWarningRecord, TXinyiIndustry tXinyiIndustry, TXinyiNormConfig normConfig, String last4Str) {
+        ChatReq chatReq = new ChatReq();
+        //保存聊天记录
+        //将问答更新到数据库中
+        chatReq.setSessionId(IdUtils.simpleUUID());
+        chatReq.setType(1);//0问答 1决策 2本地 3仿真预测
+        chatReq.setModule(3);
+            /*String userId = SecurityUtils.getUserId().toString();
+            String username = SecurityUtils.getUsername();*/
+        chatReq.setUserId(WARNING_DEFAULT_CREATE);
+        String showVal = this.buildShowValue(tXinyiWarningRecord, tXinyiIndustry, normConfig, DateUtils.getNowDate());
+        chatReq.setShowVal(showVal);//前端展示的数据和提问的数据不一致
+        chatReq.setQuestion(BusinessEnum.WarningSymbolEnum.YBGZ_LX_MORE.getMsg());//本地问题
+//        chatReq.setAnswer(MORE_NO_CHANGE_ANSWER);
+//        chatReq.setAnswer(MORE_NO_CHANGE_ANSWER_REPLACE.replaceAll("@@@0", tXinyiWarningRecord.getCategory()).replaceAll("@@@1", String.valueOf(DecimalUtils.getAbsAndScale(tXinyiWarningRecord.getWarningVal(), INT_2))));
+        chatReq.setAnswer(MORE_NO_CHANGE_ANSWER_REPLACE_NEW.replaceAll("@@@0", tXinyiWarningRecord.getCategory()).replaceAll("@@@1", last4Str));
+        chatReq.setWarningId(String.valueOf(tXinyiWarningRecord.getId()));
+        chatReq.setCounts(1);//问答次数
+
+        chatReq.setCreateBy(WARNING_DEFAULT_CREATE);
+        chatReq.setCreateTime(DateUtils.getNowDate());
+        this.xinyiChatRecordMapper.insertTXinyiChatRecord(chatReq);
+    }
+
     private void addChatRecordByNoChangeMore(TXinyiWarningRecord tXinyiWarningRecord, TXinyiIndustry tXinyiIndustry, TXinyiNormConfig normConfig) {
         ChatReq chatReq = new ChatReq();
         //保存聊天记录
@@ -5794,6 +5928,39 @@ public class AsyncTask {
         this.xinyiChatRecordMapper.insertTXinyiChatRecord(chatReq);
     }
 
+
+
+    /**
+     * 2025年04月18日09:50:50  因为本地决策的当前进水表现从原来的1个值变成了现在的4个值
+     * 多指标断点本地解决方案-新的
+     * @param tXinyiWarningRecord
+     * @param tXinyiIndustry
+     * @param normConfig
+     * @param last4Str
+     */
+    private void addChatRecordByBreakPointsMoreNew(TXinyiWarningRecord tXinyiWarningRecord, TXinyiIndustry tXinyiIndustry, TXinyiNormConfig normConfig, String last4Str) {
+        ChatReq chatReq = new ChatReq();
+        //保存聊天记录
+        //将问答更新到数据库中
+        chatReq.setSessionId(IdUtils.simpleUUID());
+        chatReq.setType(1);//0问答 1决策 2本地 3仿真预测
+        chatReq.setModule(3);
+            /*String userId = SecurityUtils.getUserId().toString();
+            String username = SecurityUtils.getUsername();*/
+        chatReq.setUserId(WARNING_DEFAULT_CREATE);
+        String showVal = this.buildShowValue(tXinyiWarningRecord, tXinyiIndustry, normConfig, DateUtils.getNowDate());
+        chatReq.setShowVal(showVal);//前端展示的数据和提问的数据不一致
+        chatReq.setQuestion(BusinessEnum.WarningSymbolEnum.YBGZ_DD_MORE_GYK.getMsg());//本地问题
+//        chatReq.setAnswer(MORE_BREAKPOINT_ANSWER);
+        chatReq.setAnswer(MORE_BREAKPOINT_ANSWER_REPLACE_NEW.replaceAll("@@@0", tXinyiWarningRecord.getCategory()).replaceAll("@@@1", last4Str));
+        chatReq.setWarningId(String.valueOf(tXinyiWarningRecord.getId()));
+        chatReq.setCounts(1);//问答次数
+
+        chatReq.setCreateBy(WARNING_DEFAULT_CREATE);
+        chatReq.setCreateTime(DateUtils.getNowDate());
+        this.xinyiChatRecordMapper.insertTXinyiChatRecord(chatReq);
+    }
+
     private void addChatRecordByBreakPointsMore(TXinyiWarningRecord tXinyiWarningRecord, TXinyiIndustry tXinyiIndustry, TXinyiNormConfig normConfig) {
         ChatReq chatReq = new ChatReq();
         //保存聊天记录