| | |
| | | import dayjs from 'dayjs'; |
| | | import dayjs from 'dayjs' |
| | | // import exceptionApi from '../../api/exceptionApi'; |
| | | export default { |
| | | /** |
| | | * 计算日期相差几天 |
| | |
| | | * @returns: |
| | | */ |
| | | getDaysDifference(startDate, endDate) { |
| | | return dayjs(endDate).diff(startDate, 'day') + 1; |
| | | return dayjs(endDate).diff(startDate, 'day') + 1 |
| | | }, |
| | | |
| | | /** |
| | | * 从分析数据数组中计算最小和大值 ,平均值, 在线率,有效率,超标率(后三个值为0~100取值) |
| | | * @param:分析表中的数据 |
| | | * @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); |
| | | console.log('日期间隔', dayDiff); |
| | | 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; |
| | | // console.log('sumavg:',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 |
| | | * 异常复现率: 量级突变,超标临近和超标次数临界在该时段出现的累计复现此次除3(比如量级突变出现3次,算作复现2次) |
| | | * @param: 异常数据数组 |
| | | * @returns: |
| | | */ |
| | | calRecur(exceptionArr) { |
| | | // 典型异常复现率 |
| | | let exceptionTyprRecurRate = 0; |
| | | if (exceptionArr.length == 0) { |
| | | let obj = {} |
| | | obj['exceptionRecurrence'] = 0 |
| | | obj['exceptionTypeAggregation'] = 0 |
| | | |
| | | return obj |
| | | } |
| | | |
| | | // 量级突变 |
| | | 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); |
| | | // 保存新的异常类型 数据超低、长时间无波动等两类异常暂不纳入分析 |
| | | else if ( item.exceptionType!='1' && item.exceptionType!='3' && exception.indexOf(item.exceptionType) == -1) { |
| | | 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 |
| | | } |
| | | // console.log('sum:', sum); |
| | | // console.log('exception:', exception); |
| | | // console.log( |
| | | // '其他', |
| | | // mutationCount, |
| | | // exceedindCriticalDegree, |
| | | // exceedindCriticalDegree |
| | | // ); |
| | | 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 / 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) { |
| | | 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 [] |
| | | } |
| | | |
| | | exceptionTypeAggregation = exception.length / 8; |
| | | let temp = [] |
| | | exceptionData.forEach((res) => { |
| | | if (res.mnCode == value) { |
| | | temp.push(res) |
| | | } |
| | | }) |
| | | return temp |
| | | }, |
| | | |
| | | let obj = {}; |
| | | obj['exceptionRecurrence'] = exceptionTyprRecurRate; |
| | | obj['exceptionTypeAggregation'] = exceptionTypeAggregation; |
| | | /** |
| | | * 计算风险值 |
| | | * @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 obj; |
| | | 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 temp = [...res,...d] |
| | | |
| | | // 计算在线,有效率,超标率 |
| | | let r1 = this.getRate(res, beginTime, endTime) |
| | | |
| | | // 计算复现率 |
| | | let r2 = this.calRecur(d) |
| | | i = i + 1 |
| | | // 数组的拷贝 防止地址引用 |
| | | let temp = this.shallowCopyList('arr') |
| | | temp.push(r1['online']) |
| | | temp.push(r1['valid']) |
| | | temp.push(r1['exceeding']) |
| | | temp.push(r2['exceptionRecurrence']) |
| | | temp.push(r2['exceptionTypeAggregation']) |
| | | // 计算风险值 |
| | | let weight = this.calRiskValue(temp) |
| | | |
| | | // 对象的拷贝 防止地址引用 |
| | | let obj = this.shallowCopyList('obj') |
| | | |
| | | // 构成表格的一行 |
| | | 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 = '1.若不涉及超标或在线率、有效率异常,常态数据审核即可;\n2.若涉及超标或在线率、有效率等异常,建议通过守法服务小程序、监测监管微信群等线上方式提示站点所属单位,及时开展自查自纠;' |
| | | } else if (weight < 0.6 && weight >= 0.2) { |
| | | obj.riskGrage = '中风险' |
| | | obj.riskAdvice = '1.建议通过守法服务小程序、监测监管微信群等线上方式提示站点所属单位,聚焦当前存在的问题或隐患,及时开展自查自纠;\n2.若同时存在在线率或有效率月度不达标,建议电话通知该站点所属单位进行应急维护,并进行专项审核;' |
| | | } else { |
| | | obj.riskGrage = '低风险' |
| | | obj.riskAdvice = '1.建议及时提醒该站点所属单位进行应急维护;\n2.若同时存在超标、临界超标、量级突变等异常时,建议将该站点移交环境执法大队开展现场执法检查;\n3.若持续两月及以上为高风险,建议将该站点纳入年度抽测比对清单;' |
| | | } |
| | | table.push(obj) |
| | | }) |
| | | |
| | | return table |
| | | } |
| | | }; |
| | | } |