已修改14个文件
已删除2个文件
已添加1个文件
3968 ■■■■ 文件已修改
src/api/site/siteInfo.js 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/router/index.js 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/utils/chartFunction/exceptionOption.js 36 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/utils/chartFunction/lineChart.js 48 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/utils/risk_estimate_common_function/index.js 20 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/utils/risk_estimate_common_function/riskValue.js 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/exception/SiteAuditAssistance.vue 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/exception/components/CompFlightInspection.vue 80 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/exception/components/SubFlightInspection.vue 1847 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/risk_assessment/DataIndexRank.vue 11 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/risk_assessment/DataRiskModel.vue 709 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/risk_assessment/DataRiskRank.vue 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/risk_assessment/SiteComprehensiveRskRanking.vue 371 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/risk_assessment/components/CompDataRiskModel.vue 778 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/risk_assessment/components/DustRadarChart.vue 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/risk_assessment/components/SiteDetail.vue 34 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/risk_assessment/components/subRiskModel.vue 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/site/siteInfo.js
@@ -34,6 +34,15 @@
   */
  queryScenarioTypeName(){
    return $http.get('/dust/scenario')
  },
  /**
   * æ ¹æ®ç‚¹ä½åå­—查询对应的设备编号
   * @param:
   * @returns:
   */
  queryMnCode(siteName){
    return $http.get('/dust/siteInfo/mncode',{params:{siteName:siteName}})
  }
}
src/router/index.js
@@ -17,7 +17,7 @@
          component: () => import('@/views/risk_assessment/DataRiskModel.vue')
        },
        //  æ•°æ®é£Žé™©æŽ’名
        //  æ•°æ®æŒ‡æ ‡æŽ’名
        {
          path: '/analysis',
          name: 'analysis',
@@ -86,7 +86,8 @@
          meta: { title: '风险模型嵌入' },
          component: () => import('@/views/risk_assessment/components/SubRiskModel.vue')
        },
        // å®¡æ ¸è¾…助嵌入过渡页面
        {
          path: '/AuditDetail/:beginTime/:endTime/:exceptionType',
@@ -105,7 +106,7 @@
        // å¼‚常详情嵌入过渡页面
        {
          path: '/exceptionDetail/:siteName/:month/',
          path: '/exceptionDetail/:siteName/:time/:timeType/:jumpPage',
          name: 'exceptionDetail',
          meta: { title: '异常具体信息', transition: 'slide-left' },
          component: () => import('@/views/risk_assessment/components/SiteDetail.vue')
src/utils/chartFunction/exceptionOption.js
@@ -17,6 +17,7 @@
    endIndex,
    exceptionName,
    areaObj,
    lineColor,
    exceptionType
  ) {
    switch (exceptionType) {
@@ -65,7 +66,8 @@
          exceptionName
        )
      case '8':
        return this.validOption(xData, yData, exceptionName, areaObj)
        console.log('传进来',lineColor)
        return this.validOption(xData, yData, exceptionName, areaObj,lineColor)
    }
  },
@@ -564,7 +566,7 @@
   * @param:
   * @returns:
   */
  validOption(xData, yData, exceptionName, areaObj) {
  validOption(xData, yData, exceptionName, areaObj,lineColor) {
    return {
      title: {
        text: exceptionName,
@@ -577,9 +579,6 @@
      toolbox: {
        // å·¥å…·æ 
        feature: {
          // dataZoom: {
          //   yAxisIndex: 'none'
          // },
          // ä¿å­˜ä¸ºå›¾ç‰‡
          saveAsImage: {}
        }
@@ -622,7 +621,32 @@
            data: areaObj
          }
        }
      ]
      ],
      // æŒ‡å®šæ—¶é—´åŒºé—´çš„线段变颜色
      // visualMap: {
      //   show: false,
      //   dimension: 0,
      //   // pieces: [
      //   //   {
      //   //     lte: beginIndex,
      //   //     color: 'green'
      //   //   },
      //   //   {
      //   //     gt: beginIndex,
      //   //     lte: endIndex,
      //   //     color: 'red'
      //   //   },
      //   //   {
      //   //     gt: endIndex,
      //   //     lte: xData.length - 1,
      //   //     color: 'green'
      //   //   }
      //   // ],
      //   pieces: lineColor
      // }
    }
  }
}
src/utils/chartFunction/lineChart.js
@@ -1,4 +1,5 @@
import dayjs from 'dayjs'
import { time } from 'echarts'
export default {
  // èŽ·å–è¯¥æœˆä»½å¤©æ•°
@@ -163,5 +164,50 @@
   */
  deleteLastStr(valueStr) {
    return valueStr.slice(0, -1)
  }
  },
  /**
   * æŒ‡å®šæ—¶é—´åŒºé—´çš„线段变颜色
   * @param:
   * @returns:
   */
  getLineColor(timeInteval,xList){
    let result = []
    // åªå–
    let temp = []
    for (let i = 0; i < timeInteval.length; i++){
      if(timeInteval[i][0]!=timeInteval[i][1]){
        temp.push(timeInteval[i])
      }
    }
    // æ— è¿žç»­çš„æ•°æ® ç›´æŽ¥é€€å‡º
    if(temp.length == 0){
      return []
    }
    // å–第一个连续的时段
    result.push(
      [
      {
        lte: temp[0][0],
        color: 'green'
      },
      {
        gt: temp[0][0],
        lte:temp[0][1],
        color: 'red'
      },
      {
        gt: temp[0][1],
        lte:xList[xList.length-1],
        color: 'green'
      }
    ]
    )
    return result[0]
  },
}
src/utils/risk_estimate_common_function/index.js
@@ -109,8 +109,8 @@
      if (exception.length == 0) {
        exception.push(item.exceptionType)
      }
      // ä¿å­˜æ–°çš„异常类型
      else if (exception.indexOf(item.exceptionType) == -1) {
      // ä¿å­˜æ–°çš„异常类型 æ•°æ®è¶…低、长时间无波动等两类异常暂不纳入分析
      else if ( item.exceptionType!='1' && item.exceptionType!='3' && exception.indexOf(item.exceptionType) == -1) {
        exception.push(item.exceptionType)
      }
    })
@@ -137,15 +137,27 @@
      default:
        return 'error'
    }
    exceptionTypeAggregation = (exception.length / 8).toFixed(2)
    // æ•°æ®è¶…低、长时间无波动等两类异常暂不纳入分析
    exceptionTypeAggregation = (exception.length / 6).toFixed(2)
    let obj = {}
    obj['exceptionRecurrence'] = exceptionTyprRecurRate
    obj['exceptionTypeAggregation'] = exceptionTypeAggregation
    // ä¿å­˜è¯¥æ—¶æ®µå‡ºçŽ°çš„å¼‚å¸¸
    obj['exception'] = exception
    // ä¸‰ç±»å¼‚常出现的次数
    obj['mutationCount'] = mutationCount
    obj['exceedingNearCount'] = exceedingNearCount
    obj['exceedingCriticalDegree'] = exceedingCriticalDegree
    return obj
  },
  // å‚数:对象数组(该对象中的属性不能是引用类型,否则拷贝的值还是会相互影响)
  // åŠŸèƒ½ï¼šæ‹·è´è¯¥å¯¹è±¡æ•°ç»„ã€‚
  shallowCopyList(val) {
src/utils/risk_estimate_common_function/riskValue.js
@@ -63,19 +63,19 @@
    judgeRiskGradeAndAdvice(monthlyRiskValue){
        let temp = []
        // ä½Žé£Žé™©
        if(monthlyRiskValue < 0.2) {
        if(monthlyRiskValue < 0.15) {
            temp.push('低风险')
            let advice =  '1.建议及时提醒该站点所属单位进行应急维护;\n2.若同时存在超标、临界超标、量级突变等异常时,建议将该站点移交环境执法大队开展现场执法检查;\n3.若持续两月及以上为高风险,建议将该站点纳入年度抽测比对清单;'
            temp.push(advice)
        }
        // ä¸­é£Žé™©
        if (monthlyRiskValue < 0.6 && monthlyRiskValue >= 0.2) {
        if (monthlyRiskValue <= 0.6 && monthlyRiskValue >= 0.15) {
            temp.push('中风险')
            let advice =  '1.建议通过守法服务小程序、监测监管微信群等线上方式提示站点所属单位,聚焦当前存在的问题或隐患,及时开展自查自纠;\n2.若同时存在在线率或有效率月度不达标,建议电话通知该站点所属单位进行应急维护,并进行专项审核;'
            temp.push(advice)
        }
        // é«˜é£Žé™©
        if (monthlyRiskValue >= 0.6) {
        if (monthlyRiskValue > 0.6) {
            temp.push('高风险')
            let advice = '1.若不涉及超标或在线率、有效率异常,常态数据审核即可;\n2.若涉及超标或在线率、有效率等异常,建议通过守法服务小程序、监测监管微信群等线上方式提示站点所属单位,及时开展自查自纠;'
            temp.push(advice)
src/views/exception/SiteAuditAssistance.vue
@@ -245,6 +245,7 @@
        '',
        this.tableCurrentRowData.exception,
        areaObj,
        '',
        this.tableCurrentRowData.exceptionType
      )
    },
@@ -1709,7 +1710,7 @@
          align="center"
          show-overflow-tooltip
        />
        <el-table-column prop="flag" label="flag" align="center" show-overflow-tooltip />
        <el-table-column prop="flag" label="数据标识" align="center" show-overflow-tooltip />
      </el-table>
    </div>
    <template #footer>
src/views/exception/components/CompFlightInspection.vue
@@ -33,8 +33,8 @@
      type: String,
      default: ''
    },
    // æœˆä»½
    month:{
    // æ—¥æ—¶é—´æˆ–者月时间
    time:{
        type:String,
        default:''
    },
@@ -42,6 +42,12 @@
    showAll: {
      type: Boolean,
      default: true
    },
    // 0代表日时间,1代表月时间
    timeType:{
      type:Number,
      default:-1
    }
  },
  components: {
@@ -179,7 +185,6 @@
    }
  },
  setup() {
    // provide('search',readonly(form))
    const { isExceedOneMonth } = useCommonFunction()
    return {
      isExceedOneMonth
@@ -221,17 +226,26 @@
            this.backExceptionDataAWeekAgo()
        }
    },
    siteName(){
        this.beginTime = dayjs(this.month).startOf('month').format('YYYY-MM-DD HH:mm:ss')
        this.endTime = dayjs(this.month).endOf('month').format('YYYY-MM-DD HH:mm:ss')
        this.backExceptionDataAWeekAgo()
        this.getShopNames()
    },
    month(){
        this.beginTime = dayjs(this.month).startOf('month').format('YYYY-MM-DD HH:mm:ss')
        this.endTime = dayjs(this.month).endOf('month').format('YYYY-MM-DD HH:mm:ss')
        this.backExceptionDataAWeekAgo()
        this.getShopNames()
    // siteName(){
    //   if(this.siteName!=''){
    //     this.beginTime = dayjs(this.month).startOf('month').format('YYYY-MM-DD HH:mm:ss')
    //     this.endTime = dayjs(this.month).endOf('month').format('YYYY-MM-DD HH:mm:ss')
    //     this.backExceptionDataAWeekAgo()
    //     this.getShopNames()
    //   }
    // },
    timeType(){
      if(this.timeType == '0'){
        this.beginTime = dayjs(this.time).format('YYYY-MM-DD 00:00:00')
        this.endTime = dayjs(this.time).format('YYYY-MM-DD 23:59:59')
      }else if(this.timeType == '1'){
        this.beginTime = dayjs(this.time).startOf('month').format('YYYY-MM-DD HH:mm:ss')
        this.endTime = dayjs(this.time).endOf('month').format('YYYY-MM-DD HH:mm:ss')
      }
      this.backExceptionDataAWeekAgo()
      this.getShopNames()
    }
  },
  computed: {
@@ -379,6 +393,12 @@
  mounted() {
    this.getSiteNume()
    // é£žè¡Œå·¡æ£€é¡µé¢ï¼Œè¿›åŽ»åŠ è½½
    if(this.showAll == true){
      this.backExceptionDataAWeekAgo()
      this.getShopNames()
    }
  },
  methods: {
@@ -413,7 +433,9 @@
      // let rangeTime_1 = time.splitTime(rangeTime)
      // å¾—到背景区间的配置
      let areaObj = lineChart.getMarkArea(rangeTime, '异常')
      // let lineColor = lineChart.getLineColor(rangeTime,xList)
      let lineColor = []
      // console.log('线段',lineColor);
      // ä¼ å…¥å‚æ•°
      this.dialog.option = exceptionOption.setExceptionChartOption(
        xList,
@@ -424,6 +446,7 @@
        '',
        this.tableCurrentRowData.exception,
        areaObj,
        lineColor,
        this.tableCurrentRowData.exceptionType
      )
    },
@@ -535,6 +558,7 @@
          startIndex,
          endIndex,
          this.tableCurrentRowData.exception,
          '',
          '',
          this.tableCurrentRowData.exceptionType
        )
@@ -1201,10 +1225,11 @@
            align="center"
            show-overflow-tooltip
          />
          <el-table-column prop="flag" label="flag" align="center" show-overflow-tooltip />
          <el-table-column prop="flag" label="数据标识" align="center" show-overflow-tooltip />
        </el-table>
      </div>
      <template #footer>
        <div class="dialog-footer">
        <el-tag type="success" class="mx-1" effect="dark" round
          ><span class="table-line-lable" v-show="tableCurrentRowData.exceptionType == '0'"
            >缺失数据:
@@ -1214,13 +1239,20 @@
              tableCurrentRowData.exceptionType == '1' ||
              tableCurrentRowData.exceptionType == '2' ||
              tableCurrentRowData.exceptionType == '3' ||
              tableCurrentRowData.exceptionType == '4'
              tableCurrentRowData.exceptionType == '4' ||
              tableCurrentRowData.exceptionType == '5' ||
              tableCurrentRowData.exceptionType == '6' ||
              tableCurrentRowData.exceptionType == '7' ||
              tableCurrentRowData.exceptionType == '8'
            "
            >异常数据:</span
          >
          <span class="table-line-num">{{ dialog.exceptionTotal }}条</span>
          <span v-show="tableCurrentRowData.exceptionType == '0'"> (逻辑计算)</span>
        </el-tag>
        <el-text v-show="tableCurrentRowData.exceptionType == '8'" type="warning" class="dialog-footer-text">数据标识A为数据长期缺失,系统自动补全</el-text>
        <!-- <el-text class="mx-1" type="warning">Warning</el-text> -->
      </div>
      </template>
    </el-dialog>
  </div>
@@ -1359,9 +1391,19 @@
}
.mx-1 {
  position: absolute;
  /* position: absolute;
  left: 10px;
  bottom: 10px;
  bottom: 10px; */
  justify-content: flex-start;
}
.dialog-footer{
  display: flex;
}
.dialog-footer-text {
  justify-content: flex-end;
  margin-left: auto;
  font-size: 14px;
  /* color: #333333; */
}
/* æŸ¥çœ‹è¯¦æƒ…对话框模块结束 */
</style>
src/views/exception/components/SubFlightInspection.vue
ÎļþÒÑɾ³ý
src/views/risk_assessment/DataIndexRank.vue
@@ -8,6 +8,8 @@
import ButtonExportExcel from '@/sfc/ButtonExportExcel.vue'
import ButtonClick from '@/sfc/ButtonClick.vue'
export default {
  components: {
    TimeShortCuts,
@@ -96,12 +98,13 @@
        }
      }
      //  åœ¨çº¿çŽ‡ï¼Œæœ‰æ•ˆçŽ‡ ä¸æ»¡è¶³æ ‡å‡†æ—¶ å˜é¢œè‰²
      if (columnIndex == 7) {
        if (row.dayOnline < 0.9) {
          return 'red-color'
        }
      }
      if (columnIndex == 8) {
        if (row.dayValid < 0.9) {
          return 'red-color'
@@ -179,12 +182,16 @@
    },
    openDetail(row) {
      const encodedSiteName = encodeURIComponent(row.name)
      this.$router.push(`/exceptionDetail/${encodedSiteName}/${row.lst}`)
      const timeType = '0'
      const jumpPage = '2'
      this.$router.push(`/exceptionDetail/${encodedSiteName}/${row.lst}/${timeType}/${jumpPage}`)
    }
  }
}
</script>
<template>
  <el-form :inline="true" :model="form" ref="h1">
    <el-form-item>
src/views/risk_assessment/DataRiskModel.vue
@@ -1,712 +1,27 @@
<!-- æ—¥å‡å€¼ -->
<script>
import InputSearch from '@/sfc/InputSearch.vue'
import AreaAndmonitorType from '@/sfc/AreaAndmonitorType.vue'
import DustRadarChart from './components/DustRadarChart.vue'
import exceptionApi from '@/api/exceptionApi.js'
import LineChart from './components/LineChart.vue'
import index from '@/utils/risk_estimate_common_function/index.js'
import ButtonClick from '@/sfc/ButtonClick.vue'
import dayjs from 'dayjs'
import MonthSelect from '@/sfc/MonthSelect.vue'
import riskApi from '@/api/risk/riskApi.js'
import riskValue from '@/utils/risk_estimate_common_function/riskValue.js'
import lineChart from '@/utils/chartFunction/lineChart.js'
import siteInfo from '@/api/site/siteInfo.js'
export default {
  components: {
    LineChart,
    InputSearch,
    AreaAndmonitorType,
    DustRadarChart,
    ButtonClick,
    MonthSelect
  },
  data() {
    return {
      isNoData: false,
      loading: false,
      screenLoading: false,
      parentDataFlag: false,
      chartData: [],
      chartData1: {}, //保存查询的结果
      chartData2: {},
      chartData3: {},
      chartData4: {},
      begin: '', //开始时间
      end: '', //结束时间
      form: {
        // ç«™ç‚¹åç§°
        name: '',
        // è®¾å¤‡ç¼–号
        number: '3234',
        // å¼€å§‹æ—¶é—´
        beginTime: '',
        // ç»“束时间
        endTime: ''
      },
      month: '',
      // æŠ˜çº¿å›¾é…ç½®é¡¹
      option: {},
      // æ•°æ®æ¸…单
      bill: {
        min: '',
        max: '',
        avg: '',
        online: 100,
        valid: 100,
        exceeding: 0,
        //  å…¸åž‹å¼‚常复现率
        exceptionRecurrence: 0,
        // å¼‚常类型据聚集度
        exceptionTypeAggregation: 0
      },
      // æŸ¥è¯¢æŒ‰é’®åŠ è½½æ•ˆæžœ
      queryButton: false,
      // é£Žé™©å€¼æŽ’名前十的站点
      top_10_sites_with_risk_values: [{ name: '', riskValue: 0.2 }],
      // é£Žé™©å€¼
      weight: '',
      // æ— æ•°æ®é…ç½®æ—¶é—´æ®µ
      areaColor: [],
      // æŸç«™ç‚¹çš„基本信息
      siteInfo: {},
      // å¼‚常风险的值
      exceptionRisk: {
        // åœ¨çº¿çŽ‡é£Žé™©
        onlineRisk: '',
        // æœ‰æ•ˆçŽ‡é£Žé™©
        validRisk: '',
        // è¶…标风险
        exceedRisk: '',
        // å¼‚常类型聚集度
        exceptionTypeAggregation: '',
        // å…¸åž‹å¼‚常复现率
        typicalExceptionRepetitionRate:''
      }
    }
  },
  mounted() {
    // // åŠ è½½é£Žé™©å€¼æœ€é«˜çš„ç«™ç‚¹æ•°æ®
    this.ShowDefaultData()
  },
  computed: {
    // é£Žé™©ç­‰çº§
    riskGradeAndAdvice() {
      return riskApi.getRiskAdvice(this.weight)
    }
  },
  methods: {
    // æŸ¥è¯¢ç«™ç‚¹ç»Ÿè®¡ä¿¡æ¯
    async querySiteStaticsInfo(row) {
      this.form.name = row.siteName
      // æ›´æ–°ç»Ÿè®¡æ•°æ®
      await this.getAnalysisData()
      // è®¡ç®—风险值
      this.calRiskValue()
  import CompDataRiskModel from '@/views/risk_assessment/components/CompDataRiskModel.vue'
  export default {
    components:{
      CompDataRiskModel
    },
    data() {
      return{
    // æ ¼å¼åŒ–月份
    giveMonth(val) {
      //将中国标准时间转为指定格式(该组件返回的标准时间的格式,所以必须的加这个函数)
      this.month = dayjs(val).format('YYYY-MM-DD')
      // åŒæ—¶æ›´æ–°å¼€å§‹å’Œç»“束时间
      this.form.beginTime = dayjs(this.month).startOf().format('YYYY-MM-DD HH:mm:ss')
      this.form.endTime = dayjs(this.month).endOf('month').format('YYYY-MM-DD HH:mm:ss')
    },
    /**
     * é£Žé™©è¯„估按钮
     * @param:
     * @returns:
     */
    riskAssessment() {
      // æ›´æ–°æŽ’名清单
      this.getRiskRank()
      // æ›´æ–°è¯¥ç«™ç‚¹çš„æ‰€å±žåœºæ™¯å’Œè¿ç»´å•†
      this.getSiteInfo(this.form.number)
      // æ›´æ–°åˆ†æžæ•°æ®
      this.getAnalysisData()
      // è®¡ç®—风险值
      this.calRiskValue()
    },
    // æ›´æ–°åˆ†æžæ•°æ®
    getAnalysisData() {
      // æ—¥ç»Ÿè®¡æ•°æ®
      this.fetchDayAnalysisData()
      // å¼‚常数据
      // this.fetchExceptionAnalysisData()
    },
    findObjectByPropertyValue(array, property, value) {
      return array.find((obj) => obj[property] === value)
    },
    // æ­¤é¡µé¢æ‰“开时
    ShowDefaultData() {
      // é»˜è®¤åŠ è½½å±•ç¤ºçš„å†…å®¹
      this.updateOriginPage()
    },
    // åŠ è½½é»˜è®¤å±•ç¤ºçš„å†…å®¹
    async updateOriginPage() {
      this.screenLoading = true
      // æ›´æ–°æŽ’名清单,并得到风险值最高站点
      let arr = await this.getRiskRank()
      this.form.name = arr[0]
      this.form.number = arr[1]
      this.screenLoading = false
      // æ›´æ–°è¯¥ç«™ç‚¹çš„æ‰€å±žåœºæ™¯å’Œè¿ç»´å•†
      this.getSiteInfo(this.form.number)
      // æ›´æ–°æ—¥ç»Ÿè®¡æ•°æ®
      this.getAnalysisData()
      // è®¡ç®—风险值
      this.calRiskValue()
    },
    /**
    * å¾—到数据风险值 ï¼Œå¹¶è®¡ç®—风险值
    * @param:
    * @returns:
    */
    calRiskValue() {
      riskApi.queryRiskValue(this.form.number, this.month, 'month').then((response) => {
        const riskValue = response.data.data[0]
        this.exceptionRisk.onlineRisk = riskValue.onlineRisk
        this.exceptionRisk.validRisk = riskValue.validRisk
        this.exceptionRisk.exceedRisk = riskValue.exceedRisk
        this.exceptionRisk.exceptionTypeAggregation = riskValue.exceptionTypeAggregation
        this.exceptionRisk.typicalExceptionRepetitionRate = riskValue.typicalExceptionRepetitionRate
        this.weight = riskValue.calRiskValue(riskValue).toFixed(2)
      })
    },
    //  æ ¹æ®ç›®å‰ç«™ç‚¹ï¼Œæœˆä»½ï¼ŒæŸ¥æŠ˜çº¿å›¾æ—¥ç»Ÿè®¡æ•°æ®
    fetchDayAnalysisData() {
      let params = {}
      if (this.form.name) {
        params['siteName'] = this.form.name
      }
      if (this.form.beginTime) {
        params['beginTime'] = this.form.beginTime
      }
      if (this.form.endTime) {
        params['endTime'] = this.form.endTime
      }
      this.loading = true
      this.queryButton = true
      exceptionApi
        .analysisdata(this.form.name, this.form.beginTime, this.form.endTime, 'day')
        .then((response) => {
          this.chartData = response.data.data
          this.loading = false
          this.queryButton = false
          if (response.data.data.length == 0) {
            this.isNoData = true
            return
          }
          // åˆ†æžæ•°æ®ä¸­çš„æœ€æ—©æ—¶é—´
          let begin = this.chartData[0].lst
          // åˆ†æžæ•°æ®ä¸­çš„æœ€æ™šæ—¶é—´
          let end = this.chartData[this.chartData.length - 1].lst
          // ç§»é™¤ç©ºæ•°æ®çŠ¶æ€
          this.isNoData = false
          // æ— æ•°æ®çš„æ—¶é—´æ®µ
          let noDataTimeInteval = lineChart.backNoDataInteval(begin, end)
          // æ— æ•°æ®é…ç½®æ—¶é—´æ®µ
          this.areaColor = lineChart.getMarkArea(noDataTimeInteval)
          this.setChart()
          //  æŠ˜çº¿å›¾æ•°æ®
          let temp = index.calBillData(this.chartData, begin, end)
          this.bill.min = temp['min']
          this.bill.max = temp['max']
          this.bill.avg = temp['avg']
          this.bill.online = temp['online']
          this.bill.valid = temp['valid']
          this.bill.exceeding = temp['exceeding']
        })
    },
    // ä¼ä¸šå¼‚常统计数据
    fetchExceptionAnalysisData() {
      exceptionApi
        .exceptiondata1({
          siteName: this.form.name,
          beginTime: this.form.beginTime,
          endTime: this.form.endTime
        })
        .then((res) => {
          let obj = index.calRecur(res.data.data)
          this.bill.exceptionRecurrence = obj['exceptionRecurrence']
          this.bill.exceptionTypeAggregation = obj['exceptionTypeAggregation']
        })
    },
    // é€‰æ‹©å…¶ä»–值类型时
    setChart() {
      if (this.chartData.length) {
        // æž„建折线图x,y数据
        let obj = lineChart.getLineChartXYData(
          this.chartData,
          this.form.beginTime,
          this.form.endTime
        )
        this.chartData1 = {
          x: obj.xData,
          y: obj.yAvg
        }
        this.chartData2 = {
          x: obj.xData,
          y: obj.yOnline
        }
        this.chartData3 = {
          x: obj.xData,
          y: obj.yValid
        }
        this.chartData4 = {
          x: obj.xData,
          y: obj.yExceed
        }
      }
    },
    mounted() {
    // å¾—到前10风险排名清单
    async getRiskRank() {
      let response = await riskApi.queryRiskValue('', this.month, 'month')
      let tableData = riskValue.backComprehensiveRiskTableData(response.data.data)
      this.top_10_sites_with_risk_values = this.getTopRiskData(tableData, 10)
      if (this.top_10_sites_with_risk_values.length != 0) {
        // è¡¨æ ¼æŒ‰é£Žé™©å€¼å€’叙排列
        this.$nextTick(() => {
          this.$refs.table.sort('riskValue', 'descending')
        })
        // ä¿å­˜é£Žé™©å€¼æœ€é«˜çš„站点名称和设备编号
        let temp = []
        temp.push(
          this.top_10_sites_with_risk_values[0].siteName,
          this.top_10_sites_with_risk_values[0].mnCode
        )
        return temp
      }
    },
    /**
     * é™åºæŽ’列,返回降序前num的元素
     * @param: å¯¹è±¡æ•°ç»„,返回的数量
     */
    getTopRiskData(arr, num) {
      // æŒ‰ç…§riskValue降序排列
      arr.sort((a, b) => b.riskValue - a.riskValue)
      // èŽ·å–å‰num个元素
      return arr.slice(0, num)
    },
    /**
     * æ ¹æ®è®¾å¤‡ç¼–号查询站点基本信息
     * @param: è®¾å¤‡ç¼–号
     */
    getSiteInfo(mnCode) {
      siteInfo.querySiteInfoByMnCode(mnCode).then(response => {
        this.siteInfo = response.data.data[0]
      })
    },
    methods: {
    openDetail() {
      const encodedSiteName = encodeURIComponent(this.form.name)
      this.$router.push(`/exceptionDetail/${encodedSiteName}/${this.month}`)
    }
  }
     }
}
</script>
<template>
  <el-form :inline="true" :model="form">
    <el-form-item class="form-item">
      <AreaAndmonitorType></AreaAndmonitorType>
    </el-form-item>
    <el-form-item class="form-item">
      <InputSearch
        :site-name="form.name"
        isNeedDefaultSite="0"
        @submit-value="(n) => (form.name = n)"
        @submit-mncode="(n) => (form.number = n)"
      ></InputSearch>
    </el-form-item>
    <el-form-item>
      <MonthSelect  @submit-value="giveMonth"></MonthSelect>
    </el-form-item>
    <el-form-item>
      <ButtonClick
        content="风险评估"
        type="primary"
        :loading="queryButton"
        @do-search="riskAssessment"
      ></ButtonClick>
    </el-form-item>
  </el-form>
  <div v-loading="screenLoading" class="wait-name">
    <div class="chart-container" v-show="!isNoData && !screenLoading">
      <el-card class="time-text" >
        <h4>{{form.name}}</h4>
        <br/>
        <br/>
         <span>数据统计时段:{{ form.beginTime }} ~ {{ form.endTime }}</span>
         <el-tag class="mx-1" >场景</el-tag>{{siteInfo.typename}}
         <el-tag class="mx-1">运维商</el-tag>{{siteInfo.dutyCompany}}
         <el-button type="primary"  size="default" class="exception-button" @click="openDetail">
           æ•°æ®å¼‚常详情
         </el-button>
       </el-card>
      <el-row :gutter="10">
        <el-col :span="5">
          <el-card shadow="never" class="table-class">
            <el-table
              ref="table"
              :highlight-current-row="true"
              :data="top_10_sites_with_risk_values"
              :default-sort="{ prop: 'riskValue', order: 'descending' }"
              height="540"
            >
              <el-table-column
                type="index"
                label="序号"
                fixed
                width="52"
                show-overflow-tooltip
                align="center"
              />
              <el-table-column
                prop="siteName"
                label="点位名称"
                show-overflow-tooltip
                width="97"
                align="center"
              >
                <template #default="{ row }">
                  <el-button
                    type="primary"
                    text
                    class="table-button"
                    @click="querySiteStaticsInfo(row)"
                    >
                  <span class="risk-rank-site">
                    {{ row.siteName }}
                  </span>
                    </el-button
                  >
                </template>
              </el-table-column>
              <el-table-column
                prop="riskValue"
                label="风险值"
                sortable
                show-overflow-tooltip
                align="center"
              />
            </el-table>
          </el-card>
        </el-col>
        <el-col :span="11">
          <el-card shadow="never" class="table-class">
            <DustRadarChart
              :name="[
                '数据有效风险',
                '典型异常复现风险',
                '异常类型聚集风险',
                '超标异常风险',
                '数据在线风险'
              ]"
              :yData="exceptionRisk"
            ></DustRadarChart>
          </el-card>
        </el-col>
        <el-col :span="4">
          <el-card shadow="never" class="card-height risk-card">
            <template #header>
              <h1
                :class="{
                  'weightColor-low': weight < 0.2,
                  'weightColor-medium': weight >= 0.2 && weight < 0.6,
                  'weightColor-heigh': weight >= 0.6
                }"
              >
                é£Žé™©å€¼(0~1):{{ weight }}
              </h1>
            </template>
            <div class="risk-text-container">
            <div class="risk-grade">
              <h1 class="sub-title">风险等级:</h1>
              <span class="sub-title">{{ riskGradeAndAdvice.riskGrade }} </span>
            </div>
            <div class="risk-advice">
              <h1 class="sub-title">管控建议:</h1>
              <div v-for="item in riskGradeAndAdvice.riskAdvice" :key="item" class="risk-advice-text">
                {{ item }}
              </div>
            </div>
            <div class="grade-instance">
              <div class="container">
                <div class="block-color heigh"></div>
                <div>高风险(≥0.6)</div>
              </div>
              <div class="container">
                <div class="block-color medium"></div>
                <div>中风险(0.2~0.6)</div>
              </div>
              <div class="container">
                <div class="block-color low"></div>
                <div>低风险(<0.2)</div>
              </div>
            </div>
            </div>
          </el-card>
        </el-col>
        <el-col :span="4">
          <el-card shadow="never" class="card-height">
            <template #header>
              <span class="title-16">风险详情</span>
            </template>
            <el-form>
              <el-form-item label="最大值:"> {{ bill.max }} mg/m³ </el-form-item>
              <el-form-item label="最小值:"> {{ bill.min }} mg/m³ </el-form-item>
              <el-form-item label="数据有效率:"> {{ bill.online }}% </el-form-item>
              <el-form-item label="数据在线率:"> {{ bill.valid }}% </el-form-item>
              <el-form-item label="数据超标率:"> {{ bill.exceeding }}% </el-form-item>
              <el-form-item label="异常类型聚集度:">
                {{ bill.exceptionTypeAggregation * 100 }}%
              </el-form-item>
              <el-form-item label="典型异常复现率:">
                {{ bill.exceptionRecurrence * 100 }}%
              </el-form-item>
            </el-form>
          </el-card>
        </el-col>
      </el-row>
      <el-row :gutter="20">
        <el-col :span="12">
          <el-card shadow="never" class="card-value">
            <LineChart
              title="日均值"
              :chartData="chartData1"
              yName="mg/m³"
              seriesName="日均值"
              :areaColor="areaColor"
            >
            </LineChart>
          </el-card>
        </el-col>
        <el-col :span="12">
          <el-card shadow="never" class="card-value">
            <LineChart
              title="日有效率"
              :chartData="chartData3"
              yName="%"
              seriesName="日有效率"
              :areaColor="areaColor"
            >
            </LineChart>
          </el-card>
        </el-col>
      </el-row>
    </div>
  </div>
  <el-empty description="暂无数据" v-show="isNoData" :image-size="200" />
  <CompDataRiskModel  :show-all="true"/>
</template>
<style scoped>
.el-form {
  margin: 10px;
}
.form-item {
  margin-top: 10px;
}
.chart-container {
  margin-left: 10px;
}
.time-text {
  font-size: 14px;
  color: #333333;
  letter-spacing: 1px;
}
.el-card {
  margin-top: 15px;
  border-radius: 9px;
}
.chart-container {
  width: 98%;
  /* height: 600px; */
}
<style  scoped>
.card-height {
  height: 570px;
}
.el-header {
  background-color: #010408;
  color: #333;
  line-height: 60px;
}
.risk-advice {
  /* margin: 20px 0px; */
}
.container {
  display: flex;
  margin-bottom: 10px;
}
.grade-instance {
  /* margin-top: 50px; */
}
.block-color {
  width: 1em;
  height: 1em;
  margin-right: 10px;
  margin-top: 3px;
}
.heigh {
  background-color: red;
}
.medium {
  background-color: #fadc19;
}
.low {
  background-color: #9fdb1d;
}
.el-text {
  align-self: left;
}
.el-form-item {
  margin-bottom: 20px;
}
:deep().el-form-item__content {
  justify-content: flex-end;
}
.title-16 {
  font-size: 16px;
  font-weight: bold;
}
.weightColor-low {
  color: #9fdb1d;
  font-size: 16px;
}
.weightColor-medium {
  color: #dabe09;
  font-size: 16px;
}
.weightColor-heigh {
  color: red;
  font-size: 16px;
}
.risk-grade {
  display: flex;
}
:deep().el-table__header-wrapper {
  color: red;
}
/* .wait-name {
    width: 500px;
    height: 600px;
  } */
.table-class {
  /* border: 1px solid blue; */
  /* margin: 20px 0px 20px 0px; */
  height: 570px;
}
.table-button {
  letter-spacing: 1px;
  text-decoration: underline;
  /* border-radius: 0px; */
}
.risk-rank-site {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  width: 80px;
}
.site-name {
  margin-left: 20px;
}
.risk-advice-text {
  font-size: 14px;
  color: #333333;
  letter-spacing: 1.5px;
  margin-top: 10px;
}
.sub-title {
  font-size: 14px;
  color: #333333;
}
.risk-text-container{
  height: 490px;
  display: flex;
  flex-direction: column;
  justify-content: space-around;
}
.el-tag{
  margin-left: 25px;
  font-size: 14px;
  vertical-align: baseline;
}
.exception-button {
  vertical-align: baseline;
  margin-left: 150px;
}
.site-info-detail{
  display: flex;
  justify-content: space-between;
}
.mx-1{
  margin-left: 100px;
}
</style>
</style>
src/views/risk_assessment/DataRiskRank.vue
@@ -214,8 +214,8 @@
    },
    openDetail(row) {
      const encodedSiteName = encodeURIComponent(row.siteName)
      let titleName = '站点风险数据详情'
      this.$router.push(`/detail/${encodedSiteName}/${this.form.month}/${titleName}`)
      const jumpPage = 1
      this.$router.push(`/exceptionDetail/${encodedSiteName}/${this.form.month}/1/${jumpPage}`)
    }
  }
}
src/views/risk_assessment/SiteComprehensiveRskRanking.vue
ÎļþÒÑɾ³ý
src/views/risk_assessment/components/CompDataRiskModel.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,778 @@
<!-- æ—¥å‡å€¼ -->
<script>
import InputSearch from '@/sfc/InputSearch.vue'
import AreaAndmonitorType from '@/sfc/AreaAndmonitorType.vue'
import exceptionApi from '@/api/exceptionApi.js'
import DustRadarChart from '@/views/risk_assessment/components/DustRadarChart.vue'
import LineChart from '@/views/risk_assessment/components/LineChart.vue'
import index from '@/utils/risk_estimate_common_function/index.js'
import ButtonClick from '@/sfc/ButtonClick.vue'
import dayjs from 'dayjs'
import MonthSelect from '@/sfc/MonthSelect.vue'
import riskApi from '@/api/risk/riskApi.js'
import riskValue from '@/utils/risk_estimate_common_function/riskValue.js'
import lineChart from '@/utils/chartFunction/lineChart.js'
import siteInfo from '@/api/site/siteInfo.js'
export default {
  props: {
    // ç‚¹ä½åå­—
    siteName: {
      type: String,
      default: ''
    },
    // æœˆä»½
    time: {
      type: String,
      default: ''
    },
    // å±•示页面的全部
    showAll: {
      type: Boolean,
      default: true
    }
  },
  components: {
    LineChart,
    InputSearch,
    AreaAndmonitorType,
    DustRadarChart,
    ButtonClick,
    MonthSelect
  },
  data() {
    return {
      isNoData: false,
      loading: false,
      screenLoading: false,
      parentDataFlag: false,
      chartData: [],
      chartData1: {}, //保存查询的结果
      chartData2: {},
      chartData3: {},
      chartData4: {},
      begin: '', //开始时间
      end: '', //结束时间
      form: {
        // ç«™ç‚¹åç§°
        name: '',
        // è®¾å¤‡ç¼–号
        number: '3234',
        // å¼€å§‹æ—¶é—´
        beginTime: '',
        // ç»“束时间
        endTime: ''
      },
      month: '',
      // æŠ˜çº¿å›¾é…ç½®é¡¹
      option: {},
      // æ•°æ®æ¸…单
      bill: {
        min: '',
        max: '',
        avg: '',
        online: 100,
        valid: 100,
        exceeding: 0,
        //  å…¸åž‹å¼‚常复现率
        exceptionRecurrence: 0,
        // å¼‚常类型据聚集度
        exceptionTypeAggregation: 0,
        exception: 0,
        mutationCount: 0,
        exceedingNearCount: 0,
        exceedingCriticalDegree: 0
      },
      // æŸ¥è¯¢æŒ‰é’®åŠ è½½æ•ˆæžœ
      queryButton: false,
      // é£Žé™©å€¼æŽ’名前十的站点
      top_10_sites_with_risk_values: [{ name: '', riskValue: 0.2 }],
      // é£Žé™©å€¼
      weight: '',
      // æ— æ•°æ®é…ç½®æ—¶é—´æ®µ
      areaColor: [],
      // æŸç«™ç‚¹çš„基本信息
      siteInfo: {},
      // å¼‚常风险的值
      exceptionRisk: {
        // åœ¨çº¿çŽ‡é£Žé™©
        onlineRisk: '',
        // æœ‰æ•ˆçŽ‡é£Žé™©
        validRisk: '',
        // è¶…标风险
        exceedRisk: '',
        // å¼‚常类型聚集度
        exceptionTypeAggregation: '',
        // å…¸åž‹å¼‚常复现率
        typicalExceptionRepetitionRate: ''
      }
    }
  },
  watch: {
    // showAll() {
    //     console.log('1111')
    //   // é¡µé¢åŠ è½½æ—¶showAll才会变化一次
    //   // ä¸ºtrue表示的风险模型页面
    //   if (this.showAll) {
    //     // åŠ è½½é£Žé™©å€¼æœ€é«˜çš„ç«™ç‚¹æ•°æ®
    //     this.ShowDefaultData()
    //   }
    // },
    siteName() {
      if(this.siteName!= ''){
    // æ›´æ–°ç«™ç‚¹åå­—和时间
      this.form.name = this.siteName
      this.screenLoading = true
      siteInfo.queryMnCode(this.siteName).then((response) => {
        this.form.number = response.data.data[0].mnCode
        this.month = this.time
        // åŒæ—¶æ›´æ–°æœˆèµ·å§‹æ—¶é—´
        this.form.beginTime = dayjs(this.month).startOf().format('YYYY-MM-DD HH:mm:ss')
        this.form.endTime = dayjs(this.month).endOf('month').format('YYYY-MM-DD HH:mm:ss')
        // æ›´æ–°è¯¥ç«™ç‚¹çš„æ‰€å±žåœºæ™¯å’Œè¿ç»´å•†
        this.getSiteInfo(this.form.number)
        // æ›´æ–°ç»Ÿè®¡æ•°æ®
        this.getAnalysisData()
        // è®¡ç®—风险值
        this.calRiskValue()
        this.screenLoading = false
      })
      }
    }
  },
  computed: {
    // é£Žé™©ç­‰çº§
    riskGradeAndAdvice() {
      return riskApi.getRiskAdvice(this.weight)
    }
  },
mounted(){
    if(this.showAll){
        // åŠ è½½é£Žé™©å€¼æœ€é«˜çš„ç«™ç‚¹æ•°æ®
        this.ShowDefaultData()
    }
},
  methods: {
    // æŸ¥è¯¢ç«™ç‚¹ç»Ÿè®¡ä¿¡æ¯
    async querySiteStaticsInfo(row) {
      this.form.name = row.siteName
      // æ›´æ–°ç»Ÿè®¡æ•°æ®
      await this.getAnalysisData()
      // è®¡ç®—风险值
      this.calRiskValue()
    },
    // æ ¼å¼åŒ–月份
    giveMonth(val) {
      //将中国标准时间转为指定格式(该组件返回的标准时间的格式,所以必须的加这个函数)
      this.month = dayjs(val).format('YYYY-MM-DD')
      // åŒæ—¶æ›´æ–°å¼€å§‹å’Œç»“束时间
      this.form.beginTime = dayjs(this.month).startOf().format('YYYY-MM-DD HH:mm:ss')
      this.form.endTime = dayjs(this.month).endOf('month').format('YYYY-MM-DD HH:mm:ss')
    },
    /**
     * é£Žé™©è¯„估按钮
     * @param:
     * @returns:
     */
    riskAssessment() {
      // æ›´æ–°æŽ’名清单
      this.getRiskRank()
      // æ›´æ–°è¯¥ç«™ç‚¹çš„æ‰€å±žåœºæ™¯å’Œè¿ç»´å•†
      this.getSiteInfo(this.form.number)
      // æ›´æ–°åˆ†æžæ•°æ®
      this.getAnalysisData()
      // è®¡ç®—风险值
      this.calRiskValue()
    },
    // æ›´æ–°åˆ†æžæ•°æ®
    getAnalysisData() {
      // æ—¥ç»Ÿè®¡æ•°æ®
      this.fetchDayAnalysisData()
      // å¼‚常数据
      this.fetchExceptionAnalysisData()
    },
    findObjectByPropertyValue(array, property, value) {
      return array.find((obj) => obj[property] === value)
    },
    // æ­¤é¡µé¢æ‰“开时
    ShowDefaultData() {
      // é»˜è®¤åŠ è½½å±•ç¤ºçš„å†…å®¹
      this.updateOriginPage()
    },
    // åŠ è½½é»˜è®¤å±•ç¤ºçš„å†…å®¹
    async updateOriginPage() {
      this.screenLoading = true
      // æ›´æ–°æŽ’名清单,并得到风险值最高站点
      let arr = await this.getRiskRank()
      this.form.name = arr[0]
      this.form.number = arr[1]
      this.screenLoading = false
      // æ›´æ–°è¯¥ç«™ç‚¹çš„æ‰€å±žåœºæ™¯å’Œè¿ç»´å•†
      this.getSiteInfo(this.form.number)
      // æ›´æ–°æ—¥ç»Ÿè®¡æ•°æ®
      this.getAnalysisData()
      // è®¡ç®—风险值
      this.calRiskValue()
    },
    /**
     * å¾—到数据风险值 ï¼Œå¹¶è®¡ç®—风险值
     * @param:
     * @returns:
     */
    calRiskValue() {
      riskApi.queryRiskValue(this.form.number, this.month, 'month').then((response) => {
        const rValue = response.data.data[0]
        this.exceptionRisk.onlineRisk = rValue.onlineRisk
        this.exceptionRisk.validRisk = rValue.validRisk
        this.exceptionRisk.exceedRisk = rValue.exceedRisk
        this.exceptionRisk.exceptionTypeAggregation = rValue.exceptionTypeAggregation
        this.exceptionRisk.typicalExceptionRepetitionRate = rValue.typicalExceptionRepetitionRate
        this.weight = riskValue.calRiskValue(rValue).toFixed(2)
      })
    },
    //  æ ¹æ®ç›®å‰ç«™ç‚¹ï¼Œæœˆä»½ï¼ŒæŸ¥æŠ˜çº¿å›¾æ—¥ç»Ÿè®¡æ•°æ®
    fetchDayAnalysisData() {
      let params = {}
      if (this.form.name) {
        params['siteName'] = this.form.name
      }
      if (this.form.beginTime) {
        params['beginTime'] = this.form.beginTime
      }
      if (this.form.endTime) {
        params['endTime'] = this.form.endTime
      }
      this.loading = true
      this.queryButton = true
      exceptionApi
        .analysisdata(this.form.name, this.form.beginTime, this.form.endTime, 'day')
        .then((response) => {
          this.chartData = response.data.data
          this.loading = false
          this.queryButton = false
          if (response.data.data.length == 0) {
            this.isNoData = true
            return
          }
          // åˆ†æžæ•°æ®ä¸­çš„æœ€æ—©æ—¶é—´
          let begin = this.chartData[0].lst
          // åˆ†æžæ•°æ®ä¸­çš„æœ€æ™šæ—¶é—´
          let end = this.chartData[this.chartData.length - 1].lst
          // ç§»é™¤ç©ºæ•°æ®çŠ¶æ€
          this.isNoData = false
          // æ— æ•°æ®çš„æ—¶é—´æ®µ
          let noDataTimeInteval = lineChart.backNoDataInteval(begin, end)
          // æ— æ•°æ®é…ç½®æ—¶é—´æ®µ
          this.areaColor = lineChart.getMarkArea(noDataTimeInteval)
          this.setChart()
          //  æŠ˜çº¿å›¾æ•°æ®
          let temp = index.calBillData(this.chartData, begin, end)
          this.bill.min = temp['min']
          this.bill.max = temp['max']
          this.bill.avg = temp['avg']
          this.bill.online = temp['online']
          this.bill.valid = temp['valid']
          this.bill.exceeding = temp['exceeding']
        })
    },
    // ä¼ä¸šå¼‚常统计数据
    fetchExceptionAnalysisData() {
      exceptionApi
        .exceptiondata1({
          siteName: this.form.name,
          beginTime: this.form.beginTime,
          endTime: this.form.endTime
        })
        .then((res) => {
          let obj = index.calRecur(res.data.data)
          this.bill.exceptionRecurrence = obj['exceptionRecurrence']
          this.bill.exceptionTypeAggregation = obj['exceptionTypeAggregation']
          this.bill.exception = obj['exception']
          this.bill.mutationCount = obj['mutationCount']
          this.bill.exceedingNearCount = obj['exceedingNearCount']
          this.bill.exceedingCriticalDegree = obj['exceedingCriticalDegree']
        })
    },
    // é€‰æ‹©å…¶ä»–值类型时
    setChart() {
      if (this.chartData.length) {
        // æž„建折线图x,y数据
        let obj = lineChart.getLineChartXYData(
          this.chartData,
          this.form.beginTime,
          this.form.endTime
        )
        this.chartData1 = {
          x: obj.xData,
          y: obj.yAvg
        }
        this.chartData2 = {
          x: obj.xData,
          y: obj.yOnline
        }
        this.chartData3 = {
          x: obj.xData,
          y: obj.yValid
        }
        this.chartData4 = {
          x: obj.xData,
          y: obj.yExceed
        }
      }
    },
    // å¾—到前10风险排名清单
    async getRiskRank() {
      let response = await riskApi.queryRiskValue('', this.month, 'month')
      let tableData = riskValue.backComprehensiveRiskTableData(response.data.data)
      this.top_10_sites_with_risk_values = this.getTopRiskData(tableData, 10)
      if (this.top_10_sites_with_risk_values.length != 0) {
        // è¡¨æ ¼æŒ‰é£Žé™©å€¼å€’叙排列
        this.$nextTick(() => {
          this.$refs.table.sort('riskValue', 'descending')
        })
        // ä¿å­˜é£Žé™©å€¼æœ€é«˜çš„站点名称和设备编号
        let temp = []
        temp.push(
          this.top_10_sites_with_risk_values[0].siteName,
          this.top_10_sites_with_risk_values[0].mnCode
        )
        return temp
      }
    },
    /**
     * é™åºæŽ’列,返回降序前num的元素
     * @param: å¯¹è±¡æ•°ç»„,返回的数量
     */
    getTopRiskData(arr, num) {
      // æŒ‰ç…§riskValue降序排列
      arr.sort((a, b) => b.riskValue - a.riskValue)
      // èŽ·å–å‰num个元素
      return arr.slice(0, num)
    },
    /**
     * æ ¹æ®è®¾å¤‡ç¼–号查询站点基本信息
     * @param: è®¾å¤‡ç¼–号
     */
    getSiteInfo(mnCode) {
      siteInfo.querySiteInfoByMnCode(mnCode).then((response) => {
        this.siteInfo = response.data.data[0]
      })
    },
    openDetail() {
      const encodedSiteName = encodeURIComponent(this.form.name)
      const timeType = '1'
      const jumpPage = '2'
      this.$router.push(`/exceptionDetail/${encodedSiteName}/${this.month}/${timeType}/${jumpPage}`)
    }
  }
}
</script>
<template>
  <el-form :inline="true" :model="form">
    <el-form-item class="form-item">
      <AreaAndmonitorType></AreaAndmonitorType>
    </el-form-item>
    <el-form-item class="form-item">
      <InputSearch
        :site-name="form.name"
        isNeedDefaultSite="0"
        @submit-value="(n) => (form.name = n)"
        @submit-mncode="(n) => (form.number = n)"
      ></InputSearch>
    </el-form-item>
    <el-form-item v-show="showAll">
      <MonthSelect @submit-value="giveMonth"></MonthSelect>
    </el-form-item>
    <el-form-item v-show="showAll">
      <ButtonClick
        content="风险评估"
        type="primary"
        :loading="queryButton"
        @do-search="riskAssessment"
      ></ButtonClick>
    </el-form-item>
  </el-form>
  <div v-loading="screenLoading" class="wait-name">
    <div class="chart-container" v-show="!isNoData && !screenLoading">
      <el-card class="time-text">
        <h4>{{ form.name }}</h4>
        <br />
        <br />
        <span>数据统计时段:{{ form.beginTime }} ~ {{ form.endTime }}</span>
        <el-tag class="mx-1">场景</el-tag>{{ siteInfo.typename }}
        <el-tag class="mx-1">运维商</el-tag>{{ siteInfo.dutyCompany }}
        <el-button type="primary" size="default" class="exception-button" v-show="showAll" @click="openDetail">
          æ•°æ®å¼‚常详情
        </el-button>
      </el-card>
      <el-row :gutter="10">
        <el-col :span="5" v-show="showAll">
          <el-card shadow="never" class="table-class">
            <el-table
              ref="table"
              :highlight-current-row="true"
              :data="top_10_sites_with_risk_values"
              :default-sort="{ prop: 'riskValue', order: 'descending' }"
              height="540"
            >
              <el-table-column
                type="index"
                label="序号"
                fixed
                width="52"
                show-overflow-tooltip
                align="center"
              />
              <el-table-column
                prop="siteName"
                label="点位名称"
                show-overflow-tooltip
                width="99"
                align="center"
              >
                <template #default="{ row }">
                  <el-button
                    type="primary"
                    text
                    class="table-button"
                    @click="querySiteStaticsInfo(row)"
                  >
                    <span class="risk-rank-site">
                      {{ row.siteName }}
                    </span>
                  </el-button>
                </template>
              </el-table-column>
              <el-table-column
                prop="riskValue"
                label="风险值"
                sortable
                show-overflow-tooltip
                align="center"
              />
            </el-table>
          </el-card>
        </el-col>
        <el-col :span="11">
          <el-card shadow="never" class="table-class">
            <DustRadarChart
              :name="[
                '数据有效风险',
                '异常复现风险',
                '异常类型聚集风险',
                '超标异常风险',
                '数据在线风险'
              ]"
              :yData="exceptionRisk"
            ></DustRadarChart>
          </el-card>
        </el-col>
        <el-col :span="4">
          <el-card shadow="never" class="card-height risk-card">
            <template #header>
              <h1
                :class="{
                  'weightColor-low': weight < 0.15,
                  'weightColor-medium': weight >= 0.15 && weight <= 0.6,
                  'weightColor-heigh': weight > 0.6
                }"
              >
                é£Žé™©å€¼(0~1):{{ weight }}
              </h1>
            </template>
            <div class="risk-text-container">
              <div class="risk-grade">
                <h1 class="sub-title">风险等级:</h1>
                <span class="sub-title">{{ riskGradeAndAdvice.riskGrade }} </span>
              </div>
              <div class="risk-advice">
                <h1 class="sub-title">管控建议:</h1>
                <div
                  v-for="item in riskGradeAndAdvice.riskAdvice"
                  :key="item"
                  class="risk-advice-text"
                >
                  {{ item }}
                </div>
              </div>
              <div class="grade-instance">
                <div class="container">
                  <div class="block-color heigh"></div>
                  <div>高风险(>0.6)</div>
                </div>
                <div class="container">
                  <div class="block-color medium"></div>
                  <div>中风险(0.15~0.6)</div>
                </div>
                <div class="container">
                  <div class="block-color low"></div>
                  <div>低风险(<0.15)</div>
                </div>
              </div>
            </div>
          </el-card>
        </el-col>
        <el-col :span="4">
          <el-card shadow="never" class="card-height">
            <template #header>
              <span class="title-16">风险详情</span>
            </template>
            <el-form>
              <el-form-item label="最大值:"> {{ bill.max }} mg/m³ </el-form-item>
              <el-form-item label="最小值:"> {{ bill.min }} mg/m³ </el-form-item>
              <el-form-item label="数据有效率:"> {{ bill.online }}% </el-form-item>
              <el-form-item label="数据在线率:"> {{ bill.valid }}% </el-form-item>
              <el-form-item label="数据超标率:"> {{ bill.exceeding }}% </el-form-item>
              <el-form-item label="异常类型聚集度:">
                {{ exceptionRisk.exceptionTypeAggregation * 100 }}%
              </el-form-item>
              <el-tag :size="small">共出现了{{ bill.exception.length }}类异常</el-tag>
              <el-form-item label="典型异常复现率:">
                {{ exceptionRisk.typicalExceptionRepetitionRate * 100 }}%
              </el-form-item>
              <div>
                <el-tag :size="small">量级突变异常:{{ bill.mutationCount }}条</el-tag>
              </div>
              <div>
                <el-tag :size="small">临近超标异常:{{ bill.exceedingNearCount }}条</el-tag>
              </div>
              <div>
                <el-tag :size="small"
                  >单日超标次数临界异常:{{ bill.exceedingCriticalDegree }}条</el-tag
                >
              </div>
            </el-form>
          </el-card>
        </el-col>
      </el-row>
      <el-row :gutter="20">
        <el-col :span="12">
          <el-card shadow="never" class="card-value">
            <LineChart
              title="日均值"
              :chartData="chartData1"
              yName="mg/m³"
              seriesName="日均值"
              :areaColor="areaColor"
            >
            </LineChart>
          </el-card>
        </el-col>
        <el-col :span="12">
          <el-card shadow="never" class="card-value">
            <LineChart
              title="日有效率"
              :chartData="chartData3"
              yName="%"
              seriesName="日有效率"
              :areaColor="areaColor"
            >
            </LineChart>
          </el-card>
        </el-col>
      </el-row>
    </div>
  </div>
  <el-empty description="暂无数据" v-show="isNoData" :image-size="200" />
</template>
<style scoped>
.el-form {
  margin: 10px;
}
.form-item {
  margin-top: 10px;
}
.chart-container {
  margin-left: 10px;
}
.time-text {
  font-size: 14px;
  color: #333333;
  letter-spacing: 1px;
}
.el-card {
  margin-top: 15px;
  border-radius: 9px;
}
.chart-container {
  width: 98%;
  /* height: 600px; */
}
.card-height {
  height: 570px;
}
.el-header {
  background-color: #010408;
  color: #333;
  line-height: 60px;
}
.risk-advice {
  /* margin: 20px 0px; */
}
.container {
  display: flex;
  margin-bottom: 10px;
}
.grade-instance {
  /* margin-top: 50px; */
}
.block-color {
  width: 1em;
  height: 1em;
  margin-right: 10px;
  margin-top: 3px;
}
.heigh {
  background-color: red;
}
.medium {
  background-color: #fadc19;
}
.low {
  background-color: #9fdb1d;
}
.el-text {
  align-self: left;
}
.el-form-item {
  margin-bottom: 20px;
}
:deep().el-form-item__content {
  justify-content: flex-end;
}
.title-16 {
  font-size: 16px;
  font-weight: bold;
}
.weightColor-low {
  color: #9fdb1d;
  font-size: 16px;
}
.weightColor-medium {
  color: #dabe09;
  font-size: 16px;
}
.weightColor-heigh {
  color: red;
  font-size: 16px;
}
.risk-grade {
  display: flex;
}
:deep().el-table__header-wrapper {
  color: red;
}
/* .wait-name {
        width: 500px;
        height: 600px;
      } */
.table-class {
  /* border: 1px solid blue; */
  /* margin: 20px 0px 20px 0px; */
  height: 570px;
}
.table-button {
  letter-spacing: 1px;
  text-decoration: underline;
  /* border-radius: 0px; */
}
.risk-rank-site {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  width: 80px;
}
.site-name {
  margin-left: 20px;
}
.risk-advice-text {
  font-size: 14px;
  color: #333333;
  letter-spacing: 1.5px;
  margin-top: 10px;
}
.sub-title {
  font-size: 14px;
  color: #333333;
}
.risk-text-container {
  height: 490px;
  display: flex;
  flex-direction: column;
  justify-content: space-around;
}
.el-tag {
  margin-left: 25px;
  font-size: 14px;
  vertical-align: baseline;
}
.exception-button {
  vertical-align: baseline;
  margin-left: 150px;
}
.site-info-detail {
  display: flex;
  justify-content: space-between;
}
.mx-1 {
  margin-left: 100px;
}
</style>
src/views/risk_assessment/components/DustRadarChart.vue
@@ -55,6 +55,8 @@
    }
  },
  methods: {
    initRadarChart() {
      this.chart = echarts.init(document.getElementById('main'));
    },
src/views/risk_assessment/components/SiteDetail.vue
@@ -1,15 +1,21 @@
<!--点击站点 è·³è½¬è‡³é£Žé™©æ¨¡åž‹é¡µé¢  -->
<script>
import CompFlightInspection from '@/views/exception/components/CompFlightInspection.vue'
import CompDataRiskModel from '@/views/risk_assessment/components/CompDataRiskModel.vue'
export default {
  components: {
    CompFlightInspection
    CompFlightInspection,
    CompDataRiskModel
  },
  data() {
    return {
      siteName: '',
      month: '',
      time: '',
      // æ—¶é—´ç±»åž‹
      timeType: '',
      //  1代表风险模型 2代表飞行巡检
      jumpPage: -1
    }
  },
  watch: {},
@@ -18,9 +24,11 @@
    next((vm) => {
      // é€šè¿‡ `vm` è®¿é—®ç»„件实例
      vm.siteName = to.params.siteName
      vm.month = to.params.month
      vm.$nextTick(()  =>  {
     })
      vm.time = to.params.time
      vm.timeType = to.params.timeType
      vm.jumpPage = to.params.jumpPage
      vm.$nextTick(() => {})
    })
  },
  methods: {
@@ -35,12 +43,24 @@
<template>
  <el-page-header @back="onBack">
    <template #content>
      <span>  å¼‚常详情  </span>
      <span v-if="jumpPage == '1'"> é£Žé™©æ¨¡åž‹ </span>
      <span v-else-if="jumpPage == '2'"> å¼‚常详情 </span>
    </template>
  </el-page-header>
  <CompFlightInspection :site-name="siteName" :month="month" :show-all="false"> </CompFlightInspection>
  <div v-show="jumpPage == '1'">
    <CompDataRiskModel :site-name="siteName" :time="time" :show-all="false"></CompDataRiskModel>
  </div>
  <div v-show="jumpPage == '2'">
    <CompFlightInspection
      :site-name="siteName"
      :time="time"
      :time-type="timeType"
      :show-all="false"
    >
    </CompFlightInspection>
  </div>
</template>
<style scoped>
src/views/risk_assessment/components/subRiskModel.vue
@@ -7,8 +7,9 @@
<script>
// import InputSearch from '@/sfc/InputSearch.vue'
import AreaAndmonitorType from '@/sfc/AreaAndmonitorType.vue'
import DustRadarChart from '@/views/risk_assessment/components/DustRadarChart.vue'
import exceptionApi from '@/api/exceptionApi.js'
import DustRadarChart from '@/views/risk_assessment/components/DustRadarChart.vue'
import LineChart from '@/views/risk_assessment/components/LineChart.vue'
import index from '@/utils/risk_estimate_common_function/index.js'
import ButtonClick from '@/sfc/ButtonClick.vue'