@@ -69,25 +84,17 @@ export default {
roomId: '01A1DC2123C2B75E1A579D',
allDisplayConfigData: [],
displayConfigData: [],
+ originalAllDeviceIds: [],
allDeviceIds: [],
currentIpIndex: 0,
excludeIpList: [
'192.168.99.101:6003'
],
- oaoMessage: [],
timer: '',
- topDisplayData: {
- DAK_DIV_TOP_001: { show: true, curValue: '23.10', unit: '℃', curstatus: 0 },
- DAK_DIV_TOP_002: { show: true, curValue: '48.90', unit: '%', curstatus: 0 },
- DAK_DIV_TOP_003: { show: true, curValue: '619', unit: 'ppm', curstatus: 0 },
- DAK_DIV_TOP_004: { show: true, curValue: '0.21', unit: 'mg/m³', curstatus: 0 },
- DAK_DIV_TOP_005: { show: true, curValue: '26.00', unit: 'ug/m³', curstatus: 0 },
- DAK_DIV_TOP_006: { show: true, curValue: '38.00', unit: 'ug/m³', curstatus: 0 }
- },
open: false,
newAlarm: [],
aqiValue: 45,
- aqiStatus: '健康',
+ aqiStatus: '优',
keepIndicators: [
'二氧化碳',
'甲醛',
@@ -98,17 +105,47 @@ export default {
'湿度',
'空气质量'
],
+ aqiGradeStandard: [
+ { aqiMin: 0, aqiMax: 50, level: '优', colorKey: 'excellent' },
+ { aqiMin: 51, aqiMax: 100, level: '良', colorKey: 'good' },
+ { aqiMin: 101, aqiMax: 150, level: '轻度污染', colorKey: 'lightPollution' },
+ { aqiMin: 151, aqiMax: 200, level: '中度污染', colorKey: 'mediumPollution' },
+ { aqiMin: 201, aqiMax: 300, level: '重度污染', colorKey: 'heavyPollution' },
+ { aqiMin: 301, aqiMax: 500, level: '严重污染', colorKey: 'severePollution' }
+ ],
+ aqiBpTable: {
+ pm25: [
+ { iaqiLo: 0, iaqiHi: 50, bpLo: 0, bpHi: 35 }, // 优
+ { iaqiLo: 50, iaqiHi: 100, bpLo: 35, bpHi: 75 }, // 良
+ { iaqiLo: 100, iaqiHi: 150, bpLo: 75, bpHi: 115 }, // 轻度污染
+ { iaqiLo: 150, iaqiHi: 200, bpLo: 115, bpHi: 150 }, // 中度污染
+ { iaqiLo: 200, iaqiHi: 300, bpLo: 150, bpHi: 250 }, // 重度污染
+ { iaqiLo: 300, iaqiHi: 500, bpLo: 250, bpHi: 500 } // 严重污染
+ ],
+ pm10: [
+ { iaqiLo: 0, iaqiHi: 50, bpLo: 0, bpHi: 50 }, // 优
+ { iaqiLo: 50, iaqiHi: 100, bpLo: 50, bpHi: 150 }, // 良
+ { iaqiLo: 100, iaqiHi: 150, bpLo: 150, bpHi: 250 }, // 轻度污染
+ { iaqiLo: 150, iaqiHi: 200, bpLo: 250, bpHi: 350 }, // 中度污染
+ { iaqiLo: 200, iaqiHi: 300, bpLo: 350, bpHi: 420 }, // 重度污染
+ { iaqiLo: 300, iaqiHi: 500, bpLo: 420, bpHi: 500 } // 严重污染
+ ]
+ },
// 新增:存储IP到设备名称的映射
ipToNameMap: {},
// 新增:当前显示的设备名称
- currentDeviceName: ''
+ currentDeviceName: '',
+ aqiTimer: null,
+ // 新增:存储所有设备的PM2.5/PM10数据
+ allDevicesPollutantData: [],
+ hasValidData: false
}
},
async created() {
window.getIframeLoading = this.getIframeLoading
- // 模拟
// this.allDisplayConfigData = allDeviceData
- // 真实请求
+ // this.handleDeviceIpList()
+
await alarmApi.FetchYpGetSite().then((data) => {
if (data && data.length > 0) {
this.allDisplayConfigData = data
@@ -117,15 +154,15 @@ export default {
this.allDisplayConfigData = []
}
})
- // this.allDisplayConfigData = allDeviceData
- // this.handleDeviceIpList()
- // 初始加载+创建定时器
+ await this.getAllDevicesPollutantData()
+ this.calcGlobalAQI()
+
if (this.allDeviceIds.length > 0) {
this.currentDeviceName = this.ipToNameMap[this.allDeviceIds[0]] || ''
await this.getRealTimeData(this.allDeviceIds[0])
- // 移到这里创建定时器
+ // 轮询定时器(仅更新msg-list,完全不碰AQI)
this.timer = setInterval(async() => {
const currentIp = this.getNextIp()
this.currentDeviceName = this.ipToNameMap[currentIp] || ''
@@ -136,47 +173,63 @@ export default {
console.warn('无有效设备IP,停止轮询')
this.newAlarm = []
}
+
+ // 可选:开启AQI定时更新(如需实时刷新全量AQI)
+ // if (this.allDeviceIds.length > 0) {
+ // this.aqiTimer = setInterval(async() => {
+ // await this.getAllDevicesPollutantData()
+ // this.calcGlobalAQI()
+ // }, 30000)
+ // console.log('启动全量AQI计算定时器(30秒/次)')
+ // }
},
mounted() {
const _this = this
_this.iframeWin = this.$refs.myIframe.contentWindow
window.addEventListener('message', this.handleMessageEvent)
-
- // if (this.allDeviceIds.length > 0) {
- // this.timer = setInterval(async() => {
- // const currentIp = _this.getNextIp()
- // // 轮询时更新设备名称
- // _this.currentDeviceName = _this.ipToNameMap[currentIp] || ''
- // await _this.getRealTimeData(currentIp)
- // }, 10000)
- // console.log(`启动IP轮询,共${this.allDeviceIds.length}个有效IP:`, this.allDeviceIds)
- // }
},
beforeDestroy() {
+ // 清理轮询定时器
if (this.timer) {
clearInterval(this.timer)
console.log('停止IP轮询')
}
+ // 清理AQI定时器
+ if (this.aqiTimer) {
+ clearInterval(this.aqiTimer)
+ console.log('停止全量AQI计算定时器')
+ }
window.removeEventListener('message', this.handleMessageEvent)
},
methods: {
handleDeviceIpList() {
- const ipSet = new Set()
+ const filteredIpSet = new Set() // 过滤后的IP(轮询用)
+ const originalIpSet = new Set() // 原始IP(AQI计算用)
this.ipToNameMap = {}
this.allDisplayConfigData.forEach(element => {
const ip = (element.IP || '').trim()
- if (ip && !this.excludeIpList.includes(ip)) {
- ipSet.add(ip)
+ if (ip) {
+ // 1. 原始IP列表:所有非空IP都加入(用于AQI计算)
+ originalIpSet.add(ip)
+ // 2. 过滤后的IP列表:排除指定IP(用于轮询)
+ if (!this.excludeIpList.includes(ip)) {
+ filteredIpSet.add(ip)
+ } else {
+ console.log('轮询排除IP:', ip, '设备名称:', element.Name)
+ }
+ // 存储IP到名称的映射(所有IP都存)
this.ipToNameMap[ip] = element.Name || `未知设备(${ip})`
- console.log('有效设备IP:', ip, '设备名称:', element.Name)
- } else if (this.excludeIpList.includes(ip)) {
- console.log('排除指定IP:', ip, '设备名称:', element.Name)
- } else if (!ip) {
+ console.log('有效设备IP(AQI计算包含):', ip, '设备名称:', element.Name)
+ } else {
console.log('过滤空IP:', element.Name)
}
})
- this.allDeviceIds = Array.from(ipSet)
+ // 赋值:过滤后的IP(轮询)、原始IP(AQI)
+ this.allDeviceIds = Array.from(filteredIpSet) // 轮询用
+ this.originalAllDeviceIds = Array.from(originalIpSet) // AQI计算用
+ console.log(`轮询IP列表(过滤后):`, this.allDeviceIds)
+ console.log(`AQI计算IP列表(原始):`, this.originalAllDeviceIds)
},
/**
@@ -246,7 +299,6 @@ export default {
try {
console.log(`开始请求IP【${targetIp}】的实时数据(模拟)`)
- // 模拟
// const data = await mockFetchDataForIP({ ip: targetIp })
// 真实请求
const data = await alarmApi.FetchDataForIP({ ip: targetIp })
@@ -258,43 +310,137 @@ export default {
if (filteredData.length > 0) {
this.newAlarm = filteredData
console.log(`IP【${targetIp}】(${this.currentDeviceName}) 过滤后的数据:`, filteredData)
- this.calcAQI(filteredData)
} else {
this.newAlarm = []
- this.aqiValue = 45
- this.aqiStatus = '健康'
console.log(`IP【${targetIp}】(${this.currentDeviceName}) 无需要的指标数据`)
}
} catch (error) {
this.newAlarm = []
- this.aqiValue = 45
- this.aqiStatus = '健康'
+ // 移除AQI重置逻辑
this.currentDeviceName = ''
console.error(`IP【${targetIp}】模拟数据请求失败:`, error)
}
},
+ calcAQI() {},
+ /**
+ * 获取所有设备的PM2.5/PM10数据(用于计算全局AQI)
+ */
+ async getAllDevicesPollutantData() {
+ if (this.originalAllDeviceIds.length === 0) {
+ this.allDevicesPollutantData = []
+ return
+ }
+
+ const allPollutantData = []
+ // 遍历原始IP列表(和EnvironmentalScreen的allDeviceIds一致)
+ for (const ip of this.originalAllDeviceIds) {
+ try {
+ // const data = await mockFetchDataForIP({ ip })
+ // 真实请求
+ const data = await alarmApi.FetchDataForIP({ ip })
+ // 仅过滤PM2.5/PM10
+ const pm25Item = data.find(item => item.subName === 'PM2.5浓度')
+ const pm10Item = data.find(item => item.subName === 'PM10浓度')
+ if (pm25Item) {
+ allPollutantData.push({
+ ...pm25Item,
+ value: parseFloat(pm25Item.value) || 0, // 确保数值类型
+ dw: pm25Item.dw || 'ug/立方米' // 对齐单位
+ })
+ }
+ if (pm10Item) {
+ allPollutantData.push({
+ ...pm10Item,
+ value: parseFloat(pm10Item.value) || 0,
+ dw: pm10Item.dw || 'ug/立方米'
+ })
+ }
+ } catch (error) {
+ console.error(`获取IP【${ip}】污染物数据失败:`, error)
+ }
+ }
+ this.allDevicesPollutantData = allPollutantData
+ },
/**
- * 计算AQI
+ * 计算全局AQI(所有设备PM2.5/PM10平均值)
*/
- calcAQI(filteredData) {
- const pm25 = parseFloat(filteredData.find(item => item.subName === 'PM2.5浓度')?.value || 0)
- const pm10 = parseFloat(filteredData.find(item => item.subName === 'PM10浓度')?.value || 0)
- const formaldehyde = parseFloat(filteredData.find(item => item.subName === '甲醛')?.value || 0)
- const co2 = parseFloat(filteredData.find(item => item.subName === '二氧化碳')?.value || 0)
-
- let aqi = 0
- if (pm25 > 50 || pm10 > 100 || formaldehyde > 30 || co2 > 1000) {
- aqi = Math.floor(Math.random() * 50) + 100
- this.aqiStatus = '污染'
- } else if (pm25 > 25 || pm10 > 50 || formaldehyde > 10 || co2 > 800) {
- aqi = Math.floor(Math.random() * 50) + 50
- this.aqiStatus = '一般'
- } else {
- aqi = Math.floor(Math.random() * 50) + 1
- this.aqiStatus = '健康'
+ calcGlobalAQI() {
+ this.hasValidData = this.allDevicesPollutantData.length > 0
+
+ // 无数据时兜底(和EnvironmentalScreen一致:默认AQI=45,状态=优)
+ if (!this.hasValidData) {
+ this.aqiValue = 45
+ this.aqiStatus = '优'
+ return
}
- this.aqiValue = aqi
+
+ // 2. 提取所有设备的PM2.5/PM10数值(转数字,兜底0)
+ const pm25List = this.allDevicesPollutantData
+ .filter(item => item.subName === 'PM2.5浓度')
+ .map(item => parseFloat(item.value) || 0)
+ const pm10List = this.allDevicesPollutantData
+ .filter(item => item.subName === 'PM10浓度')
+ .map(item => parseFloat(item.value) || 0)
+
+ // 3. 计算平均值(和EnvironmentalScreen一致:所有设备平均值)
+ const avgPm25 = pm25List.length > 0
+ ? (pm25List.reduce((sum, val) => sum + val, 0) / pm25List.length)
+ : 0
+ const avgPm10 = pm10List.length > 0
+ ? (pm10List.reduce((sum, val) => sum + val, 0) / pm10List.length)
+ : 0
+
+ // 4. 完全复用EnvironmentalScreen的国标AQI计算公式
+ const aqiBpTable = {
+ pm25: [
+ { iaqiLo: 0, iaqiHi: 50, bpLo: 0, bpHi: 35 }, // 优
+ { iaqiLo: 50, iaqiHi: 100, bpLo: 35, bpHi: 75 }, // 良
+ { iaqiLo: 100, iaqiHi: 150, bpLo: 75, bpHi: 115 }, // 轻度污染
+ { iaqiLo: 150, iaqiHi: 200, bpLo: 115, bpHi: 150 }, // 中度污染
+ { iaqiLo: 200, iaqiHi: 300, bpLo: 150, bpHi: 250 }, // 重度污染
+ { iaqiLo: 300, iaqiHi: 500, bpLo: 250, bpHi: 500 } // 严重污染
+ ],
+ pm10: [
+ { iaqiLo: 0, iaqiHi: 50, bpLo: 0, bpHi: 50 }, // 优
+ { iaqiLo: 50, iaqiHi: 100, bpLo: 50, bpHi: 150 }, // 良
+ { iaqiLo: 100, iaqiHi: 150, bpLo: 150, bpHi: 250 }, // 轻度污染
+ { iaqiLo: 150, iaqiHi: 200, bpLo: 250, bpHi: 350 }, // 中度污染
+ { iaqiLo: 200, iaqiHi: 300, bpLo: 350, bpHi: 420 }, // 重度污染
+ { iaqiLo: 300, iaqiHi: 500, bpLo: 420, bpHi: 500 } // 严重污染
+ ]
+ }
+
+ // 计算单污染物分指数(IAQI)
+ const calculateIAQI = (conc, pollutantType) => {
+ const bpTable = aqiBpTable[pollutantType]
+ if (conc > bpTable[bpTable.length - 1].bpHi) return 500
+ const matchedBp = bpTable.find(item => conc >= item.bpLo && conc <= item.bpHi) || bpTable[0]
+ const iaqi = ((matchedBp.iaqiHi - matchedBp.iaqiLo) / (matchedBp.bpHi - matchedBp.bpLo)) * (conc - matchedBp.bpLo) + matchedBp.iaqiLo
+ return Math.min(Math.round(iaqi), 500)
+ }
+
+ // 计算PM2.5、PM10分指数,取最大值为最终AQI
+ const iaqiPm25 = calculateIAQI(avgPm25, 'pm25')
+ const iaqiPm10 = calculateIAQI(avgPm10, 'pm10')
+ const finalAQI = Math.max(iaqiPm25, iaqiPm10)
+
+ // 5. 匹配AQI等级
+ this.aqiValue = finalAQI
+ const matchedGrade = this.aqiGradeStandard.find(grade =>
+ finalAQI >= grade.aqiMin && finalAQI <= grade.aqiMax
+ )
+ this.aqiStatus = matchedGrade ? matchedGrade.level : '严重污染'
+
+ // 可选:打印日志,便于和EnvironmentalScreen对比
+ console.log('FullView AQI计算(对齐EnvironmentalScreen):', {
+ avgPm25: avgPm25.toFixed(2),
+ avgPm10: avgPm10.toFixed(2),
+ iaqiPm25,
+ iaqiPm10,
+ finalAQI,
+ aqiStatus: this.aqiStatus
+ })
},
getIframeLoading(value) {},
@@ -348,8 +494,8 @@ export default {
right: 20px;
color: #fff;
padding: 20px 20px 10px 20px;
- background-image: linear-gradient(to top, rgba(24, 176, 143, .5), rgba(24, 176, 143, 0));
border-radius: 5px;
+ z-index: 999;
h3{
padding: 30px 0;
}
@@ -401,12 +547,68 @@ export default {
font-weight: 600;
padding: 10px 30px;
margin-top: 10px;
- background-color: rgba(24, 176, 143, .2);
border-radius: 5px;
}
}
}
+
+ &.air-excellent { // 优 - 绿色
+ background-image: linear-gradient(to top, rgba(40, 180, 40, .5), rgba(40, 180, 40, 0));
+ .air-params .air-right p {
+ background-color: rgba(40, 180, 40, .2);
+ }
+ .air-title::before {
+ background-color: #28B428;
+ }
+ }
+ &.air-good { // 良 - 黄色
+ background-image: linear-gradient(to top, rgba(255, 200, 0, .5), rgba(255, 200, 0, 0));
+ .air-params .air-right p {
+ background-color: rgba(255, 200, 0, .2);
+ }
+ .air-title::before {
+ background-color: #FFC800;
+ }
+ }
+ &.air-lightPollution { // 轻度污染 - 橙色
+ background-image: linear-gradient(to top, rgba(255, 140, 0, .5), rgba(255, 140, 0, 0));
+ .air-params .air-right p {
+ background-color: rgba(255, 140, 0, .2);
+ }
+ .air-title::before {
+ background-color: #FF8C00;
+ }
+ }
+ &.air-mediumPollution { // 中度污染 - 红色
+ background-image: linear-gradient(to top, rgba(255, 0, 0, .5), rgba(255, 0, 0, 0));
+ .air-params .air-right p {
+ background-color: rgba(255, 0, 0, .2);
+ }
+ .air-title::before {
+ background-color: #FF0000;
+ }
+ }
+ &.air-heavyPollution { // 重度污染 - 紫色
+ background-image: linear-gradient(to top, rgba(150, 0, 200, .5), rgba(150, 0, 200, 0));
+ .air-params .air-right p {
+ background-color: rgba(150, 0, 200, .2);
+ }
+ .air-title::before {
+ background-color: #9600C8;
+ }
+ }
+ &.air-severePollution { // 严重污染 - 褐红色
+ background-image: linear-gradient(to top, rgba(120, 0, 0, .5), rgba(120, 0, 0, 0));
+ .air-params .air-right p {
+ background-color: rgba(120, 0, 0, .2);
+ }
+ .air-title::before {
+ background-color: #780000;
+ }
+ }
}
+
+// 兼容原有air-warn类(可选,可删除)
.air-warn{
background-image: linear-gradient(to top, rgba(246, 81, 99, .5), rgba(24, 176, 143, 0));
.air-params{
@@ -417,8 +619,9 @@ export default {
}
}
}
+
.msg-list{
- // top: 40px;
+ position: static;
flex-wrap: wrap !important;
li{
margin-bottom: 20px;
diff --git a/src/views/system/logManage/warnLog/index.vue b/src/views/system/logManage/warnLog/index.vue
index 542d4c4..68060ef 100644
--- a/src/views/system/logManage/warnLog/index.vue
+++ b/src/views/system/logManage/warnLog/index.vue
@@ -2,18 +2,19 @@
导出
- 手动处理
-
+
+
+
+
+
+
-
-
- 已处理
- 未处理
-
-
-
-
-
-
-
+
+
+
+
+
+
- {{ scope.row.create_time | parseTime }}
+
+ {{ formatAlarmLevel(scope.row.itemLevels) }}
-
+
- {{ scope.row.update_time | parseTime }}
+ {{ scope.row.ts | parseTime }}
@@ -93,8 +108,8 @@ export default {
mixins: [presenter(), crud(), header()],
cruds() {
return CRUD({
- url: 'api/alarmlog/',
- sort: ['state'],
+ url: 'api/device/hikAlarmLog',
+ sort: [],
optShow: {
add: false,
edit: false,
@@ -120,7 +135,7 @@ export default {
{ value: 1, label: '设备' },
{ value: 2, label: '库房' }
],
- queryTime: null,
+ queryTime: [],
form: {
description: ''
},
@@ -128,6 +143,18 @@ export default {
description: [
{ required: true, message: '说明不能为空', trigger: 'blur' }
]
+ },
+ alarmLevelMap: {
+ 1: '紧急',
+ 2: '重大',
+ 3: '严重',
+ 4: '紧要',
+ 5: '重要',
+ 6: '次要',
+ 7: '一般',
+ 8: '警告',
+ 9: '提示',
+ 10: '忽略'
}
}
},
@@ -137,22 +164,32 @@ export default {
])
},
methods: {
+ formatAlarmLevel(level) {
+ // 处理数字类型(如后端返回字符串数字)
+ const numLevel = Number(level)
+ // 优先匹配数字键,无匹配则返回"未知"
+ return this.alarmLevelMap[numLevel] || this.alarmLevelMap['']
+ },
// 获取数据前的处理
[CRUD.HOOK.beforeRefresh]() {
- this.crud.downloadLoading = true
- this.crud.query.state = null
- // this.crud.query.blurry = this.keyWord
- if (this.oprType > -1) {
- this.crud.query.state = this.oprType
+ if (this.queryTime && this.queryTime.length > 0) {
+ this.crud.query.startTime = this.queryTime[0]
+ this.crud.query.endTime = this.queryTime[1]
+ } else {
+ this.crud.query.startTime = null
+ this.crud.query.endTime = null
}
- this.crud.downloadLoading = false
},
// 导出
handleDownload() {
this.crud.downloadLoading = true
const fileName = parseTime(new Date()) + '-报警日志'
- getBlob(this.baseApi + '/api/alarmlog/download' + '?' + qs.stringify(this.crud.query, { indices: false }), function(blob) {
+ getBlob(this.baseApi + '/api/device/downloadHikAlarmLog' + '?' + qs.stringify(this.crud.query, { indices: false }), function(blob) {
saveAs(blob, fileName)
+ }, (err) => {
+ console.error('导出失败:', err)
+ this.$message.error('导出失败')
+ this.crud.downloadLoading = false
})
this.crud.downloadLoading = false
},
@@ -164,25 +201,23 @@ export default {
},
// 手动处理
handleHand() {
- this.form.description = this.selections[0].remark
+ this.form.description = this.selections[0]?.remark || ''
this.handleVisible = true
},
handleSave() {
const row = this.selections[0]
+ if (!row) {
+ this.$message.warning('请选择要处理的记录')
+ return
+ }
const params = {
'id': row.id,
- // 'storeroom_name': row.storeroomName,
'state': true,
- // 'device_id': row.deviceId,
- // 'device_name': row.deviceName,
- // 'content': row.content,
'remark': this.form.description
}
- console.log(params)
this.$refs.formDom.validate((valid) => {
if (valid) {
warnRemark(params).then(res => {
- // console.log(res, '手动处理')
if (res === 'SUCCESS') {
this.crud.refresh()
this.$message({
@@ -195,6 +230,8 @@ export default {
} else {
this.$message.error('处理失败')
}
+ }).catch(() => {
+ this.$message.error('处理失败')
})
} else {
return false
@@ -207,6 +244,24 @@ export default {
} else if (row.state === false && columnIndex === 2) {
return 'fail-clear'
}
+ },
+ // 状态选择框清空处理
+ handleOprTypeClear() {
+ this.oprType = -1
+ this.crud.toQuery()
+ },
+ handleDateChange() {
+ this.crud.toQuery()
+ },
+ // 日期范围选择器清空处理
+ handleDateClear() {
+ // 清空时间范围
+ this.queryTime = []
+ // 重置时间相关查询参数
+ this.crud.query.startTime = null
+ this.crud.query.endTime = null
+ // 触发查询刷新列表
+ this.crud.toQuery()
}
}
}