import dayjs from 'dayjs'
|
// import exceptionApi from '../../api/exceptionApi';
|
export default {
|
/**
|
* 计算日期相差几天
|
* @param:
|
* @createTime:开始时间,结束时间
|
* @returns:
|
*/
|
getDaysDifference(startDate, endDate) {
|
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 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 = {}
|
// 计算最小和大值
|
arr.forEach((item) => {
|
if (item.min < min) {
|
min = item.min
|
}
|
if (item.max > 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))
|
|
sumOnline = sumOnline + Number(item.dayOnline)
|
sumValid = sumValid + Number(item.dayValid)
|
sumExceeding = sumExceeding + Number(item.dayExceeding)
|
})
|
// 计算均值
|
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)
|
|
return obj
|
},
|
|
/**
|
* 计算异常类型聚集度:该时段出现的异常类型数量除8
|
* 异常复现率: 量级突变,超标临近和超标次数临界在该时段出现的累计复现此次除3(比如量级突变出现3次,算作复现2次)
|
* @param: 异常数据数组
|
* @returns:
|
*/
|
calRecur(exceptionArr) {
|
if (exceptionArr.length == 0) {
|
let obj = {}
|
obj['exceptionRecurrence'] = 0
|
obj['exceptionTypeAggregation'] = 0
|
|
return obj
|
}
|
|
// 量级突变
|
let mutationCount = 0
|
// 超标临近
|
let exceedingNearCount = 0
|
// 超标次数临界
|
let exceedingCriticalDegree = 0
|
|
// 保存出现的不同异常类型
|
let exception = []
|
// 异常类型聚集度
|
let exceptionTypeAggregation = 0
|
// 典型异常复现率
|
let exceptionTyprRecurRate = 0
|
// 记录指定3种异常出现的次数和不同的异常种类
|
exceptionArr.forEach((item) => {
|
// 量级突变异常
|
if (item.exceptionType == 4) {
|
mutationCount++
|
// 临近超标异常
|
} else if (item.exceptionType == 5) {
|
exceedingNearCount++
|
// 单日超标次数临界异常
|
} else if (item.exceptionType == 6) {
|
exceedingCriticalDegree++
|
}
|
|
// 异常类型聚集度
|
if (exception.length == 0) {
|
exception.push(item.exceptionType)
|
}
|
// 保存新的异常类型 数据超低、长时间无波动等两类异常暂不纳入分析
|
else if ( item.exceptionType!='1' && item.exceptionType!='3' && exception.indexOf(item.exceptionType) == -1) {
|
exception.push(item.exceptionType)
|
}
|
})
|
|
let sum = 0
|
// 次数减1,该异常出现2次,算复现1次。出现3次,算复现2次...
|
if (mutationCount > 1) {
|
sum = sum + mutationCount - 1
|
}
|
if (exceedingNearCount > 1) {
|
sum = sum + exceedingNearCount - 1
|
}
|
if (exceedingCriticalDegree > 1) {
|
sum = sum + exceedingCriticalDegree - 1
|
}
|
|
switch (true) {
|
case sum == 0 || sum == 1:
|
exceptionTyprRecurRate = (sum / 3).toFixed(2)
|
break
|
case sum == 2 || sum >= 3:
|
exceptionTyprRecurRate = 1
|
break
|
default:
|
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 []
|
}
|
|
let temp = []
|
exceptionData.forEach((res) => {
|
if (res.mnCode == value) {
|
temp.push(res)
|
}
|
})
|
return temp
|
},
|
|
/**
|
* 计算风险值
|
* @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 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
|
}
|
}
|