zmc
2023-11-16 73cb3ec2b1660610e3621d7614ad308f2c19331d
src/utils/risk_estimate_common_function/index.js
@@ -1,4 +1,4 @@
import dayjs from 'dayjs';
import dayjs from 'dayjs'
// import exceptionApi from '../../api/exceptionApi';
export default {
  /**
@@ -8,7 +8,7 @@
   * @returns:
   */
  getDaysDifference(startDate, endDate) {
    return dayjs(endDate).diff(startDate, 'day') + 1;
    return dayjs(endDate).diff(startDate, 'day') + 1
  },
  /**
@@ -17,55 +17,52 @@
   * @returns:
   */
  calBillData(arr, beginTime, endTime) {
    let min = 65536;
    let max = -1;
    let avg = 0;
    let online = 0;
    let valid = 0;
    let exceeding = 0;
    let min = 65536
    let max = -1
    let avg = 0
    let online = 0
    let valid = 0
    let exceeding = 0
    let sumAvg = 0;
    let sumOnline = 0;
    let sumValid = 0;
    let sumExceeding = 0;
    let sumAvg = 0
    let sumOnline = 0
    let sumValid = 0
    let sumExceeding = 0
    // 计算选择的时间的相差的天数
    let begin = dayjs(beginTime).format('YYYY-MM-DD');
    let end = dayjs(endTime).format('YYYY-MM-DD');
    let dayDiff = this.getDaysDifference(begin, end);
    let obj = {};
    let begin = dayjs(beginTime).format('YYYY-MM-DD')
    let end = dayjs(endTime).format('YYYY-MM-DD')
    let dayDiff = this.getDaysDifference(begin, end)
    let obj = {}
    // 计算最小和大值
    arr.forEach((item) => {
      if (item.min < min) {
        min = item.min;
        min = item.min
      }
      if (item.max > max) {
        max = item.max;
        max = item.max
      }
      // 计算平均值,在线率,有效率,超标率
      sumAvg = sumAvg + item.dayAvg;
      sumOnline = sumOnline + Number(item.dayOnline.slice(0, -1));
      sumValid = sumValid + Number(item.dayValid.slice(0, -1));
      sumExceeding = sumExceeding + Number(item.dayExceeding.slice(0, -1));
    });
      sumAvg = sumAvg + item.dayAvg
      sumOnline = sumOnline + Number(item.dayOnline.slice(0, -1))
      sumValid = sumValid + Number(item.dayValid.slice(0, -1))
      sumExceeding = sumExceeding + Number(item.dayExceeding.slice(0, -1))
    })
    // 计算均值
    avg = sumAvg / dayDiff;
    online = sumOnline / dayDiff;
    valid = sumValid / dayDiff;
    exceeding = sumExceeding / dayDiff;
    obj['min'] = min.toFixed(3);
    obj['max'] = max.toFixed(3);
    avg = sumAvg / dayDiff
    online = sumOnline / dayDiff
    valid = sumValid / dayDiff
    exceeding = sumExceeding / dayDiff
    obj['min'] = min.toFixed(3)
    obj['max'] = max.toFixed(3)
    obj['avg'] = avg.toFixed(2);
    obj['online'] = online.toFixed(2);
    obj['valid'] = valid.toFixed(2);
    obj['exceeding'] = exceeding.toFixed(2);
    obj['avg'] = avg.toFixed(2)
    obj['online'] = online.toFixed(2)
    obj['valid'] = valid.toFixed(2)
    obj['exceeding'] = exceeding.toFixed(2)
    return obj;
    return obj
  },
  /**
   * 计算异常类型聚集度:该时段出现的异常类型数量除8
@@ -74,163 +71,165 @@
   * @returns:
   */
  calRecur(exceptionArr) {
    if(exceptionArr.length == 0){
      let obj = {};
      obj['exceptionRecurrence'] = 0;
      obj['exceptionTypeAggregation'] = 0;
    if (exceptionArr.length == 0) {
      let obj = {}
      obj['exceptionRecurrence'] = 0
      obj['exceptionTypeAggregation'] = 0
      return obj;
      return obj
    }
    // 典型异常复现率
    let exceptionTyprRecurRate = 0;
    // 量级突变
    let mutationCount = 0;
    let mutationCount = 0
    // 超标临近
    let exceedingNearCount = 0;
    let exceedingNearCount = 0
    // 超标次数临界
    let exceedindCriticalDegree = 0;
    let exceedingCriticalDegree = 0
    // 保存出现的不同异常类型
    let exception = [];
    let exception = []
    // 异常类型聚集度
    let exceptionTypeAggregation = 0;
    let exceptionTypeAggregation = 0
    // 典型异常复现率
    let exceptionTyprRecurRate = 0
    // 记录指定3种异常出现的次数和不同的异常种类
    exceptionArr.forEach((item) => {
      // 异常复现率
      // 量级突变异常
      if (item.exceptionType == 4) {
        mutationCount++;
        mutationCount++
        // 临近超标异常
      } else if (item.exceptionType == 5) {
        exceedingNearCount++;
        exceedingNearCount++
        // 单日超标次数临界异常
      } else if (item.exceptionType == 6) {
        exceedindCriticalDegree++;
        exceedingCriticalDegree++
      }
      // 异常类型聚集度
      if (exception.length == 0) {
        exception.push(item.exceptionType);
        exception.push(item.exceptionType)
      }
      // 保存新的异常类型
      else if (exception.indexOf(item.exceptionType) == -1) {
        exception.push(item.exceptionType);
        exception.push(item.exceptionType)
      }
    });
    })
    let sum = 0;
    let sum = 0
    // 次数减1,该异常出现2次,算复现1次。出现3次,算复现2次...
    if (mutationCount > 1) {
      sum = sum + mutationCount - 1;
      sum = sum + mutationCount - 1
    }
    if (exceedingNearCount > 1) {
      sum = sum + exceedindCriticalDegree - 1;
      sum = sum + exceedingNearCount - 1
    }
    if (exceedindCriticalDegree > 1) {
      sum = sum + exceedindCriticalDegree - 1;
    if (exceedingCriticalDegree > 1) {
      sum = sum + exceedingCriticalDegree - 1
    }
    switch (sum) {
      case 0:
        exceptionTyprRecurRate = sum / 3;
        break;
      case 1:
        exceptionTyprRecurRate = sum / 3;
        break;
      case 2:
      case sum >= 3:
        exceptionTyprRecurRate = 1;
        break;
    switch (true) {
      case sum == 0 || sum == 1:
        exceptionTyprRecurRate = (sum / 3).toFixed(2)
        break
      case sum == 2 || sum >= 3:
        exceptionTyprRecurRate = 1
        break
      default:
        return 'error';
        return 'error'
    }
    exceptionTypeAggregation = exception.length / 8;
    exceptionTypeAggregation = (exception.length / 8).toFixed(2)
    let obj = {};
    obj['exceptionRecurrence'] = exceptionTyprRecurRate;
    obj['exceptionTypeAggregation'] = exceptionTypeAggregation;
    let obj = {}
    obj['exceptionRecurrence'] = exceptionTyprRecurRate
    obj['exceptionTypeAggregation'] = exceptionTypeAggregation
    return obj;
},
// 参数:对象数组(该对象中的属性不能是引用类型,否则拷贝的值还是会相互影响)
    // 功能:拷贝该对象数组。
shallowCopyList(val) {
  if(val == 'arr'){
    let tempList = [];
    return tempList;
  }else if(val == 'obj'){
    let tempList = {};
    return tempList;
  }
},
getRate(obj){
  let a = {}
  a.online = obj['dayOnline']
  a.valid = obj['dayValid']
  a.exceeding = obj['dayExceeding']
  return a
},
/**
 * 找到对象数组中属性mnCode为value的对象 添加进数组中
 * @param: 对象数组 ,mnCode等于value
 * @returns:
 */
findValue(exceptionData,value){
  if(exceptionData.length==0){
    return []
  }
  let temp = []
  exceptionData.forEach((res)=>{
    if(res.mnCode == value){
      temp.push(res)
    return obj
  },
  // 参数:对象数组(该对象中的属性不能是引用类型,否则拷贝的值还是会相互影响)
  // 功能:拷贝该对象数组。
  shallowCopyList(val) {
    if (val == 'arr') {
      let tempList = []
      return tempList
    } else if (val == 'obj') {
      let tempList = {}
      return tempList
    }
  })
  return temp
},
  },
  getRate(obj) {
    let a = {}
    a.online = obj['dayOnline']
    a.valid = obj['dayValid']
    a.exceeding = obj['dayExceeding']
    return a
  },
/**
 * 计算风险值
 * @param: 数组。依次是在线率,有效率,超标率,异常类型聚集度,异常复现率
 * @returns:
 */
calRiskValue(arr){
  // 用100减 是因为该属性需要计算的是风险值,应当是离线率,无效率
  // 乘以0.01是因为去除百分号后需要再缩小100倍
  let weight = (
    (100 - parseFloat(arr[0].slice(0, -1)))*0.01 * 0.1 +
    (100 - parseFloat(arr[1].slice(0, -1)))*0.01 * 0.2 +
    parseFloat(arr[2].slice(0, -1))*0.01 * 0.2 +
    arr[3] * 0.2 +
    arr[4] * 0.3
  ).toFixed(2)
  return weight
},
  /**
   * 找到对象数组中属性mnCode为value的对象 添加进数组中
   * @param: 对象数组 ,mnCode等于value
   * @returns:
   */
  findValue(exceptionData, value) {
    if (exceptionData.length == 0) {
      return []
    }
/**
 * 对分析值和异常值计算风险值
 * @param: 分析数据,异常数据,开始时间,结束时间
 * @returns:表格数据
 */
merge(anaData,exceptionData,beginTime,endTime){
    let temp = []
    exceptionData.forEach((res) => {
      if (res.mnCode == value) {
        temp.push(res)
      }
    })
    return temp
  },
  if (anaData.length == 0){
    return []
  }
  const table = []
  let i = 0
  anaData.forEach((res) =>{
  /**
   * 计算风险值
   * @param: 数组。依次是在线率,有效率,超标率,异常类型聚集度,异常复现率
   * @returns:
   */
  calRiskValue(arr) {
    // 用100减 是因为该属性需要计算的是风险值,应当是离线率,无效率
    // 乘以0.01是因为去除百分号后需要再缩小100倍
    /* arr[0]:在线率 90%
     arr[1]:有效率 100%
     arr[2]:超标率 2%
     arr[3]:典型异常复现风险 0.2
     arr[4]:异常类型聚集风险  0.5
  */
    let weight = (
      (100 - parseFloat(arr[0].slice(0, -1))) * 0.01 * 0.1 +
      (100 - parseFloat(arr[1].slice(0, -1))) * 0.01 * 0.2 +
      parseFloat(arr[2].slice(0, -1)) * 0.01 * 0.2 +
      arr[3] * 0.2 +
      arr[4] * 0.3
    ).toFixed(2)
    return weight
  },
  /**
   * 对分析值和异常值计算风险值
   * @param: 分析数据,异常数据,开始时间,结束时间
   * @returns:表格数据
   */
  merge(anaData, exceptionData, beginTime, endTime) {
    if (anaData.length == 0) {
      return []
    }
    const table = []
    let i = 0
    anaData.forEach((res) => {
      // 从分析数据中得到设备编号
      let mnCode = res.mnCode
      // 找到异常数据中mnCode等于value的对象
      let d = this.findValue(exceptionData,mnCode)
      let d = this.findValue(exceptionData, mnCode)
      // let temp = [...res,...d]
      // 计算在线,有效率,超标率
      let r1 = this.getRate(res, beginTime, endTime)
      // 计算复现率
      let r2 = this.calRecur(d)
      i = i + 1
@@ -251,23 +250,23 @@
      obj.region = '金山区'
      obj.monitorType = '扬尘'
      obj.siteName = res.name
      obj.mnCode = res.mnCode
      obj.beginTime = beginTime
      obj.endTime = endTime
      obj.riskValue = weight
      if (weight >= 0.6) {
        obj.riskGrage = '高风险'
        obj.riskAdvice = '建议对该站点进行线下执法检查,专项数据对比'
        obj.riskAdvice = '1.若不涉及超标或在线率、有效率异常,常态数据审核即可;\n2.若涉及超标或在线率、有效率等异常,建议通过守法服务小程序、监测监管微信群等线上方式提示站点所属单位,及时开展自查自纠;'
      } else if (weight < 0.6 && weight >= 0.2) {
        obj.riskGrage = '中风险'
        obj.riskAdvice = '建议开展常态追踪分析'
        obj.riskAdvice = '1.建议通过守法服务小程序、监测监管微信群等线上方式提示站点所属单位,聚焦当前存在的问题或隐患,及时开展自查自纠;\n2.若同时存在在线率或有效率月度不达标,建议电话通知该站点所属单位进行应急维护,并进行专项审核;'
      } else {
        obj.riskGrage = '低风险'
        obj.riskAdvice = '建议引导企业长态保持'
        obj.riskAdvice = '1.建议及时提醒该站点所属单位进行应急维护;\n2.若同时存在超标、临界超标、量级突变等异常时,建议将该站点移交环境执法大队开展现场执法检查;\n3.若持续两月及以上为高风险,建议将该站点纳入年度抽测比对清单;'
      }
      table.push(obj)
    })
    return table
  }
}
}