ForecastView.vue 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. <script setup>
  2. import { onMounted, ref } from 'vue';
  3. import { useRouter } from 'vue-router';
  4. import { NTabs, NTab } from 'naive-ui';
  5. // import * as G2Plot from '@antv/g2plot';
  6. import * as echarts from 'echarts';
  7. import { getAreaOptions, areaOptions } from '@/utils/echartOptions'
  8. // import { Area } from '@antv/g2plot';
  9. import { useChatStore } from '@/stores/modules/chatStore';
  10. import { BaseTable, ChatWelcome, RecodeSquareCardItem, TheSubMenu, TheChatView } from "@/components";
  11. import { ChatBaseCard, ChatAnswer } from '@/components/Chat';
  12. import { formatToData, replaceArray } from "@/utils/format";
  13. import { waterApi } from '@/api/water';
  14. import { useInfinite, useRecommend, useScroll } from '@/composables'
  15. import { columns } from './config';
  16. const { recommendList } = useRecommend({ type: 3 });
  17. const { scrollRef, scrollToTop } = useScroll();
  18. const { recordList, isFetching, onScrolltolower, onRestore } = useInfinite('/front/bigModel/warning/pageList', { type: 2, warningStatus: 0 });
  19. const router = useRouter();
  20. const chatStore = useChatStore();
  21. const answerResult = ref("");
  22. const textDataSources = ref(null);
  23. const chartTitle = ref("");
  24. let chart = {};
  25. const echartRef = ref({});
  26. // 进出水数据
  27. const jsTableData = ref([]);
  28. const csTableData = ref([]);
  29. // 切换Tabs
  30. const onChangeTabs = warningStatus => {
  31. answerResult.value = '';
  32. textDataSources.value = '';
  33. onRestore({ warningStatus })
  34. }
  35. // 打开详情
  36. const handleOpenContent = async ({ id, reason: title }) => {
  37. const { data } = await waterApi.getWaringDetails(id);
  38. const showVal = JSON.parse(data.showVal);
  39. const { basic, jsData, csData, chartsData, chartsTitle } = showVal;
  40. answerResult.value = data.answer;
  41. chartTitle.value = chartsTitle;
  42. basic.title = title
  43. textDataSources.value = formatToData(basic, '预测值');
  44. jsTableData.value = [jsData];
  45. csTableData.value = [csData];
  46. createLineChat(chartsData);
  47. scrollToTop();
  48. }
  49. // 创建图表
  50. const createLineChat = (data) => {
  51. const [xAxisData, yData] = data.reduce((acc, { time, val }) => {
  52. acc[0].push(time);
  53. acc[1].push(val);
  54. return acc;
  55. }, [[], []]);
  56. const seriesPast = replaceArray([...yData], yData.length - 3, 3, null);
  57. const seriesFuture = replaceArray([...yData], 0, 5, null);
  58. const option = getAreaOptions({xAxisData, seriesList: [seriesPast, seriesFuture]});
  59. chart.setOption(option);
  60. }
  61. // 欢迎 - 问答
  62. const handleWelcomeRecommend = question => {
  63. chatStore.setChatQuestion(question);
  64. router.push('/answer');
  65. }
  66. onMounted(() => {
  67. chart = echarts.init(echartRef.value, 'light');
  68. })
  69. </script>
  70. <template>
  71. <section class="flex items-start h-full" id="warning">
  72. <TheSubMenu title="预测预警" @scrollToLower="onScrolltolower" :loading="isFetching">
  73. <template #top>
  74. <div class="border-[#DAE5ED]">
  75. <n-tabs type="line" justify-content="space-evenly">
  76. <n-tab name="oasis" tab="正在预警" @click="onChangeTabs(0)"></n-tab>
  77. <n-tab name="thebeatles" tab="历史预警" @click="onChangeTabs(1)"></n-tab>
  78. </n-tabs>
  79. </div>
  80. </template>
  81. <div class="px-[12px] py-[14px] text-[#5e5e5e]">
  82. <div class="grid grid-cols-1 gap-[12px]">
  83. <RecodeSquareCardItem v-for="item in recordList" :key="item.id" :item="item" @on-click="handleOpenContent" />
  84. </div>
  85. </div>
  86. </TheSubMenu>
  87. <TheChatView ref="scrollRef" :is-footer="false">
  88. <ChatWelcome title="您好,我是LibraAI工艺管控助手" card-title="常见处理方案:" :sub-title="[
  89. '报警分析功能具备实时监测与预警机制,检测到异常情况推送相关工作人员确保问题及时处理',
  90. '报警时间为每小时警报,请大家及时处理'
  91. ]" v-if="!textDataSources" :card-content="recommendList" @on-click="handleWelcomeRecommend" />
  92. <ChatBaseCard v-show="textDataSources">
  93. <div class="waring-answer-wrapper">
  94. <dl class="message-inner warning-info_medium ">
  95. <dt class="mb-[2px] font-bold text-[#1A2029]">{{ textDataSources?.title }}</dt>
  96. <dd v-for="item, index in textDataSources?.list" :key="index"><span
  97. :class="{ 'text-[#F44C49]': item.isWarning }">{{ item.label }}: {{ item.value }}</span></dd>
  98. </dl>
  99. <div class="table-inner">
  100. <div class="warning-table mb-[8px]">
  101. <div class="title">
  102. <span>当前进水数据:</span>
  103. </div>
  104. <div class="main">
  105. <BaseTable :columns="columns" :data="jsTableData"></BaseTable>
  106. </div>
  107. </div>
  108. <div class="warning-table">
  109. <div class="title">
  110. <span>当前出水数据:</span>
  111. </div>
  112. <div class="main">
  113. <BaseTable :columns="columns" :data="csTableData"></BaseTable>
  114. </div>
  115. </div>
  116. </div>
  117. </div>
  118. <div class="echart-warpper">
  119. <span>{{ chartTitle }}</span>
  120. <div id="chartContainer" class="w-[600px] h-[200px]" ref="echartRef"></div>
  121. <ul class="flex justify-between w-[600px] text-center text-[12px] text-[#666] leading-[18px]">
  122. <li class="w-[370px] pl-[40px]">
  123. <span class="inline-block w-[10px] h-[2px] mb-[2px] mr-[4px] bg-[#2185da]"></span>
  124. <span>过去</span>
  125. </li>
  126. <li class="flex-1 pr-[30px]">
  127. <span class="inline-block w-[10px] h-[2px] mb-[2px] mr-[4px] bg-[#2ee055]"></span>
  128. <span>未来</span>
  129. </li>
  130. </ul>
  131. </div>
  132. </ChatBaseCard>
  133. <ChatAnswer :loading="false" :delay-loading="false" :toggleVisibleIcons="false" :content="answerResult"
  134. v-if="answerResult" />
  135. </TheChatView>
  136. </section>
  137. </template>
  138. <style lang="scss" scoped>
  139. .echart-warpper {
  140. display: flex;
  141. align-items: center;
  142. justify-content: center;
  143. flex-flow: column;
  144. width: 100%;
  145. padding: 50px 0 30px 0;
  146. border-radius: 8px;
  147. // background: #eee;
  148. // border: 1px solid #ccc;
  149. }
  150. </style>