Jelajahi Sumber

fix: 优化和修改

zhangwenya 1 tahun lalu
induk
melakukan
ca89cd426c

+ 5 - 0
src/api/risk/r2.js

@@ -31,3 +31,8 @@ export const analysisTypeTrend = id => request({
     url: '/risk/analysis/type3/trend/' + id,
     method: 'get',
 })
+
+export const analysisTypeResult = resultId => request({
+    url: '/risk/analysis/type3/result/' + resultId,
+    method: 'get',
+})

+ 7 - 0
src/api/risk/r5.js

@@ -49,3 +49,10 @@ export function listNetwork(modelId,metricsId){
         method: 'get',
     })
 }
+
+export function listHostTrend(id){
+    return request({
+        url: '/risk/other/host/trend/'+id,
+        method: 'get',
+    })
+}

+ 23 - 12
src/views/index/css/style.scss

@@ -172,41 +172,52 @@
     min-width: 550px;
     max-width: 660px;
     margin: 0 10px;
-    background-image: url("@/assets/images/center-bg.png");
-    background-repeat: no-repeat;
-    background-position: center center;
-    //background-size: 70%;
-    background-size: 550px;
+    z-index:1;
+    &::before {
+      content: '';
+      position: absolute;
+      top: 0;
+      left: 0;
+      right: 0;
+      bottom: 0;
+      background-image: url("@/assets/images/center-bg.png");
+      background-repeat: no-repeat;
+      background-position: center center;
+      //background-size: 70%;
+      background-size: 550px;
+      opacity: 0.8; /* 设置背景透明度 */
+      z-index: -1; /* 确保在文本下方 */
+    }
     .h-img {
-      width: 120px;
+      width: 130px;
     }
 
     .a-h-item {
       position: absolute;
       top: 29%;
-      left: -4%;
+      left: -8%;
       text-align: center;
       cursor: pointer;
     }
 
     .item-cq {
       top: 63%;
-      left: 27%;
+      left: 17%;
     }
 
     .item-js {
-      top: 5%;
+      top: 4%;
       left: 50%;
-      margin-left: -60px;
+      margin-left: -65px;
     }
 
     .item-hg {
       top: 63%;
-      left: 57%;
+      left: 62%;
     }
 
     .item-fb {
-      left: calc(90% - 40px);
+      left: calc(92% - 40px);
     }
 
     .item-jcd {

+ 1 - 1
src/views/index/widget/alarmRanking.vue

@@ -14,7 +14,7 @@
           </span>
           {{item.name}}
         </div>
-        <span class="alarm-num">{{item.alarm}}</span>
+        <span class="alarm-num">{{item.num}}</span>
       </div>
       <div class="alarm-progress">
         <div class="progress" :style="`width:${(item.alarm/maxValue)*100}%`" />

+ 2 - 2
src/views/index/widget/runResult.vue

@@ -1,10 +1,10 @@
 <template>
     <div class="column-row">
       <div class="column-row-title">
-        <span class="title-text"><img src="@/assets/images/title-icon.png" alt=""/>运行风险预测结果
+        <span class="title-text"><img src="@/assets/images/title-icon.png" alt=""/>异常分析及预测
           <span class="s-span">(截止前一天)</span>
         </span>
-        <div><el-checkbox v-model="risk" label="只看风险" size="large" @change="getRisk"/><span class="yellow-txt">{{riskNum}}</span></div>
+        <div>风险<span class="yellow-txt">{{riskNum}}</span></div>
       </div>
       <div class="column-content">
         <div class="c-row" v-for="item in riskData">

+ 1 - 1
src/views/risk/r2/components/historyRisk.vue

@@ -21,7 +21,7 @@
   />
 
   <el-dialog :title="'分析详情'" v-model="visible" width="800" append-to-body>
-    <risk-detail :rows="detailRow" v-if="visible" />
+    <risk-detail :rows="detailRow" v-if="visible" :history="true"/>
   </el-dialog>
 </template>
 <script setup lang="ts">

+ 12 - 4
src/views/risk/r2/components/riskDetail.vue

@@ -9,7 +9,6 @@
           </span>
           <div class="progress-row">
             {{ item.name }}
-            {{ maxNum }}
             <div class="progress-bg">
               <div class="progress-bar"
                    :style="`width:${item.num/maxNum*100}%;background:${colors[index]||'#A1B3D2'}`"/>
@@ -30,13 +29,22 @@
 </template>
 <script setup lang="ts">
 import {parseTime} from "@/utils/ruoyi"
-import {analysisAtOnce,analysisTypeTrend} from "@/api/risk/r2"
+import {analysisAtOnce,analysisTypeTrend,analysisTypeResult} from "@/api/risk/r2"
 import {watchEffect} from "vue";
 import * as echarts from "echarts";
 
 const chartTop = ref(null)
 const maxNum = ref(0)
-const props = defineProps(['rows'])
+const props = defineProps({
+  rows: {
+    type:Object,
+    default:()=>{}
+  },
+  history: {
+    type:Boolean,
+    default:false
+  }
+})
 const analysisData = ref({})
 const colors = ['#f56c6c', '#e6a23c', '#409EFF']
 const activeTop = ref(null)
@@ -45,7 +53,7 @@ watchEffect(() => {
 })
 
 async function getAnalysisData() {
-  const res = await analysisAtOnce(props.rows.riskId)
+  const res = props.history ? await analysisTypeResult(props.rows.resultId) : await analysisAtOnce(props.rows.riskId)
   analysisData.value = res.data
   maxNum.value = Math.max(...analysisData.value.top.map(item => item.num)) + 20
 }

+ 1 - 6
src/views/risk/r3/components/historyAnalyse.vue

@@ -11,12 +11,7 @@
     <el-table-column label="指标名称" prop="metricsName"/>
     <el-table-column label="运行业务对象" prop="objName"/>
     <el-table-column label="分析时间" prop="analyseTime"/>
-    <el-table-column label="分析结果">
-      <template #default="scope">
-        <el-tag v-if="scope.row.result=='趋势恶化'" type="danger">{{scope.row.result}}</el-tag>
-        <el-tag v-else >{{scope.row.result}}</el-tag>
-      </template>
-    </el-table-column>
+    <el-table-column label="分析结果" prop="result" />
     <el-table-column label="操作" width="100">
       <template #default="scope">
         <el-button type="primary" link @click="checkAnalyse(scope.row)">查看</el-button>

+ 31 - 38
src/views/risk/r3/components/nowAnalyse.vue

@@ -5,38 +5,30 @@
         <el-form-item label="数据有效性">
           <el-row :gutter="20">
             <el-col :span="24">
-              <el-tag effect="light" :type="rows.normalValid === '通过'?'success':'info'">正态检测: {{
-                  rows.normalValid
-                }}
-              </el-tag>
+              正态检测: {{  rows.normalValid }}
             </el-col>
             <el-col :span="24">
-              <el-tag effect="light" :type="rows.varianceValid === '通过'?'success':'info'">方差齐性检测:
-                {{ rows.varianceValid }}
-              </el-tag>
+              方差齐性检测: {{ rows.varianceValid }}
             </el-col>
           </el-row>
         </el-form-item>
         <el-form-item label="结果">
-          <el-tag v-if="rows.result=='趋势恶化'" type="danger">{{ rows.result }}</el-tag>
-          <el-tag v-else>{{ rows.result }}</el-tag>
+          {{ rows.result }}
         </el-form-item>
         <el-form-item label="置信区间">
           {{ rows.confidenceLevel }}
         </el-form-item>
-        <el-form-item label="p值">
-          {{ rows.pvalue }}
-        </el-form-item>
       </el-form>
-      <div>
+      <div style="margin-left:10px;width: 400px">
         <div class="top-title">均值比较</div>
-        <div ref="chartTop" style="height: 200px;width: 400px"/>
+        {{rows.avgValue}}
+<!--        -->
       </div>
     </div>
   </div>
   <div class="chart-row">
     <div class="top-title">2周数据图</div>
-    <el-image style="width: 300px" :src="rows.imgPath" fit="scale-down"/>
+    <div ref="chartTop" style="height: 200px;width: 760px"/>
   </div>
 </template>
 <script setup lang="ts">
@@ -46,35 +38,33 @@ import * as echarts from "echarts";
 const chartTop = ref(null)
 const props = defineProps(['rows'])
 onMounted(()=>{
-  initChart(props.rows)
+  if(props.rows.input){
+    const data = JSON.parse(props.rows.input)
+    initChart(data)
+  }
+
 })
 
 async function initChart(item) {
   const myChart = echarts.init(chartTop.value);
   const option = {
     tooltip: {
-      trigger: 'axis'
+      trigger: 'axis',
     },
     grid: {
       left: '0%',
       right: '0%',
       bottom: '3%',
-      top: '5%',
+      top: '15%',
       containLabel: true
     },
+    legend: {
+      data: ['上周', '本周']
+    },
     xAxis: {
       type: 'category',
-      data: ['本周', '上周'],
-      axisLine: {
-        show: true,
-        lineStyle: {
-          color: "#9FB9E7",
-          width: 0,
-        }
-      },
-      axisTick: {
-        show: false,
-      },
+      show:false,
+      data:item.sort
     },
     yAxis: {
       type: 'value',
@@ -92,16 +82,19 @@ async function initChart(item) {
         }
       },
     },
-    series: {
-      type: 'bar',
-      data: item.avgValue ? item.avgValue.split(",") : [],
-      barMaxWidth: 25,
-      itemStyle: {
-        normal: {
-          barBorderRadius:[10, 10 , 0, 0]
-        }
+    series: [
+      {
+        type: 'line',
+        name:"上周",
+        data: item.last,
+        itemStyle: { opacity: 0 },
+      },{
+        type: 'line',
+        name:"本周",
+        itemStyle: { opacity: 0 },
+        data: item.curr,
       }
-    }
+    ]
   };
   myChart.setOption(option)
 }

+ 3 - 0
src/views/risk/r3/css/style.scss

@@ -19,5 +19,8 @@
     margin-right:10px;
     font-size: 12px;
   }
+  .chart-row{
+    width: 100%;
+  }
 }
 

+ 39 - 24
src/views/risk/r5/components/alarmsTop.vue

@@ -1,47 +1,62 @@
 <template>
-  <div class="top-title">{{title}}</div>
-  <div class="sub-tip">
-    <span class="tip-alarm"/>告警次数
-    <span class="tip-title"/>持续时间
-  </div>
-  <div v-for="(item,index) in data" :key="index" class="top-style">
-      <span class="index" :style="`background:${colors[index]||'#A1B3D2'}`">
+
+  <div class="top-content">
+    <div class="top-ranking">
+      <div class="sub-tip">
+        <span class="tip-alarm"/>告警次数
+        <span class="tip-title"/>持续时间
+      </div>
+      <div v-for="(item,index) in data" :key="index" :class="['top-style',{'active-bg':alarmId === item.id}]" @click="clickRanking(item)">
+      <span class="index" style="background:#409EFF">
         {{ index + 1 }}
       </span>
-    <div class="progress-row">
-      {{ item.objName }}
-      <div class="row-flex">
-        <div class="progress-alarm">
-          <div class="alarms" :style="`width:${item.alarms/maxAlarms*100}%`">{{item.alarms}}</div>
-        </div>
-        <div class="progress-alarm">
-          <div class="time" :style="`width:${item.value/maxNum*100}%`">{{item.value}}</div>
+        <div class="progress-row">
+          {{ item.objName }}
+          <div class="row-flex">
+            <div class="progress-alarm">
+              <div class="alarms" :style="`width:${item.alarms/maxAlarms*100}%`">{{ item.alarms }}</div>
+            </div>
+            <div class="progress-alarm">
+              <div class="time" :style="`width:${item.value/maxNum*100}%`">{{ item.value }}</div>
+            </div>
+          </div>
         </div>
       </div>
     </div>
+    <chart ref="cRef"/>
   </div>
+
 </template>
 <script setup lang="ts">
+import chart from "./chart.vue"
+const cRef = ref(null)
+const {proxy} = getCurrentInstance()
 const props = defineProps({
   data: {
     type: Array,
     default: () => []
   },
-  title:{
-    type: String,
-    default: ''
-  },
-  colors:{
-    type: Array,
-    default: () => []
+  alarmId:{
+    type:Number,
+    default:null
   }
 })
 const maxNum = computed(() => {
-  return Math.max(...props.data.map(item => item.value))+10
+  return Math.max(...props.data.map(item => item.value)) + 10
 })
 const maxAlarms = computed(() => {
-  return Math.max(...props.data.map(item => item.alarms))+10
+  return Math.max(...props.data.map(item => item.alarms)) + 10
 })
+
+function clickRanking(item){
+  proxy.$emit('clickRanking', item.id,"alarm")
+}
+function initChart(data){
+  cRef.value.initChart(data)
+}
+
+defineExpose({initChart})
+
 </script>
 <style scoped lang="scss">
 </style>

+ 60 - 0
src/views/risk/r5/components/chart.vue

@@ -0,0 +1,60 @@
+<template>
+  <div ref="chartTop" style="height: 300px;width: 50%"/>
+</template>
+<script setup lang="ts">
+import * as echarts from "echarts"
+const chartTop = ref(null)
+function initChart(data){
+  const myChart = echarts.init(chartTop.value)
+  const option = {
+    grid: {
+      left: '1%',
+      right: '1%',
+      bottom: '1%',
+      top: '5%',
+      containLabel: true
+    },
+    xAxis: {
+      type: 'category',
+      boundaryGap: false,
+      data:data.time,
+      axisLine: {
+        show: true,
+        lineStyle: {
+          color: "#849ac4",
+          width: 0,
+        }
+      },
+      axisTick: {
+        show: false,
+      },
+    },
+    yAxis: {
+      type: 'value',
+      axisLine: {
+        show: true,
+        lineStyle: {
+          color: "#849ac4",
+          width: 0,
+        }
+      },
+      splitLine: {
+        lineStyle: {
+          color: "#849ac480",
+          type: 'dashed',
+        }
+      },
+    },
+    series: [
+      {
+        data: data.data,
+        type: 'line',
+        areaStyle: {}
+      }
+    ]
+  };
+  myChart.setOption(option)
+}
+
+defineExpose({initChart})
+</script>

+ 32 - 19
src/views/risk/r5/components/cpuTop.vue

@@ -1,35 +1,48 @@
 <template>
-    <div class="top-title">{{title}}</div>
-    <div v-for="(item,index) in data" :key="index" class="top-style">
-      <span class="index" :style="`background:${colors[index]||'#A1B3D2'}`">
-        {{ index + 1 }}
-      </span>
-      <div class="progress-row">
-        {{ item.objName }}
-        <div class="progress-bg">
-          <div class="progress-bar"
-               :style="`width:${item.value/maxNum*100}%;background:${colors[index]||'#A1B3D2'}`"/>
-          {{ item.value }}
+  <div class="top-content">
+    <div class="top-ranking mt5">
+      <div v-for="(item,index) in data" :key="index" :class="['top-style',{'active-bg':currentId === item.id}]" @click="clickRanking(item)">
+        <span class="index" style="background:#409EFF">
+          {{ index + 1 }}
+        </span>
+        <div class="progress-row">
+          {{ item.objName }}
+          <div class="progress-bg">
+            <div class="progress-bar" :style="`width:${item.value/maxNum*100}%;background:#409EFF80}`"/>
+            {{ item.value }}
+          </div>
         </div>
       </div>
     </div>
+    <chart ref="cRef"/>
+  </div>
 </template>
 <script setup lang="ts">
+import chart from "./chart.vue"
+const cRef = ref(null)
+const {proxy} = getCurrentInstance()
+
 const props = defineProps({
   data: {
     type: Array,
     default: () => []
   },
-  title:{
-    type: String,
-    default: ''
-  },
-  colors:{
-    type: Array,
-    default: () => []
+  currentId:{
+    type:Number,
+    default:null
   }
 })
 const maxNum = computed(() => {
-  return Math.max(...props.data.map(item => item.value))+10
+  return Math.max(...props.data.map(item => item.value)) + 10
 })
+
+function clickRanking(item){
+  proxy.$emit('clickRanking', item.id,"current")
+}
+function initChart(data){
+  cRef.value.initChart(data)
+}
+
+defineExpose({initChart})
+
 </script>

+ 28 - 3
src/views/risk/r5/css/style.scss

@@ -58,10 +58,22 @@
         font-weight: bolder;
       }
     }
+    .tab-bar-row{
+      @include flexStart;
+      border-bottom:1px solid #99a9bf40;
+      width: 100%;
+      padding-bottom:10px;
+      .row-title{
+        color: #657385;
+        font-size: 14px;
+        margin:0 5px;
+      }
+    }
   }
   .sub-tip{
     text-align: center;
     font-size: 12px;
+    margin-top:10px;
     color:#888;
     @include flexCenter;
     .tip-alarm{
@@ -77,9 +89,18 @@
       background: #e6a23c;
     }
   }
-
+  .top-content{
+    @include flexBetween;
+    width: 100%;
+    .top-ranking{
+      width: 45%;
+    }
+  }
+  .mt30{
+    margin-top: 30px;
+  }
   .top-style{
-    margin:10px 0;
+    padding:5px;
     @include flexStart();
     cursor: pointer;
     &:last-child{
@@ -111,7 +132,7 @@
         .progress-bar{
           height:12px;
           border-radius: 6px;
-          background: #A1B3D2;
+          background: #409EFF;
           margin-right:5px;
           transition: all .3s;
         }
@@ -138,6 +159,10 @@
       }
     }
   }
+  .active-bg{
+    background-image: linear-gradient(to right,#409EFF19, rgba(64, 158, 255, 0.1));
+    border-radius: 4px;
+  }
 
   .r7-row{
     border:1px solid #F1F1F1;

+ 68 - 6
src/views/risk/r5/index.vue

@@ -6,10 +6,26 @@
     <el-tabs v-model="activeName" class="demo-tabs" @tab-click="handleClick" type="border-card" v-if="modelData.length">
       <el-tab-pane :label="item.modelName" :name="item.modelName" v-for="item in modelData" :key="item.modelId"/>
       <div class="tab-content">
-        <div v-for="(item,index) in hostData" :key="index" class="t-c-row">
-          <cpu-top  v-if="item.data[0].alarms === undefined" :data="item.data" :title="item.title" :colors="colors" />
-          <alarms-top v-if="item.data[0].alarms" :data="item.data" :title="item.title" :colors="colors" />
+        <div class="tab-bar-row">
+          <el-icon color="#99a9bf" size="14">
+            <ArrowRightBold/>
+          </el-icon>
+          <span class="row-title">按前当值排序</span>
+          <el-select v-model="currentTitle" size="small" style="width: 200px;" @change="changeCurrent">
+            <el-option v-for="item in currentData" :key="item.title" :label="item.title" :value="item.title"/>
+          </el-select>
         </div>
+        <cpu-top :data="currentRow.data" ref="ctRef" v-if="currentRow.data" @clickRanking="getHostTrend" :currentId="currentId"/>
+        <div class="tab-bar-row mt30">
+          <el-icon color="#99a9bf" size="14">
+            <ArrowRightBold/>
+          </el-icon>
+          <span class="row-title">按警告次数排序</span>
+          <el-select v-model="alarmTitle" size="small" style="width: 200px;" @change="changeAlarm">
+            <el-option v-for="item in alarmData" :key="item.title" :label="item.title" :value="item.title"/>
+          </el-select>
+        </div>
+        <alarms-top :alarmId="alarmId" v-if="alarmRow.data" :data="alarmRow.data" ref="atRef" @clickRanking="getHostTrend"/>
       </div>
     </el-tabs>
     <el-empty description="暂无数据" v-else/>
@@ -21,8 +37,9 @@
 
 </template>
 <script setup lang="ts">
-import {listHost, listModel} from "@/api/risk/r5"
-import {onMounted} from "vue";
+import {listHost, listHostTrend, listModel} from "@/api/risk/r5"
+import {nextTick, onMounted} from "vue";
+import {ArrowRightBold} from "@element-plus/icons-vue"
 import cpuTop from "./components/cpuTop.vue"
 import alarmsTop from "./components/alarmsTop.vue"
 import hostSetting from "./components/hostSetting.vue"
@@ -32,6 +49,18 @@ const modelData = ref([])
 const activeName = ref('')
 const hostData = ref([])
 const visible = ref(false)
+const currentData = ref([])
+const currentTitle = ref("")
+const currentRow = ref({})
+const ctRef = ref(null)
+const currentId = ref(0)
+
+const alarmData = ref([])
+const alarmTitle = ref("")
+const alarmRow = ref({})
+const atRef = ref(null)
+const alarmId = ref(0)
+
 onMounted(() => {
   getModelList()
 })
@@ -43,7 +72,7 @@ async function getModelList() {
   await getHostInfo(modelData.value[0].modelId)
 }
 
-function handleSet(){
+function handleSet() {
   visible.value = true
 }
 
@@ -54,6 +83,39 @@ function handleClick(tab) {
 async function getHostInfo(modelId) {
   const res = await listHost(modelId)
   hostData.value = res.data
+  currentData.value = res.data.filter(p => p.data[0].alarms === undefined)
+  alarmData.value = res.data.filter(p => p.data[0].alarms)
+  if (currentData.value.length) {
+    changeCurrent(currentData.value[0].title)
+  }
+  if (alarmData.value.length) {
+    changeAlarm(alarmData.value[0].title)
+  }
+}
+
+function changeAlarm(title) {
+  alarmTitle.value = title
+  alarmRow.value = alarmData.value.find(p => p.title === title)
+  getHostTrend(alarmRow.value.data[0].id, "alarm")
+}
+
+function changeCurrent(title) {
+  currentTitle.value = title
+  currentRow.value = currentData.value.find(p => p.title === title)
+  getHostTrend(currentRow.value.data[0].id, "current")
+}
+
+async function getHostTrend(id, type) {
+  const res = await listHostTrend(id)
+  await nextTick(() => {
+    if(type === "current"){
+      currentId.value = id
+      ctRef.value.initChart(res.data)
+    }else{
+      alarmId.value = id
+      atRef.value.initChart(res.data)
+    }
+  })
 }
 
 </script>