Browse Source

feat: 水质报告调整

sunxiao 10 months ago
parent
commit
c0e8a72a0e

+ 5 - 0
src/api/water.js

@@ -20,6 +20,11 @@ export const waterApi = {
   */
   getWaterStream: ({ data, onDownloadProgress, signal }) => http.post('/grpc/decisionStream', data, { onDownloadProgress, signal, }),
 
+  /**
+   * 获取预测
+  */
+  getWaringForecast: params => http.get('/front/bigModel/warning/forecastList/' + params),
+
   // getAnswerHistoryList: params => http.get('/front/bigModel/qa/pageList', { params }),
 
   // getAnswerHistoryDetail: params => http.get('/front/bigModel/qa/qaListBySessionId', { params }),

BIN
src/assets/images/login/bg-login.png


BIN
src/assets/images/login/bg-login1.png


+ 4 - 0
src/assets/styles/common.scss

@@ -95,6 +95,10 @@
     .message-inner {
       width: 194px;
       flex-shrink: 0;
+
+      span {
+        white-space: nowrap;
+      }
     }
 
     .table-inner {

+ 5 - 1
src/components/Chat/ChatAnswer.vue

@@ -31,6 +31,10 @@ const props = defineProps({
   toggleVisibleIcons: {
     type: Boolean,
     default: true
+  },
+  loadingText: {
+    type: String,
+    default: '内容生成中...'
   }
 })
 
@@ -60,7 +64,7 @@ const handleCopy = () => {
 </script>
 
 <template>
-  <ChatBaseCard class="answer-inner" :loading="loading" :delayLoading="delayLoading">
+  <ChatBaseCard class="answer-inner" :loading="loading" :delayLoading="delayLoading" :loadingText="loadingText">
 
     <slot></slot>
     

+ 5 - 1
src/components/Chat/ChatBaseCard.vue

@@ -36,6 +36,10 @@ const props = defineProps({
     type: Boolean,
     default: false
   },
+  loadingText: {
+    type: String,
+    default: "内容生成中..."
+  }
 })
 
 </script>
@@ -54,7 +58,7 @@ const props = defineProps({
       <div class="flex-1 pt-[4px] ml-[16px] text-[15px]">
 
         <template v-if="loading && delayLoading">
-          <p class="font-bold text-[#1A2029] leading-[24px]">内容生成中...</p>
+          <p class="font-bold text-[#1A2029] leading-[24px]">{{ loadingText }}</p>
         </template>
 
         <slot></slot>

+ 1 - 1
src/components/Layout/TheLogo.vue

@@ -17,7 +17,7 @@ const changeCollapse = () => appStore.toggleSubMenuCollapse();
       <div class="w-[28px] h-[28px]">
         <SvgIcon name="common-logo" size="28"></SvgIcon>
       </div>
-      <span class="block w-[70px] font-[10px]">人工智能运营体智慧决策助手</span>
+      <span class="block w-[70px] font-[10px] text-center">人工智能运营体智慧决策助手</span>
     </div>
     <!-- 图标 -->
     <div class="icon-group flex items-center justify-center"  @click="changeCollapse" v-show="!subMenuCollapse">

+ 1 - 1
src/components/Layout/TheMenu.vue

@@ -27,7 +27,7 @@ function renderChildrenIcon({ name, size = '20' }) {
 }
 
 function renderLabel (val, url) {
-  return url ? (<a href={ url } target="_blank" class="pl-1">{ val }</a>) : (<span class="pl-1">{ val }</span>) ;
+  return url ? (<a href={ url } target="_blank" class="pl-1">{ val }</a>) : (<span class="">{ val }</span>) ;
 }
 
 const menuOptions = [

+ 1 - 0
src/components/Layout/ThePublicLayout.vue

@@ -13,6 +13,7 @@ const initWraingListData = async () => {
 }
 
 onMounted(() => {
+  initWraingListData();
   setInterval(_ => initWraingListData(), 60 * 60 * 1000)
 })
 

+ 2 - 2
src/views/analyse/PymolView.vue

@@ -148,8 +148,8 @@ const handleWelcomeRecommend = question => {
     <TheChatView ref="scrollRef" :is-footer="false">
 
       <ChatWelcome title="您好,我是LibraAI工艺管控助手" card-title="常见处理方案:" :sub-title="[
-        '报警分析功能具备实时监测与预警机制,检测到异常情况推送相关工作人员确保问题及时处理。',
-        '报警时间为每小时警报,请大家及时处理'
+        '水质报警功能对工艺过程指标实时监测,发现异常后将推送给相关人员决策方案',
+        '报警时间为每小时警报,请大家及时处理'
       ]"
         v-if="!textDataSources"
         :card-content="recommendList"

+ 119 - 32
src/views/analyse/WaterView.vue

@@ -15,9 +15,10 @@ import { useInfinite } from '@/composables/useInfinite';
 import { useRecommend } from '@/composables/useRecommend';
 import { useFetchStream } from '@/composables/useFetchStream';
 import { useScroll } from '@/composables/useScroll';
+import { SIMULATE_ENUM } from './components/config';
 
 const { recommendList } = useRecommend({type: 1});
-const { scrollRef, scrollToTop, scrollToBottomIfAtBottom } = useScroll();
+const { scrollRef, scrollToTop, scrollToBottom, scrollToBottomIfAtBottom } = useScroll();
 const { refetch, cancelFetch } = useFetchStream("/grpc/decisionStream", { methdos: 'POST' }, false);
 const { recordList, isFetching, onScrolltolower, onRestore, addHistoryRecord } = useInfinite('/front/bigModel/warning/pageList', { type: 0, warningStatus: 0 });
 
@@ -31,7 +32,7 @@ const flowParams = {
   feedback: '',
   category: '',
   warningId: '',
-  simulate: null
+  simulate: '{}'
 };
 
 const answerLoading = ref(false);
@@ -109,7 +110,6 @@ const columns = [
   }
 ]
 
-
 // 新建对话
 const handleCreateDialog = () => {
   console.log("handleCreateDialog");
@@ -132,44 +132,97 @@ const handleOpenContent = async ({ id, category }) => {
 
   flowParams.category = category;
   flowParams.warningId = id;
+  flowParams.feedback = '';
+  flowParams.simulate = '{}';
 
   const { data } = await waterApi.getWaringDetails(id);
+  const res = await waterApi.getWaringForecast(id);
+
   const showVal = JSON.parse(data.showVal);
   const { basic, jsData, csData } = showVal;
   const answer = JSON.parse(data.answer);
-  const [ answerStrItem ] = answer;
-  const answerObjItem = JSON.parse( answerStrItem );
-  
+ 
   cancelFetch();
 
   answerResult.value = [];
 
-  const textWhiteList = [
-    { label: '报警时间', realKey: '报警时间', value: '', isWarning: false },
-    { label: '报警值',   realKey: '报警值', value: 'mg/L', isWarning: true },
-    { label: '管控值',   realKey: '管控值', value: 'mg/L', isWarning: false },
-    { label: '标准值',   realKey: '标准值', value: 'mg/L', isWarning: false },
-    { label: '报警级别', realKey: '告警级别', value: '', isWarning: false },
-    { label: '报警次数', realKey: '报警次数', value: '', isWarning: false },
-    { label: '状态',     realKey: '状态', value: '', isWarning: false }
-  ]
+  const reportList = [];
+  const alertList = [];
+
+  answer.map(item => {
 
-  if ( answerObjItem.biz === "DECISION_REPORT" ) {
+    const answerObjItem = JSON.parse( item );
 
-    const answerContent = answer.map(item => {
-      const itemParse = JSON.parse(item); 
-      return itemParse.message;
-    }).join("");
+    console.log( answerObjItem );
+
+    if ( answerObjItem.biz === "DECISION_REPORT" ) {
+      reportList.push(answerObjItem.message);
+
+      // const answerContent = answer.map(item => {
+      //   const itemParse = JSON.parse(item); 
+      //   return itemParse.message;
+      // }).join("");
+
+      // answerResult.value.push({
+      //   biz: 'DECISION_REPORT',
+      //   answer: answerContent,
+      //   loading: false,
+      //   delayLoading: false
+      // })
+    }
+
+    if( answerObjItem.biz === "DECISION_ALERT" ) {
+      alertList.push(item);
+      // const [ parseAnswer ] = answer.map(item => {
+      //   const result = JSON.parse( item );
+      //   result.message = Object.keys(result.message).map(key => ({ ...result.message[key], isActive: null }));
+      //   return result;
+      // })
+
+      // answerResult.value.push({
+      //   biz: 'DECISION_ALERT',
+      //   loading: false,
+      //   delayLoading: false,
+      //   isAllSelect: false,
+      //   list: parseAnswer?.message
+      // })
+    }
+
+    if (answerObjItem.biz === "DECISION_SIMULATE") {
+      
+
+
+      // const usefulkeys = ['on', 'off'];
+      // const resultObj = {};
+
+      // usefulkeys.forEach(key => {
+      //   const tempArr = data[key];
+
+      //   resultObj[key] = tempArr.map(item => {
+      //     return {
+      //       ...item,
+      //       label: SIMULATE_ENUM[item.name],
+      //       inpVal: Array.isArray( item.value ) ? item.value.join() : item.value,
+      //       errMsg: ''
+      //     }
+      //   })
+      // })
+    }
 
+  })
+
+  if ( reportList.length ) {
+    const answerContent = reportList.join("");
     answerResult.value.push({
       biz: 'DECISION_REPORT',
       answer: answerContent,
       loading: false,
       delayLoading: false
     })
+  }
 
-  } else {
-    const [ parseAnswer ] = answer.map(item => {
+  if ( alertList.length ) {
+    const [ parseAnswer ] = alertList.map(item => {
       const result = JSON.parse( item );
       result.message = Object.keys(result.message).map(key => ({ ...result.message[key], isActive: null }));
       return result;
@@ -183,7 +236,26 @@ const handleOpenContent = async ({ id, category }) => {
     })
   }
 
-  console.log( basic );
+  // console.log( "reportList", reportList );
+  // console.log( "alertList", alertList );
+  // const [ answerStrItem ] = answer;
+  // const answerObjItem = JSON.parse( answerStrItem );
+
+
+
+
+  // console.log( "answerObjItem", answer, JSON.parse(answerObjItem.message) );
+  const textWhiteList = [
+    { label: '报警时间', realKey: '报警时间', value: '', isWarning: false },
+    { label: '报警值',   realKey: '报警值', value: 'mg/L', isWarning: true },
+    { label: '管控值',   realKey: '管控值', value: 'mg/L', isWarning: false },
+    { label: '标准值',   realKey: '标准值', value: 'mg/L', isWarning: false },
+    { label: '报警级别', realKey: '告警级别', value: '', isWarning: false },
+    { label: '报警次数', realKey: '报警次数', value: '', isWarning: false },
+    { label: '状态',     realKey: '状态', value: '', isWarning: false }
+  ]
+
+
   textDataSources.value = format.textSorting(basic, textWhiteList);
 
   jsTableData.value = [jsData];
@@ -196,6 +268,12 @@ const onChangeTabs = warningStatus => {
   textDataSources.value = '';
   answerLoading.value = false;
   answerResult.value = [];
+  flowParams = {
+    feedback: '',
+    category: '',
+    warningId: '',
+    simulate: '{}'
+  };
   cancelFetch();
   onRestore({ warningStatus })
 }
@@ -215,7 +293,7 @@ const onRegenerate = async () => {
 
   let tempSimulate = null;
 
-  answerLoading.value = true;
+  answerLoading.value = answerResult.value[len -1 ].biz !== 'DECISION_TABLE';
 
   const params = {
     body: JSON.stringify(flowParams),
@@ -230,6 +308,7 @@ const onRegenerate = async () => {
 
       if (item.biz === 'DECISION_REPORT') {
         tempReport.answer += item.message;
+        tempReport.delayLoading = false;
         answerResult.value[len] = { ...tempReport };
       }
       
@@ -239,7 +318,7 @@ const onRegenerate = async () => {
         answerResult.value.push({
           biz: 'DECISION_ALERT',
           loading: true,
-          delayLoading: true,
+          delayLoading: false,
           isAllSelect: false,
           list
         })
@@ -251,7 +330,7 @@ const onRegenerate = async () => {
         if ( lastAnswerItem.biz === 'DECISION_TABLE' ) {
           answerResult.value[len - 1] = {
             ...lastAnswerItem,
-            content: JSON.parse(item.message).pred.join(",")
+            content: JSON.parse(item.message).pred.join(", ")
           }
         } else {
           const { off, on, pred } = JSON.parse(item.message);
@@ -264,7 +343,6 @@ const onRegenerate = async () => {
           }
           modalData.value = tempSimulate;
         }
-        console.log("DECISION_SIMULATE")
       }
 
       scrollToBottomIfAtBottom();
@@ -278,10 +356,18 @@ const onRegenerate = async () => {
     if (answerItem?.biz) {
       answerItem.loading = false;
       answerItem.delayLoading = false;
+
+      if (answerItem.biz === 'DECISION_TABLE') {
+        scrollToBottom()
+      }
     }
     if (tempSimulate) {
       answerResult.value.push(tempSimulate);
     }
+    
+    // setTimeout(() => {
+    //   scrollToBottomIfAtBottom();
+    // }, 500)
   }
   catch(error) {
     console.log("exist error .....", error);
@@ -367,8 +453,8 @@ const handleWelcomeRecommend = question => {
 
       <ChatWelcome title="您好,我是LibraAI工艺管控助手" card-title="常见处理方案:"
         :sub-title="[
-          '报警分析功能具备实时监测与预警机制,检测到异常情况推送相关工作人员确保问题及时处理。',
-          '报警时间为每小时警报,请大家及时处理'
+          '水质报警功能针对五大核心指标实时监测,发现异常后将推送给相关人员决策方案',
+          '报警时间为每小时警报,请大家及时处理'
         ]" 
         :card-content="recommendList"
         @on-click="handleWelcomeRecommend"
@@ -401,7 +487,7 @@ const handleWelcomeRecommend = question => {
           </div>
         </div>
       </ChatBaseCard>
-
+  
       <section v-for="item,index in answerResult" :key="index">
         <template v-if="item.biz === 'DECISION_REPORT'">
           <ChatAnswer
@@ -411,7 +497,7 @@ const handleWelcomeRecommend = question => {
             :content="item.answer"
           ></ChatAnswer>
         </template>
-        <!-- {{ item }} -->
+        
         <template v-if="item.biz === 'DECISION_ALERT'">
           <ChatBaseCard
             :loading="item.loading"
@@ -468,7 +554,7 @@ const handleWelcomeRecommend = question => {
                 </tbody>
               </table>
               <strong class="block mb-[16px]">预测推演结果:</strong>
-              <span>出水硝酸盐:{{ item.content }}</span>
+              <span>未来三小时好氧池硝酸盐预测结果:{{ item.content }}</span>
             </div>
           </ChatAnswer>
           <button class="
@@ -489,6 +575,7 @@ const handleWelcomeRecommend = question => {
         :delay-loading="answerLoading"
         :toggleVisibleIcons="false"
         v-show="answerLoading"
+        loadingText="内容生成中,大概需要50秒..."
       ></ChatAnswer>
 
     </TheChatView>

+ 2 - 3
src/views/analyse/WorkOrder.vue

@@ -179,10 +179,9 @@ onUnmounted(() => {
     <TheChatView ref="scrollRef" :is-footer="false">
       <ChatWelcome 
         title="您好,我是LibraAI智慧工单助手" 
-        card-title="您可以试着问我:"
         :sub-title="[
-          '基于大语言模型的智能数据分析助手,可以为您实现数据分析及数据解读',
-          '选择日期并填写关键信息为您生成日报工单'
+          '基于大语言模型的智能工单分析助手,可以为您实现数据分析及数据解读',
+          '选择日期并为您生成日报分析'
         ]"
         v-if="!chatDataSource.length"
       />

+ 1 - 1
src/views/analyse/components/CustomModal.vue

@@ -76,7 +76,7 @@ const handleStartReport = () => {
     :maskClosable="false"
   >
     <div class="modal-wrapper">
-      <p class="header mb-[16px] font-bold text-[16px] leading-[22px]">水质预测推演 - 出水硝酸盐</p>
+      <p class="header mb-[16px] font-bold text-[16px] leading-[22px]">水质预测 - 出水氨氮</p>
       <div class="content-card mb-[8px]">
         <p class="mb-[10px] font-bold text-[14px] leading-[20px]">可调参数</p>
         <ul class="inp-group grid grid-cols-2 gap-x-[24px]  gap-y-[8px]">

+ 9 - 9
src/views/analyse/components/config.js

@@ -1,15 +1,15 @@
 export const SIMULATE_ENUM = {
-  COD_in: '进水COD',
-  DO_O:         '好氧池DO (多池)',
-  MLSS:         '好氧池MLSS (多池)',
+  COD_in:       '进水COD',
+  DO_O:         '好氧池DO (#1 #2)',
+  MLSS:         'MLSS (#1 #2)',
   Q_in:         '进水流量',
   tyjyl:        '碳源药剂投加量',
-  r:            '内回流比(多池)',
+  r:            '内回流比(#1 #2)',
   cltjl:        '除磷药剂投加量',
-  gwnl:         '出泥量(千泥)',
-  hycxsy_all:   '好氧硝酸盐(多池)',
-  qyan_all:     '缺氧氨氮(多池)',
+  gwnl:         '干污泥量',
+  hycxsy_all:   '好氧硝酸盐(#1 #2)',
+  qyan_all:     '缺氧氨氮(#1 #2)',
   qyckxsy_all:  '缺氧硝酸盐',
-  T:            '好氧池水温',
-  pH:           '好氧池'
+  T:            '水温',
+  pH:           'pH'
 }

+ 1 - 1
src/views/answer/AnswerView.vue

@@ -194,7 +194,7 @@ onUnmounted(() => {
     <TheChatView ref="scrollRef">
       <ChatWelcome title="您好,我是LibraAI专家问答" card-title="您可以试着问我:"
         :sub-title="[
-          '期待与您一同规划和完成未来的工作。有任何重点或需讨论的事项,随时告诉我'
+          '期待与您一同规划和完成未来的工作。有任何重点或需讨论的事项,随时告诉我'
         ]" 
         :card-content="recommendList"
         v-if="!chatDataSource.length"

+ 4 - 4
src/views/helper/HelperView.vue

@@ -187,10 +187,10 @@ onUnmounted(() => {
 
     <TheChatView ref="scrollRef">
       <div v-if="!chatDataSource.length">
-        <ChatWelcome title="您好,我是LibraAI专家问答" card-title="您可以试着问我:"
+        <ChatWelcome title="您好,我是LibraAI专家问答"
         :sub-title="[
-          'LibarAI智能助手模块,具有强大的文本理解和生成能力,可快速响应用户需求',
-          '提供撰写文章、生成报告等服务。'
+          'LibarAI智能助手模块提供撰写文章、生成报告等服务',
+          '请替换问题中##的内容'
         ]"
         />
         <div class="grid-container">
@@ -250,7 +250,7 @@ onUnmounted(() => {
 <style scoped lang="scss">
 .grid-container{
 	position: relative;
-	height: calc(100vh - 460px);
+	// height: calc(100vh - 460px);
   padding-bottom: 20px;
   margin-top: 36px;
 	overflow: hidden;

+ 10 - 4
src/views/login/LoginView.vue

@@ -56,16 +56,17 @@ const handleSubmit = async () => {
     <main class="main flex items-center space-x-[98px]">
       <div class="text-[#07233C] pb-[90px]">
         <div class="text-title mb-[8px] text-[36px] font-bold leading-[44px]">
-          <p class="text-[#2454FF]">人工智能运营体</p>
-          <p>全国首家落地水务大模型</p>
+          <p class="text-[#2454FF]">LibraAI</p>
+          <p>首家水务领域垂直大模型</p>
         </div>
         <p class="w-[540px] text-[18px] text-justify leading-[26px]">
-          人工智能运营体(Libra水务大模型+智能装备)赋能水务行业,为用户提供全参检测、专家问答、报警决策、预测预警、智能投药、精准曝气等多项功能,通过全参数自动化验、运维工能力提升,带动水厂提效变革
+          赋能水务行业,将海量水务数据与大模型能力相融合 <br>
+          为水务行业主体提供创新应用和全面支持
         </p>
       </div>
 
       <div class="login-form w-[442px] h-[454px] bg-white rounded-[16px]">
-        <p class="title pl-[2px] mb-[30px] text-[28px] leading-[40px] font-bold">系统登</p>
+        <p class="title pl-[2px] mb-[30px] text-[28px] leading-[40px] font-bold">系统登</p>
         <div class="form-inner w-full">
           <ul class="form-inp-list">
             <li class="inp-item-inner">
@@ -112,6 +113,11 @@ const handleSubmit = async () => {
 
   .text-title {
     font-family: AlimamaShuHeiTi;
+    p:nth-child(1) {
+      background: linear-gradient(92.36deg, #5ABBF2 4.56%, #2454FF 20.02%);
+      -webkit-background-clip: text;
+      -webkit-text-fill-color: transparent;
+    }
   }
 
   .login-form {