Kaynağa Gözat

feat: 动态echart - 未完成

whh 8 ay önce
ebeveyn
işleme
048e0cd0a6

+ 30 - 1
src/utils/format.js

@@ -41,8 +41,37 @@ export const truncateDecimals = num => {
   return Number((Math.floor(num * 100) / 100).toFixed(2));
 }
 
-
 export const replaceArray = (array, startIndex, length, replacementValue) => {
   array.splice(startIndex, length, ...Array(length).fill(replacementValue));
   return array;
+}
+
+export const formatEchart = (data) => {
+
+  const customEnum = {
+    no3Hlj1Jqr: '1#好氧池硝酸盐',
+    no3Hlj2Jqr: '2#好氧池硝酸盐',
+    nh31Jqr:'1#缺氧氨氮',
+    nh32Jqr:'2#缺氧氨氮',
+    no3Qyc1Jqr:'1#缺氧池硝酸盐',
+    no3Qyc2Jqr:'2#缺氧池硝酸盐',
+    tpRccJqr:'二沉池正磷酸盐',
+  }
+  const keys = Array.from(new Set(data.flatMap(item => Object.keys(item).filter(key => key !== 'time'))));
+
+  const xAxisData = data.map(item => item.time);
+  const yAxisData = keys.map(key => ({
+    title: customEnum[key],
+    list: data.map(item => !item[key] ? 0 : Number(item[key].toFixed(2)))
+  }))
+
+  return [xAxisData, yAxisData];
+}
+
+export const colorToRgba = (color, alpha) => {
+  const r = parseInt(color.slice(1, 3), 16);
+  const g = parseInt(color.slice(3, 5), 16);
+  const b = parseInt(color.slice(5, 7), 16);
+
+  return `rgba(${r}, ${g}, ${b}, ${alpha})`
 }

+ 95 - 99
src/views/analyse/WorkOrder.vue

@@ -5,6 +5,7 @@ import { BaseButton, RecodeCardItem, TheSubMenu, TheChatView, ChatWelcome, SvgIc
 import { ChatAsk, ChatAnswer } from '@/components/Chat';
 import { orderApi } from "@/api/order";
 import { chatApi } from '@/api/chat';
+import { formatEchart } from '@/utils/format';
 import { getAreaOptions, getOrderAreaOptions } from './config/echartOptions'
 import * as echarts from 'echarts';
 import dayjs from 'dayjs';
@@ -31,7 +32,7 @@ for (let i = 0; i < 2; i++) {
 const columns = ref(arr)
 
 const tableData = ref([{ no0: 1, no1: 2 }]);
-
+const pageDataSource = ref({});
 
 let chart = null;
 let controller = new AbortController();
@@ -167,73 +168,68 @@ const onRegenerate = async ({ question, params1 }) => {
 // 提交问题
 const handleSubmit = async (question, params) => {
 
-  // if (unref(isExistInHistory)) {
-  //   const { data: sessionId } = await chatApi.getChatSessionTag();
-  //   currenSessionId.value = sessionId;
-  // }
+  if (unref(isExistInHistory)) {
+    const { data: sessionId } = await chatApi.getChatSessionTag();
+    currenSessionId.value = sessionId;
+  }
 
   isLoading.value = true;
-    let option = {}
+
+  const option = {
+    sessionId: unref(currenSessionId),
+    showVal: question,
+    answer: '',
+    loading: true,
+    delayLoading: true,
+    echartWithTableData: []
+  }
 
   const isChart = tabActive.value == 'customDaily';
 
   if (isChart) {
-    // const data = await createLineEchart(params);
-
-    function getRandomInt(min, max) {
-      min = Math.ceil(min);
-      max = Math.floor(max);
-      return Math.floor(Math.random() * (max - min + 1)) + min;
+    const { data } = await orderApi.postOrderChart(params);
+    const titleEnum = {
+      jsGroup: '进水指标',
+      csGroup: '出水指标',
+      hyGroup: '化验指标'
     }
-    const xAxisData = []
-    const seriesList = []
-
-    for (let i = 0; i < 30; i++) {
-      xAxisData.push('06-' + (i + 1));
-    }
-
-    for (let i = 0; i < 2; i++) {
-      seriesList[i] = [];
-      for (let j = 0; j < 30; j++) {
-        seriesList[i].push(getRandomInt(1, 6))
+    const reuslt = Object.entries(data).map(([key, value]) => {
+      if ( value.length ) {
+        const [ xAxisData, yAxisData ] = formatEchart(value);
+        return {
+          id: key,
+          title: titleEnum[key],
+          xAxisData,
+          yAxisData
+        }
       }
-    }
-
-     option = getOrderAreaOptions({
-      xAxisData,
-      seriesList
-    });
+    }).filter(Boolean);
 
+    option.echartWithTableData = reuslt;
   }
 
-  addChat({
-    sessionId: unref(currenSessionId),
-    showVal: question,
-    answer: '',
-    loading: true,
-    delayLoading: true,
-    isChart: true
-  })
-
-  console.log( chatDataSource.value );
+  addChat(option);
 
   scrollToBottom();
 
   setTimeout(() => {
-    updateChat({
-      sessionId: unref(currenSessionId),
-      showVal: question,
-      answer: '',
-      loading: true,
-      delayLoading: false,
-      isChart: true
+
+    option.echartWithTableData.forEach(({ id, xAxisData, yAxisData }) => {
+      const dom = document.getElementById(id);
+      const chart = echarts.init(dom, null, { width: 680, height: 300 });
+      const option = getOrderAreaOptions({ xAxisData, yAxisData });
+      chart.setOption(option);
+      updateChat({
+        ...chatDataSource.value[0],
+        delayLoading: false
+      })
     })
-    if(!chart) {
-      const dom = document.getElementById('chartContainer')
-      console.log( echartRef.value );
-      chart = echarts.init(dom, {width: 680, height: 300});
-    }
-    chart.setOption(option);
+
+    // if(!chart) {
+    //   const dom = document.getElementById('chartContainer')
+    //   chart = echarts.init(dom, null, { width: 680, height: 300 });
+    // }
+    
     // chart.resize();
     // onRegenerate({ question }), 2 * 1000
   }, 2 * 1000);
@@ -241,36 +237,37 @@ const handleSubmit = async (question, params) => {
 
 // 处理推荐问题
 const handleCreateOrder = async () => {
-  // const { timeBegin, timeEnd, whichWay, checkGroup } = unref(workOrderParams);
-  // const startDateTime = dayjs(timeBegin);
-  // const endDateTime = dayjs(timeEnd);
-  // const params = {
-  //   timeBegin,
-  //   timeEnd,
-  //   whichWay
-  // };
+  const { timeBegin, timeEnd, whichWay, checkGroup } = unref(workOrderParams);
+  const startDateTime = dayjs(timeBegin);
+  const endDateTime = dayjs(timeEnd);
+  const params = {
+    timeBegin,
+    timeEnd,
+    whichWay
+  };
 
   let question = `请生成${reportDate.value}智慧工单分析报告`;
 
   if (tabActive.value === 'customDaily') {
-    //   const thirtyDaysBeforeEndTime = endDateTime.subtract(30, 'day');
-    //   const isStartAfterThirtyDaysBeforeEnd = startDateTime.isSameOrAfter(thirtyDaysBeforeEndTime);
+    const thirtyDaysBeforeEndTime = endDateTime.subtract(31, 'day');
+    const isStartAfterThirtyDaysBeforeEnd = startDateTime.isAfter(thirtyDaysBeforeEndTime);
+
+    if (!timeBegin) return message.warning('请选择开始日期');
+    if (!timeEnd) return message.warning('请选择结束日期');
+    if (!isStartAfterThirtyDaysBeforeEnd) return message.warning('只可生成一个月区间的工单报告');
+    if (!checkGroup.length) return message.warning('请至少选择一项指标项');
 
-    //   if (!timeBegin) return message.warning('请选择开始日期');
-    //   if (!timeEnd) return message.warning('请选择结束日期');
-    //   if (!isStartAfterThirtyDaysBeforeEnd) return message.warning('只可生成一个月区间的工单报告');
-    //   if (!checkGroup.length) return message.warning('请至少选择一项指标项');
+    checkGroup.forEach(key => params[key] = true);
 
-    //   checkGroup.forEach(key => params[key] = true);
-    //   // [checkGroup, csCheckGroup, hyCheckGroup].flat().forEach(key => params[key] = true);
+    question = `请成生${startDateTime.format("MM月DD日")}-${endDateTime.format("MM月DD日")}的在线仪表的日报工单`
 
-    //   question = `请成生${startDateTime.format("MM月DD日")}-${endDateTime.format("MM月DD日")}的在线仪表的日报工单`
+  } else {
+
+    if (!reportDate.value) return message.warning('请选择时间');
 
-    // } else {
-    //   if (!reportDate.value) return message.warning('请选择时间');
   }
-  handleSubmit(question)
-  // handleSubmit(question, params);
+
+  handleSubmit(question, params)
 }
 
 // 创建echart
@@ -308,6 +305,12 @@ const dateEndDisabled = (timestamp) => {
   }
 }
 
+onMounted(() => {
+  // const dom = document.getElementById('chartContainer')
+  //   console.log( echartRef.value );
+  //   chart = echarts.init(dom);
+})
+
 onUnmounted(() => {
   controller.abort();
 })
@@ -337,11 +340,15 @@ onUnmounted(() => {
       '基于大语言模型的智能工单分析助手,可以为您实现数据分析及数据解读',
       '选择日期并为您生成日报分析'
     ]" v-if="!chatDataSource.length" />
-  
+    <!-- :loading="item.loading" :delay-loading="item.delayLoading" -->
+        <!-- <ChatAnswer content="11111111111"> -->
+      <!-- v-show="item.isChart && !item.delayLoading" -->
+          
+        <!-- </ChatAnswer> -->
 
 
       <div class="conversation-item" v-show="chatDataSource.length">
-        <div v-for="item in chatDataSource" :key="item.id">
+        <div v-for="item in chatDataSource" :key="item.sessionId">
           <ChatAsk :content="item.showVal" :sessionId="item.sessionId"></ChatAsk>
           <ChatAnswer
             :id="item.id"
@@ -350,29 +357,18 @@ onUnmounted(() => {
             :delay-loading="item.delayLoading"
             :isSatisfied="item.isSatisfied"
             @on-click-icon="params => updateById(params)"
-            v-if="!item.isChart"
-          ></ChatAnswer>
-          <ChatAnswer content="11111111111" :loading="item.loading" :delay-loading="item.delayLoading" >
-            <div v-show="item.isChart && !item.delayLoading">
-            <div class="echart-warpper" >
-              <span class="#1A2029 font-bold">进水指标</span>
-
-              <!-- <ul class="flex justify-end w-[600px] text-center text-[12px] text-[#666] leading-[18px] space-x-[10px]">
-            <li class="">
-              <span class="inline-block w-[10px] h-[2px] mb-[2px] mr-[4px] bg-[#2185da]"></span>
-              <span>过去</span>
-            </li>
-            <li class="">
-              <span class="inline-block w-[10px] h-[2px] mb-[2px] mr-[4px] bg-[#2ee055]"></span>
-              <span>未来</span>
-            </li>
-          </ul> -->
-              <div id="chartContainer" class="w-[680px] h-[300px]" ref="echartRef" style="width: 680px; height: 300px;"></div>
-            </div>
-            <div class="w-[700px]">
-              <NDataTable :bordered="true" :single-line="false" single-column :columns="columns" :data="tableData"
-                scroll="{ x: true }" size="small"></NDataTable>
-            </div>
+          >
+            <div v-show="!item.delayLoading">
+              <div v-for="(item, index) in item.echartWithTableData" :key="index">
+                <div class="echart-warpper" >
+                  <span class="mb-[10px] #1A2029 font-bold">{{ item.title }}</span>
+                  <div :id="item.id" class="w-[680px] h-[300px]" style="width: 680px; height: 300px;"></div>
+                </div>
+                <div class="w-[700px]">
+                  <NDataTable :bordered="true" :single-line="false" single-column :columns="columns" :data="tableData"
+                    scroll="{ x: true }" size="small"></NDataTable>
+                </div>
+              </div>
             </div>
           </ChatAnswer>
         </div>
@@ -547,7 +543,7 @@ onUnmounted(() => {
   justify-content: center;
   flex-flow: column;
   width: 100%;
-  padding: 20px 0 30px 0;
+  padding: 20px 0;
   border-radius: 8px;
 }
 </style>

+ 44 - 23
src/views/analyse/config/echartOptions.js

@@ -1,4 +1,5 @@
 import * as echarts from 'echarts';
+import { colorToRgba } from '@/utils/format';
 
 export const getAreaOptions = ({ xAxisData, seriesList }) => {
   const series = seriesList.map((data, index) => {
@@ -140,7 +141,8 @@ export const getAreaOptions = ({ xAxisData, seriesList }) => {
   }
 }
 
-export const getOrderAreaOptions = ({ xAxisData, seriesList }) => {
+export const getOrderAreaOptions = ({ xAxisData, yAxisData }) => {
+  console.log("xAxisData", xAxisData);
 
   const color = [
     '#0FFEFF',
@@ -149,31 +151,53 @@ export const getOrderAreaOptions = ({ xAxisData, seriesList }) => {
     '#3D80FF',
     '#D35AE8',
     '#EC2E72',
-    '#FF5406',
-    '#3D3AEE',
-    '#008F07',
-    '#FF8B8B',
+    '#8B4513',
   ];
 
   const series = [];
 
-  seriesList.map((item, index) => {
+  yAxisData.map((item, index) => {
+    const itemColor = color[index];
     series.push({
-      name: index == 0 ? "COD" : "FOB",
+      name: item.title,
       type: 'line',
+      symbol: 'circle',
+      showAllSymbol: true,
       smooth: true,
-      showSymbol: false,
-      yAxisIndex: 0,
+      symbolSize: 5,
+      lineStyle: {
+        normal: {
+          width: 2,
+          color: itemColor
+        },
+        borderColor: 'rgba(0,0,0,.4)',
+      },
       itemStyle: {
-        opacity: 0.8,
-        color: color[index],
+        color: itemColor,
+        borderColor: itemColor,
+        borderWidth: 3,
       },
+      // areaStyle: {
+      //   normal: {
+      //     color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
+      //       offset: 0,
+      //       color: colorToRgba(itemColor, 0.3) 
+      //     },
+      //     {
+      //       offset: 1,
+      //       color: colorToRgba(itemColor, 0) 
+      //     }
+      //     ], false),
+      //     shadowColor: 'rgba(25,163,223, 0.5)',
+      //     shadowBlur: 20
+      //   }
+      // },
       tooltip: {
         valueFormatter: function (value) {
-          return value + '元';
+          return value + 'mg/L';
         },
       },
-      data: item,
+      data: item.list,
     });
   });
 
@@ -202,10 +226,9 @@ export const getOrderAreaOptions = ({ xAxisData, seriesList }) => {
     },
     backgroundColor: '#fff',
     grid: {
-
       top: 30,
-      left: 30,
-      right: 10,
+      left: 40,
+      right: 40,
       bottom: 30,
       // x: 40,
       // y: 10,
@@ -215,6 +238,7 @@ export const getOrderAreaOptions = ({ xAxisData, seriesList }) => {
     },
     legend: {
       orient: 'horizontal',
+      fontSize: '20px',
       icon: 'rect',
       itemWidth: 10,
       itemHeight: 2,
@@ -224,21 +248,19 @@ export const getOrderAreaOptions = ({ xAxisData, seriesList }) => {
           a: {
             width: 20,
             color: '#666',
-            fontSize: 12,
+            fontSize: 10,
             lineHeight: 18,
           },
         },
       },
       right: '4',
-          top: '0',
+      top: '0',
     },
     xAxis: [{
       type: "category",
       axisLabel: {
         color: "#666",
         fontSize: 12,
-         
-        // interval: 6,
       },
       axisLine: {
         show: true,
@@ -247,7 +269,8 @@ export const getOrderAreaOptions = ({ xAxisData, seriesList }) => {
         },
       },
       splitLine: {
-        show: false,
+        show: true,
+        interval: '0',
         lineStyle: {
           type: 'dashed',
         },
@@ -257,8 +280,6 @@ export const getOrderAreaOptions = ({ xAxisData, seriesList }) => {
       },
       boundaryGap: false,
       data: xAxisData
-
-
     }],
     yAxis: [{
       name: '',