Browse Source

每日生成简报定时任务 和 获取首页简报接口

wangmiaomiao 1 year ago
parent
commit
36abddc22c

+ 12 - 0
slibra-admin/src/main/java/com/slibra/web/controller/business/FrontController.java

@@ -289,6 +289,18 @@ public class FrontController extends BaseController {
     }
 
 
+
+    /**
+     * 获取 首页简报的问答数据
+     * @return
+     */
+    @GetMapping("/bigModel/home/getLeastShortReport}")
+    public AjaxResult getLeastShortReport()
+    {
+        log.info("进入了 首页简报的问答数据获取  接口");
+        return AjaxResult.success(frontService.getLeastShortReport());
+    }
+
     //--------------------下面是测试的方法--------------------
     /*@GetMapping("/test/data")
     public void testData(){

+ 11 - 6
slibra-admin/src/main/java/com/slibra/web/controller/business/GRPCController.java

@@ -148,7 +148,7 @@ public class GRPCController extends BaseController {
             while (predictions.hasNext()) {
                 String responseStr = predictions.next().getPrediction().toStringUtf8();
                 log.info("决策流式返回的结果是{}", responseStr);
-//                responseStr = JSON.parseObject(responseStr).getString("message");
+                String message = JSON.parseObject(responseStr).getString("message");
                 //2024年5月25日16:37:16  按照大模型返回的类型解析数据
                 String biz = JSON.parseObject(responseStr).getString("biz");
 //                String message = JSON.parseObject(responseStr).getString("message");
@@ -164,9 +164,13 @@ public class GRPCController extends BaseController {
                     outputStream.flush();*/
                 }else{//其他 要么错误 要么alert 要么出的报告
 //                    sb.append(responseStr);
-                    resultData.add(responseStr);
-                    outputStream.write(responseStr.getBytes());
-                    outputStream.flush();
+                    if(StringUtils.isBlank(message)){
+                        log.error("×××××××××××××××××××××××××××为空的数据暂时不返回×××××××××××××××××××××××××××");
+                    }else {
+                        resultData.add(responseStr);
+                        outputStream.write(responseStr.getBytes());
+                        outputStream.flush();
+                    }
                 }
             }
         } catch (Exception e) {
@@ -201,7 +205,8 @@ public class GRPCController extends BaseController {
             chatReq.setUserId(userId);
             chatReq.setCreateBy(username);
             chatReq.setCreateTime(DateUtils.getNowDate());
-            this.xinyiChatRecordMapper.insertTXinyiChatRecord(chatReq);
+            //todo 现在测试,暂时注释掉。 等测试完毕,打开注释。
+//            this.xinyiChatRecordMapper.insertTXinyiChatRecord(chatReq);
             // 关闭输出流
             try {
                 outputStream.close();
@@ -278,7 +283,7 @@ public class GRPCController extends BaseController {
             //将结果记录到问答表
             while (predictions.hasNext()) {
                 String responseStr = predictions.next().getPrediction().toStringUtf8();
-                System.out.println(responseStr);
+                log.info("大模型问答返回的原始结果为{}", responseStr);
                 responseStr = JSON.parseObject(responseStr).getString("message");
                 if("complete".equals(responseStr)){
                     System.out.println("结尾语句并且是非JSON,无需处理");

+ 34 - 2
slibra-common/src/main/java/com/slibra/common/constant/MyConstants.java

@@ -25,8 +25,40 @@ public class MyConstants {
     public static final String WARNING_DEFAULT_QUESTION= "在线仪表数据异常";
     public static final String WARNING_DEFAULT_CREATE = "task-job";
     public static final String DEFAULT_ID_IDENTIFIER = "@@id@@";
-
-
     public static final int MAX_COUNT = 30;
+    public static final String JIAN_BAO_END = "简报";
+
+    //简报的prompt
+    public static final String JIAN_BAO_PROMPT = "作为一个工艺分析师,请生成一份#{0}日分析报告,根据我提供的详细数据,输出一份详细的分析报告。报告需数据准确、分析深入,建议具体可行,以便为水务管理和决策提供支持。整体文字在500字内,报告分为三部分:\n" +
+            "\n" +
+            "\n" +
+            "\n" +
+            "     1、水质数据指标超标情况分析\n" +
+            "\n" +
+            "     2、对于超标的数据推送解决方案,没有超标情况的话,对比前一日数据,计算数据同比和可能出现异常的情况\n" +
+            "\n" +
+            "     3、提出针对性的改善建议,包括但不限于优化处理工艺、加强水质监测、改善水源保护等。\n" +
+            "\n" +
+            "   \n" +
+            "\n" +
+            "     #{0}日进出水质数据:\n" +
+            "\n" +
+            "进水  -  COD:#{2}mg/L  、 TN:#{3}mg/L 、TP:#{4}mg/L、NH3-N:#{5}mg/L、SS:#{6}mg/L、进水水量:#{7}m³/d\n" +
+            "\n" +
+            "出水  -  COD:#{8}mg/L  、 TN:#{9}mg/L 、TP:#{10}mg/L、NH3-N:#{11}mg/L、SS:#{12}mg/L、出水水量:#{13}m³/d\n" +
+            "\n" +
+            "     #{1}日进出水质数据:\n" +
+            "\n" +
+            "\n" +
+            "\n" +
+            "进水  -  COD:#{14}mg/L  、 TN:#{15}mg/L 、TP:#{16}mg/L、NH3-N:#{17}mg/L、SS:#{18}mg/L、进水水量:#{19}m³/d\n" +
+            "\n" +
+            "出水  -  COD:#{20}mg/L  、 TN:#{21}mg/L 、TP:#{22}mg/L、NH3-N:#{23}mg/L、SS:#{24}mg/L、出水水量:#{25}m³/d\n" +
+            "\n" +
+            "     标准值定义:\n" +
+            "\n" +
+            "进水  -  COD:#{26}mg/L  、 #{27}TN:mg/L 、TP:#{28}mg/L、NH3-N:#{29}mg/L、SS:#{30}mg/L\n" +
+            "\n" +
+            "出水  -  COD:#{31}mg/L  、 TN:#{32}mg/L 、TP:#{33}mg/L、NH3-N:#{34}mg/L、SS:#{35}mg/L";
 
 }

+ 154 - 2
slibra-quartz/src/main/java/com/slibra/quartz/task/RyTask.java

@@ -15,6 +15,7 @@ import com.slibra.common.constant.MyConstants;
 import com.slibra.common.enums.BusinessEnum;
 import com.slibra.common.enums.DataSourceType;
 import com.slibra.common.utils.DateUtils;
+import com.slibra.common.utils.ip.IpUtils;
 import com.slibra.common.utils.uuid.IdUtils;
 import com.slibra.framework.datasource.DynamicDataSourceContextHolder;
 import inference.InferenceAPIsServiceGrpc;
@@ -28,6 +29,7 @@ import org.springframework.stereotype.Component;
 import com.slibra.common.utils.StringUtils;
 import org.springframework.util.CollectionUtils;
 
+import java.io.IOException;
 import java.math.BigDecimal;
 import java.math.RoundingMode;
 import java.time.LocalDateTime;
@@ -852,6 +854,153 @@ public class RyTask
     }
 
 
+    public void generageShortReport(){
+        log.info("进入了定时生成每日简报数据");
+        List<TXinyiDaily> dailyTwoRecords = this.xinyiDailyMapper.selectNRecords(2);
+        //正常不会有这种问题 因为日报有很多条
+        if(CollectionUtils.isEmpty(dailyTwoRecords) || dailyTwoRecords.size() < 2){
+            log.error("进入了定时生成每日简报数据 获取最新的2条数据不足,终止");
+            return;
+        }
+        //暂时不考虑因为没有填写日报 导致生成重复数据的问题(后续需要的话再添加)
+        //处理数据 并 拼装
+        String queryData = buildShortReportQueryData(dailyTwoRecords);
+        log.info("定时生成简报,组装好的请求大模型的参数为{}", queryData);
+        if(StringUtils.isBlank(queryData)){
+            log.error("无法拼装请求数据!!!!!!");
+            return;
+        }
+        String showVal = formateDateStr(dailyTwoRecords.get(0).getTestDate()) + JIAN_BAO_END;
+        //调用模型 并保存结果
+        this.askBigModel(queryData, showVal);
+        log.info("定时生成简报任务结束~~~~~~~~~~~~~~");
+    }
+
+    /**
+     *
+     * 2022/01/01 转成2022年01月01日 数据
+     * @param testDate
+     * @return
+     */
+    private String formateDateStr(String testDate) {
+        if(StringUtils.isBlank(testDate))
+            return "";
+        if(!testDate.contains("/"))
+            return testDate;
+        String[] split = testDate.split("/");
+        return split[0] + "年" + split[1] + "月" + split[2] + "日";
+    }
+
+    private void askBigModel(String question, String showVal) {
+        log.info("进入了后台接口调⽤⼤模型获取问答结果处理");
+        StringBuilder sb = new StringBuilder();
+        String sessionId = IdUtils.simpleUUID();
+        ChatReq chatReq = new ChatReq();
+        String ipAddr = IpUtils.getIpAddr();//获取用户的ip地址 传给大模型
+        int counts = 1;//默认是第一次
+        //这种问答 没有历史问答的概念 直接把问题扔进去就行 无需查询历史记录
+        List<String> historyDates = new ArrayList<>();
+        historyDates.add(question);
+        // 获取输出流
+        ManagedChannel channel = null;
+        try {
+            channel = ManagedChannelBuilder.forAddress("10.0.0.24", 17070)
+                    .usePlaintext()
+                    .build();
+            InferenceAPIsServiceGrpc.InferenceAPIsServiceBlockingStub stub = InferenceAPIsServiceGrpc.newBlockingStub(channel);
+            String dataJson = "{\"bot_id\":\"721\",\"exp_id\":\"721\",\"session_id\":\"" + sessionId + "\",\"use_rag\":\"true\",\"prompt\":\"你是⼀个资深⽔务领域专家,能回答各种⽔务相关问题\",\"history_dia\":" + JSON.toJSONString(historyDates) + ",\"generate_args\":{\"max_new_tokens\":2048,\"max_length\":4096,\"num_beams\":1,\"do_sample\":true,\"top_p\":0.7,\"temperature\":0.95},\"extra\":{ \"ip_address\": \"" + ipAddr  + "\" },\"strengthen\":" + (false) + "}";
+            log.info("请求大模型的问答参数为{}", dataJson);
+            PredictionsRequest request = PredictionsRequest.newBuilder()
+                    .setModelName("slibra_bot")
+                    .putInput("method", ByteString.copyFrom("infer_stream", "utf-8"))//推理
+                    .putInput("data", ByteString.copyFrom(dataJson, "utf-8"))
+                    .buildPartial();
+            Iterator<PredictionResponse> predictions = stub.streamPredictions(request);
+            //将结果记录到问答表
+            while (predictions.hasNext()) {
+                String responseStr = predictions.next().getPrediction().toStringUtf8();
+                log.info("大模型问答返回的原始结果为{}", responseStr);
+                responseStr = JSON.parseObject(responseStr).getString("message");
+                if("complete".equals(responseStr)){
+                    System.out.println("结尾语句并且是非JSON,无需处理");
+                    //结束语句也流式输出,但是并不记录下来  2024年5月24日11:15:23 也不返回前端
+                    /*outputStream.write(responseStr.getBytes());
+                    outputStream.flush();*/
+                }else{
+                    sb.append(responseStr);
+                }
+            }
+            //将问答更新到数据库中
+            chatReq.setSessionId(sessionId);
+            chatReq.setType(0);//0问答 1决策
+            chatReq.setModule(4);//0专家问答 1智能工单 2智能体助手 3告警 4简报
+            chatReq.setShowVal(showVal);
+            chatReq.setQuestion(question);
+            chatReq.setAnswer(sb.toString());
+            chatReq.setCounts(counts);//问答次数
+            chatReq.setUserId(WARNING_DEFAULT_CREATE);
+            chatReq.setCreateBy(WARNING_DEFAULT_CREATE);
+            chatReq.setCreateTime(DateUtils.getNowDate());
+            this.xinyiChatRecordMapper.insertTXinyiChatRecord(chatReq);
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        } finally {
+            // 关闭输出流
+            channel.shutdown();
+        }
+    }
+
+    private String buildShortReportQueryData(List<TXinyiDaily> dailyTwoRecords) {
+        //查询配置信息
+        List<TXinyiNormConfig> tXinyiNormConfigs = this.xinyiNormConfigMapper.selectTXinyiNormConfigList(null);
+        if(CollectionUtils.isEmpty(tXinyiNormConfigs))
+            return null;
+        TXinyiNormConfig normConfig = tXinyiNormConfigs.get(0);
+        //获取数据
+        TXinyiDaily yesterdayData = dailyTwoRecords.get(0);
+        TXinyiDaily beforeYesterdayData = dailyTwoRecords.get(1);
+        String originStr = JIAN_BAO_PROMPT;
+        String yesterdayStr = yesterdayData.getTestDate().substring(5).replace("/", "月") +  "日";
+        String beforeYesterdayStr = beforeYesterdayData.getTestDate().substring(5).replace("/", "月") +  "日";
+        originStr = originStr.replace("#{0}", yesterdayStr);
+        originStr = originStr.replace("#{1}", beforeYesterdayStr);
+        originStr = originStr.replace("#{2}", String.valueOf(yesterdayData.getJsCod()));
+        originStr = originStr.replace("#{3}", String.valueOf(yesterdayData.getJsTn()));
+        originStr = originStr.replace("#{4}", String.valueOf(yesterdayData.getJsTp()));
+        originStr = originStr.replace("#{5}", String.valueOf(yesterdayData.getJsNh3()));
+        originStr = originStr.replace("#{6}", String.valueOf(yesterdayData.getJsSs()));
+        originStr = originStr.replace("#{7}", String.valueOf(yesterdayData.getJSL()));
+        originStr = originStr.replace("#{8}", String.valueOf(yesterdayData.getCsCod()));
+        originStr = originStr.replace("#{9}", String.valueOf(yesterdayData.getCsTn()));
+        originStr = originStr.replace("#{10}", String.valueOf(yesterdayData.getCsTp()));
+        originStr = originStr.replace("#{11}", String.valueOf(yesterdayData.getCsNh3()));
+        originStr = originStr.replace("#{12}", String.valueOf(yesterdayData.getCsSs()));
+        originStr = originStr.replace("#{13}", String.valueOf(yesterdayData.getCSL()));
+        originStr = originStr.replace("#{14}", String.valueOf(beforeYesterdayData.getJsCod()));
+        originStr = originStr.replace("#{15}", String.valueOf(beforeYesterdayData.getJsTn()));
+        originStr = originStr.replace("#{16}", String.valueOf(beforeYesterdayData.getJsTp()));
+        originStr = originStr.replace("#{17}", String.valueOf(beforeYesterdayData.getJsNh3()));
+        originStr = originStr.replace("#{18}", String.valueOf(beforeYesterdayData.getJsSs()));
+        originStr = originStr.replace("#{19}", String.valueOf(beforeYesterdayData.getJSL()));
+        originStr = originStr.replace("#{20}", String.valueOf(beforeYesterdayData.getCsCod()));
+        originStr = originStr.replace("#{21}", String.valueOf(beforeYesterdayData.getCsTn()));
+        originStr = originStr.replace("#{22}", String.valueOf(beforeYesterdayData.getCsTp()));
+        originStr = originStr.replace("#{23}", String.valueOf(beforeYesterdayData.getCsNh3()));
+        originStr = originStr.replace("#{24}", String.valueOf(beforeYesterdayData.getCsSs()));
+        originStr = originStr.replace("#{25}", String.valueOf(beforeYesterdayData.getCSL()));
+        originStr = originStr.replace("#{26}", String.valueOf(normConfig.getJscodSjz()));
+        originStr = originStr.replace("#{27}", String.valueOf(normConfig.getJszdSjz()));
+        originStr = originStr.replace("#{28}", String.valueOf(normConfig.getJszlSjz()));
+        originStr = originStr.replace("#{29}", String.valueOf(normConfig.getJsadSjz()));
+        originStr = originStr.replace("#{30}", String.valueOf(normConfig.getJsssSjz()));
+        originStr = originStr.replace("#{31}", String.valueOf(normConfig.getCscodBzz()));
+        originStr = originStr.replace("#{32}", String.valueOf(normConfig.getCszzBzz()));
+        originStr = originStr.replace("#{33}", String.valueOf(normConfig.getCszlBzz()));
+        originStr = originStr.replace("#{34}", String.valueOf(normConfig.getCsadBzz()));
+        originStr = originStr.replace("#{35}", String.valueOf(normConfig.getCsssBzz()));
+        return originStr;
+    }
+
 
     public static String handleDate(String str){
         StringBuilder sb = new StringBuilder();
@@ -906,7 +1055,7 @@ public class RyTask
         LocalDateTime startTime = LocalDateTime.parse(str.replaceAll("/", "-").replace(" ", "T"));
         System.out.println(startTime.plusMinutes(1L).format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));*/
 
-        ArrayList<Integer> objects = new ArrayList<>();
+        /*ArrayList<Integer> objects = new ArrayList<>();
         objects.add(1);
         objects.add(2);
         objects.add(3);
@@ -925,7 +1074,10 @@ public class RyTask
         map.put("d", '1');
         System.out.println(JSON.toJSONString(map, JSONWriter.Feature.WriteNulls));
         TXinyiIndustry tXinyiIndustry = new TXinyiIndustry();
-        System.out.println(JSON.toJSONString(tXinyiIndustry, JSONWriter.Feature.WriteNulls));
+        System.out.println(JSON.toJSONString(tXinyiIndustry, JSONWriter.Feature.WriteNulls));*/
+
+        String s = "2022/01/01".substring(5).replace("/", "月") + "日";
+        System.out.println("s = " + s);
     }
 
 

+ 2 - 2
slibra-system/src/main/java/com/slibra/business/domain/TXinyiChatRecord.java

@@ -34,8 +34,8 @@ public class TXinyiChatRecord extends BaseEntity
     @Excel(name = "类型", readConverterExp = "0=问答,1=决策,2=本地")
     private Integer type;
 
-    /** 隶属哪个模块(0专家问答 1智能工单 2智能体助手 3告警) */
-    @Excel(name = "隶属哪个模块", readConverterExp = "0=专家问答,1=智能工单,2=智能体助手,3.告警")
+    /** 隶属哪个模块(0专家问答 1智能工单 2智能体助手 3告警 4简报) */
+    @Excel(name = "隶属哪个模块", readConverterExp = "0=专家问答,1=智能工单,2=智能体助手,3.告警, 4.简报")
     private Integer module;
 
     /** 用户ID */

+ 2 - 0
slibra-system/src/main/java/com/slibra/business/mapper/TXinyiDailyMapper.java

@@ -67,4 +67,6 @@ public interface TXinyiDailyMapper
     HashMap<String, BigDecimal> selectAvgWater(@Param("begin") String begin, @Param("end") String end);
 
     TXinyiDaily selectNewestData();
+
+    List<TXinyiDaily> selectNRecords(int size);
 }

+ 2 - 0
slibra-system/src/main/java/com/slibra/business/service/IFrontService.java

@@ -30,4 +30,6 @@ public interface IFrontService
     String isSatisfiedAnswer(ChatReq chatReq);
 
     String handleWarningByMan(TXinyiWarningRecord warningRecord);
+
+    TXinyiChatRecord getLeastShortReport();
 }

+ 6 - 0
slibra-system/src/main/java/com/slibra/business/service/impl/FrontServiceImpl.java

@@ -131,6 +131,12 @@ public class FrontServiceImpl implements IFrontService {
         return "操作成功";
     }
 
+    @Override
+    public TXinyiChatRecord getLeastShortReport() {
+        List<TXinyiChatRecord> tXinyiChatRecords = this.xinyiChatRecordMapper.selectTXinyiChatRecordList(TXinyiChatRecord.builder().module(4).build());
+        return CollectionUtils.isEmpty(tXinyiChatRecords) ? null : tXinyiChatRecords.get(0);
+    }
+
     private XinyiIndustrySimple calculateData(XinyiIndustrySimple xinyiIndustrySimple, LocalDateTime nowTime) {
         LocalDateTime yesterdaySameTime = nowTime.plusDays(-1);
         DateTimeFormatter formatter = DateTimeFormatter.ofPattern(DateUtils.YYYYMMDDHH_TS);

+ 5 - 0
slibra-system/src/main/resources/mapper/business/TXinyiDailyMapper.xml

@@ -380,4 +380,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
     <select id="selectNewestData" resultMap="TXinyiDailyResult">
         <include refid="selectTXinyiDailyVo"/> order by id desc limit 1
     </select>
+
+
+    <select id="selectNRecords" resultMap="TXinyiDailyResult">
+        <include refid="selectTXinyiDailyVo"/> order by id desc limit #{size}
+    </select>
 </mapper>