新增温度管理页面 首页调试实时告警数据

This commit is contained in:
fengrong 2024-11-06 16:10:25 +08:00
parent db94a1a3b1
commit dce8ac8da9
3 changed files with 480 additions and 92 deletions

View File

@ -0,0 +1,24 @@
import createAxios from '/@/utils/axios'
export function equipList(params: object = {}) {
return createAxios({
url: '/api/equipment/list',
method: 'POST',
data: params,
})
}
export function getTemperatureLimitByDeviceId(params: object = {}) {
return createAxios({
url: '/api/page/temperature/getTemperatureLimitByDeviceId',
method: 'POST',
data: params,
})
}
export function getsnapshotData(params: object = {}) {
return createAxios({
url: '/api/data/snapshot',
method: 'POST',
data: params,
})
}

View File

@ -296,12 +296,15 @@
ref="myTable"
@mouseover.native="clearScroll"
@mouseleave.native="createScroll">
<el-table-column fixed prop="time" label="时间" />
<el-table-column prop="name" label="风机" />
<el-table-column prop="alertcontent" label="告警内容" />
<el-table-column fixed prop="eventTimeFormate" label="时间" />
<el-table-column prop="deviceCode" label="风机" />
<el-table-column prop="eventText" label="告警内容" />
<el-table-column label="操作">
<template #default="scope">
<a @click="">确认</a>
<div class="tableOperate comfirmed" style="color: #333333;" v-if="scope.row.confirmed">已确认</div>
<div class="tableOperate" v-else>
<a style="color: #0277B3; cursor: pointer;" @click="open(scope.row)">确认</a>
</div>
</template>
</el-table-column>
</el-table>
@ -320,12 +323,15 @@ import * as echarts from 'echarts'
import { useTemplateRefsList,useEventListener } from '@vueuse/core'
import {useI18n} from "vue-i18n";
import WindContent from '/@/views/backend/home/windMatrix.vue'
import { equipList } from '/@/api/backend/realData/request'
import {
getWindFarmRealData,
getWindTurbineMatrixData,
getHistoryData
getHistoryData,
getAlarmList,
alertComfirm
} from "/@/api/backend/dashboard.ts";
import {dayjs, ElMessage, TableInstance} from "element-plus";
import {dayjs, ElMessage, ElMessageBox, TableInstance} from "element-plus";
import { getRealTimeState } from '/@/views/backend/equipment/airBlower/utils.ts'
import {useRoute} from "vue-router";
const route = useRoute()
@ -403,6 +409,7 @@ const currentDayStatus=ref({
StartCapacityTotal: 0,
StarteNum: 0
})
const deviceCode=ref([])
const FanList = ref([])
const StatusListData = () => {
getWindTurbineMatrixData().then((res) => {
@ -489,7 +496,6 @@ const StatusListData = () => {
}
});
FanList.value=data
}else{
ElMessage.error({
message: res.msg,
@ -500,6 +506,8 @@ const StatusListData = () => {
})
}
const state: {
charts: { powerChart: any; trendChart: any }
remark: string
@ -668,23 +676,6 @@ const initpowerChart = () => {
const trendChartRef = ref<VNodeRef>()
/*const TrendDataForDay = [
{
currentPeriod: 86.3,
samePeriod: 63.5,
generationTime: '2024-10-01',
},
{
currentPeriod: 86.3,
samePeriod: 53.5,
generationTime: '2024-10-02',
},
{
currentPeriod: 86.3,
samePeriod: 43.5,
generationTime: '2024-10-03',
},
]*/
const TrendDataForDay: {
currentPeriod: {
time: string[]
@ -724,28 +715,8 @@ const TrendDataForMonth :{
value: [],
},
}
/*const TrendDataForMonth = [
{
currentPeriod: 26.3,
samePeriod: 53.5,
generationTime: '2024-10-01',
},
{
currentPeriod: 36.3,
samePeriod: 53.5,
generationTime: '2024-10-02',
},
{
currentPeriod: 46.3,
samePeriod: 53.5,
generationTime: '2024-10-03',
},
]*/
const inittrendChart = (type: 'day' | 'month') => {
/* const currentPeriod: number[] = type === 'day' ? TrendDataForDay.currentPeriod.value : TrendDataForMonth.map((item) => item.currentPeriod)
const samePeriod: number[] = type === 'day' ? TrendDataForDay.samePeriod.value : TrendDataForMonth.map((item) => item.samePeriod)
const xAxisdata: string[] = type === 'day' ? TrendDataForDay.currentPeriod.time : TrendDataForMonth.map((item) => item.generationTime)*/
const currentPeriod: number[] = type === 'day' ? TrendDataForDay.currentPeriod.value : TrendDataForMonth.currentPeriod.value
const samePeriod: number[] = type === 'day' ? TrendDataForDay.samePeriod.value : TrendDataForMonth.samePeriod.value
const xAxisdata: string[] = type === 'day' ? TrendDataForDay.currentPeriod.time : TrendDataForMonth.currentPeriod.time
@ -866,50 +837,86 @@ const echartsResize = () => {
onActivated(() => {
echartsResize()
})
const tableData = ref([
{
time: '2016-05-03',
name: 'SC-01',
alertcontent: '故障',
},
{
time: '2016-05-02',
name: 'SC-02',
alertcontent: '待机',
},
{
time: '2016-05-04',
name: 'SC-03',
alertcontent: '停机',
},
{
time: '2016-05-01',
name: 'SC-04',
alertcontent: '变桨叶1伺服驱动器故障',
},
{
time: '2016-05-03',
name: 'SC-01',
alertcontent: '故障',
},
{
time: '2016-05-02',
name: 'SC-02',
alertcontent: '待机',
},
{
time: '2016-05-04',
name: 'SC-03',
alertcontent: '停机',
},
{
time: '2016-05-01',
name: 'SC-04',
alertcontent: '变桨叶1伺服驱动器故障',
const timestampToTime = (timestamp: any) => {
timestamp = timestamp ? timestamp : null
let date = new Date(timestamp)
let Y = date.getFullYear() + '-'
let M = (date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1) + '-'
let D = (date.getDate() < 10 ? '0' + date.getDate() : date.getDate()) + ' '
let h = (date.getHours() < 10 ? '0' + date.getHours() : date.getHours()) + ':'
let m = date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes()
return Y + M + D + h + m
}
const tableData= ref()
const getTableData = (deviceCode) => {
const today = new Date();
const threeDaysAgo = new Date(today);
threeDaysAgo.setDate(today.getDate() - 3);
const startTime = threeDaysAgo.getTime();
const data:any = {
startTime: startTime,
endTime: Date.now(),
deviceCode:deviceCode,
limit:100
}
console.log(JSON.stringify(data))
getAlarmList(data).then((res) => {
debugger
if (res.code == 200) {
//tableData.value = res.rows
tableData.value = res.rows.map((item: any) => {
return {
...item,
eventTimeFormate: timestampToTime(item.eventTime),
}
})
} else {
ElMessage.error(res.msg ?? '查询失败')
}
})
}
const open = (val: any) => {
ElMessageBox.confirm('是否确认?', '提示', {
confirmButtonText: '确认',
cancelButtonText: '取消',
type: 'warning',
})
.then(() => {
okSubmit(val)
})
.catch(() => {
ElMessage({
type: 'info',
message: '取消确认',
})
})
}
const okSubmit = (val: any) => {
const reqData: any = [
{
eventTime: val.eventTime,
eventId: val.eventId,
confirmed: 1,
deviceId: val.deviceId,
},
]
debugger
alertComfirm(reqData)
.then((res: any) => {
debugger
if (res.code == 200) {
ElMessage.success(res.msg ?? '确认成功')
getTableData(deviceCode.value)
} else {
ElMessage.error(res.msg ?? '查询失败')
}
})
.catch((err) => {
ElMessage.error(err?.response?.data?.msg ?? '查询失败')
})
}
])
const clearScroll = () => {
@ -947,7 +954,7 @@ const getChartData = <T extends string = any>(params: {
],
interval: params.interval,
}
console.log(JSON.stringify(data))
/* console.log(JSON.stringify(data))*/
getHistoryData(data).then((res) => {
if (res.success) {
if (typeof res.data === 'object' && res.data !== null && Object.keys(res.data).length === 0) {
@ -1123,13 +1130,17 @@ onMounted(() => {
overviewList()
StatusListData()
autoUpdate()
equipList({objectType: 10002,}).then((res) => {
res.data.map((item: any) => {
deviceCode.value.push(item.name)
})
getTableData(deviceCode.value)
})
useEventListener(window, 'resize', echartsResize)
})
/*onBeforeMount(() => {
for (const key in state.charts) {
state.charts[key].dispose()
}
})*/
const activeName = ref('first')
//let autoUpdateTimer: any = null
let autoUpdateForSecondTimer: any = null

View File

@ -0,0 +1,353 @@
<template>
<div class="temperature">
<el-container class="containerPart">
<el-aside class="defaultAside">
<el-main class="treeMain">
<el-tree
style="max-width: 600px;margin-top: 2.2%"
ref="equipTreeRef"
:data="deviceData"
:props="defaultProps"
node-key="id"
@node-click="handleNodeClick"
/>
</el-main>
</el-aside>
<el-container class="defaultMainContainer">
<div class="temperature-chart" ref="temperatureChartRef"></div>
</el-container>
</el-container>
</div>
</template>
<script setup lang="ts">
import {nextTick, onActivated, onMounted, onUnmounted, reactive, ref} from 'vue'
import {equipList,getTemperatureLimitByDeviceId,getsnapshotData} from "/@/api/backend/temperature/request.ts";
import * as echarts from "echarts";
import {useEventListener } from '@vueuse/core'
import {dayjs} from "element-plus";
const defaultProps = {
children: 'children',
label: 'name'
}
const devicelistData = reactive({
objectType: 10002,
})
const deviceData = ref([{
id: 0,
name: "风机列表",
children: []
}])
const deviceId=ref()
const equipTreeRef = ref()
const deviceQuery = (data: any) => {
equipList(data).then((res) => {
deviceData.value[0].children = res.data
nextTick(() => {
deviceId.value=res.data[0]?.id
equipTreeRef.value?.setCurrentKey(deviceData.value[0].id!, false)
getChartData({id:deviceId.value})
})
})
}
const handleNodeClick = (data: any) => {
deviceId.value=data.id
state.charts.temperatureChart.clear()
getChartData({id:deviceId.value})
}
const state: {
charts: { temperatureChart: any; }
remark: string
workingTimeFormat: string
pauseWork: boolean
} = reactive({
charts: { temperatureChart: null },
remark: 'dashboard.Loading',
workingTimeFormat: '',
pauseWork: false,
})
const temperatureChartRef = ref()
const temperatureData:any ={
name: [],
values: [],
limit1High: [],
limit1Low: [],
limit2High: [],
limit2Low: []
}
const inittemperatureChar = () => {
const temperatureChart = state.charts.temperatureChart ?? echarts.init(temperatureChartRef.value as unknown as HTMLElement)
const option = {
grid: {
show:true,
top: 50,
right: 23,
bottom: 10,
left: 25,
containLabel: true,
borderColor:'transparent',
backgroundColor:'rgba(254,55,49,0.20)'
},
// tooltip: {
// trigger: 'axis',
// axisPointer: {
// type: 'shadow',
// },
// },
xAxis: {
type: 'value',
interval: 10,
axisLine: {
show: true,
lineStyle: {
color: '#ffffff',
width: 1,
type: 'solid',
},
},
axisLabel: {
//x
show: true,
textStyle: {
color: '#4E5969',
},
interval: 10,
//rotate: 45
},
splitLine: {
//线
show: true,
lineStyle: {
color: '#ffffff',
},
}
},
yAxis: [
{
type: 'category',
nameTextStyle: {
color: '#4E5969',
},
axisLine: {
show: true,
lineStyle: {
color: '#ffffff',
width: 0,
type: 'solid',
},
},
axisLabel: {
//x
show: true,
textStyle: {
color: '#4E5969',
},
},
axisTick: { show: false },
splitLine: {
interval: 50,
lineStyle: {
type: 'solid',
color: '#ffffff',
},
},
data: temperatureData.name
},
],
series: [
{
type: 'bar',
barWidth: 40,
itemStyle: {
color: '#0064AA',
barBorderRadius: 2
},
label:{
show:true,
position:'insideRight',
color:'#ffffff'
},
data: temperatureData.values,
z:3
},
{
name: '上限值',
type: 'bar',
barWidth: 40,
barGap: '-100%',
data: temperatureData.limit1High,
itemStyle: {
color: '#ccecea',
},
z:2
},
{
name: '下限值',
type: 'bar',
barWidth: 40,
barGap: '-100%',
data: temperatureData.limit1Low,
itemStyle: {
color: '#ccecea',
},
z:2
},
{
name: '上上限值',
type: 'bar',
barWidth: 40,
barGap: '-100%',
itemStyle: {
color: '#fff0cc',
},
data: temperatureData.limit2High,
z:1
},
{
name: '下下限值',
type: 'bar',
barWidth: 40,
barGap: '-100%',
data: temperatureData.limit2Low,
itemStyle: {
color: '#fff0cc',
},
z:1
},
],
}
temperatureChart.setOption(option)
state.charts.temperatureChart = temperatureChart
}
const attributesCode:any[]=[]
const getChartData = (data: any) => {
console.log(JSON.stringify(data))
getTemperatureLimitByDeviceId(data).then((res) => {
if (res.code=='200') {
temperatureData.name=[]
temperatureData.values=[]
temperatureData.limit1High=[]
temperatureData.limit1Low=[]
temperatureData.limit2High=[]
temperatureData.limit2Low=[]
res.data.forEach((item,index) => {
temperatureData.name.push(item.measPointName)
attributesCode.push(item.measPointCode)
if(item.limit1Enable){
temperatureData.limit1High.push(item.limit1High)
temperatureData.limit1Low.push(item.limit1Low)
}
if(item.limit2Enable){
temperatureData.limit2High.push(item.limit2High)
temperatureData.limit2Low.push(item.limit2Low)
}
})
getTemperaData([{deviceId:data.id,attributes:attributesCode}])
}
})
}
const getTemperaData = (data:any) => {
getsnapshotData(data).then((res) => {
if (res.code == 200) {
const data = res.data[deviceId.value]
const rangeKeys = Object.keys(data)
attributesCode.forEach((attribute, index) => {
if (attribute) {
const attributeLower = attribute.toLowerCase();
const foundKey = Object.keys(rangeKeys).find(key => rangeKeys[key] === attributeLower);
if (foundKey) {
const value=data[rangeKeys[foundKey]]
const formattedValue=value !== undefined ? (value % 1 === 0 ? value : value.toFixed(2)) : '-';
temperatureData.values = temperatureData.values.concat({value:formattedValue,itemStyle:{color:'#0064AA'}});
}
}
});
const values = temperatureData.values
const limit1High = temperatureData.limit1High
const limit1Low = temperatureData.limit1Low
const limit2High = temperatureData.limit2High
const limit2Low = temperatureData.limit2Low
inittemperatureChar()
seriesStyle(values, limit1High, limit1Low, limit2High, limit2Low)
}
})
}
const seriesStyle= (values, limit1High, limit1Low, limit2High, limit2Low) =>{
const option = state.charts.temperatureChart.getOption();
const series = option?.series?.[0];
values.forEach((item,index) => {
if (Number(item.value) > Number(limit1High[index]) || Number(item.value) < Number(limit1Low[index])) {
//debugger
item.itemStyle.color= 'red'
series.data[index].itemStyle = { color: 'red' };
} else if (Number(item.value) > Number(limit2High[index]) || Number(item.value) < Number(limit2Low[index])) {
item.itemStyle.color= 'red'
series.data[index].itemStyle = { color: 'red' };
} else {
item.itemStyle.color= '#0064AA'
}
})
state.charts.temperatureChart.setOption(option);
}
let autoUpdateTimer: any = null
const autoUpdate = () => {
if (!autoUpdateTimer) {
autoUpdateTimer = setInterval(() => {
getChartData({id:deviceId.value})
}, 2000)
}
}
const echartsResize = () => {
nextTick(() => {
const chartKeys = Object.keys(state.charts) as Array<keyof typeof state.charts>
chartKeys.forEach((key) => {
state.charts[key].resize()
})
})
}
onActivated(() => {
echartsResize()
})
onMounted(() => {
deviceQuery(devicelistData)
autoUpdate()
useEventListener(window, 'resize', echartsResize)
})
onUnmounted(() => {
autoUpdateTimer && clearInterval(autoUpdateTimer)
const chartKeys = Object.keys(state.charts) as Array<keyof typeof state.charts>
chartKeys.forEach((key) => {
state.charts[key] && state.charts[key].dispose()
})
})
</script>
<style scoped lang="scss">
.temperature{
width: 100%;
height: 100%;
.containerPart {
height: 100%;
.defaultAside {
width: 260px;
height: 100%;
border-right: 1px solid #eaebed;
}
.defaultMainContainer{
width: calc(100% - 260px);
height: 100%;
.temperature-chart{
width: 100%;
height: calc(100% - 50px);
}
}
}
}
</style>