You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

440 lines
11 KiB
Vue

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<template>
<div class="container">
<div class="centerImg"></div>
<Chart ref="chart1" class="chart1"></Chart>
<div class="table1">
<div style="background-color: #094170">
<div class="scrollTable" style="font-weight: bold;">
告警编号
</div>
<div class="scrollTable" style="font-weight: bold;">
告警类型
</div>
<div class="scrollTable" style="font-weight: bold;">
告警单元
</div>
<div class="scrollTable" style="font-weight: bold;">
操作
</div>
</div>
<vue-seamless-scroll
:class-option="{...chart1TableOption,limitMoveNum:10}"
:data="table1Data"
class="case-item"
style="height: 84%;overflow: hidden;"
>
<div
v-for="(item, index) in table1Data"
:key="index"
>
<div :style='"background-color:" + ((index % 2 === 0)? "#053460":"#032d57") '>
<div
class="scrollTable">
{{ item.value1 }}
</div>
<div
class="scrollTable">
{{ item.value2 }}
</div>
<div
class="scrollTable">
{{ item.value3 }}
</div>
<div class="scrollTable" style="width: 25%">
<el-button v-if="item.status === '0'" size="mini" type="primary" @click="dispose(item)">处理</el-button>
<span v-else>已处理</span>
</div>
</div>
</div>
</vue-seamless-scroll>
</div>
<div>
<div class="title1">监控单元报警统计</div>
<div class="title2">告警信息</div>
<div class="info1">监控单元数量</div>
<div class="info2">设备数量</div>
<div class="info3">在线设备数量</div>
<div class="num1">{{ num2 }}</div>
<div class="num2">{{ num1 }}</div>
<div class="num3">{{ num3 }}</div>
</div>
<div id="map" class="map"></div>
</div>
</template>
<script>
import Chart from "@/components/Charts/Chart";
import vueSeamlessScroll from "vue-seamless-scroll";
import * as echarts from 'echarts';
import {
alarmStats,
subDevice,
getAlarmInfos,
ElectronicNumVo
} from '@/api/board/GPS'
import red from '@/assets/board/GPS/red.png'
import green from '@/assets/board/GPS/green.png'
import {handleAlarmInfo} from "@/api/board/index";
let map = null
let polyEditor = null
export default {
components: {
Chart,
vueSeamlessScroll,
},
watch: {
async $route(to, from) {
await this.getData()
}
},
data() {
return {
num1: 0,
num2: 0,
num3: 0,
chart1TableOption: {
step: 0.5, // 数值越大速度滚动越快
limitMoveNum: 3, // 开始无缝滚动的数据量 this.dataList.length
hoverStop: true, // 是否开启鼠标悬停stop
direction: 1, // 0向下 1向上 2向左 3向右
openWatch: true, // 开启数据实时监控刷新dom
singleHeight: 0, // 单步运动停止的高度(默认值0是无缝不停止的滚动) direction => 0/1
singleWidth: 0, // 单步运动停止的宽度(默认值0是无缝不停止的滚动) direction => 2/3
waitTime: 0,
},
chart1Option: {
grid: {
left: "0%",
right: "5%",
top: "0%",
bottom: "0%",
containLabel: true,
},
tooltip: {
trigger: "axis",
axisPointer: {
type: "shadow",
},
},
xAxis: {
type: "value",
axisLine: {
show: true,
lineStyle: {
color: "#fffa",
},
},
splitLine: {
show: true,
lineStyle: {
color: "#fff4",
type: 'dashed'
},
},
boundaryGap: [0, 0.01],
},
},
table1Data: [],
sceneId: 0,
}
},
async mounted() {
await this.getData()
},
methods: {
async getData() {
if (this.$store.getters.sceneId === null) return
await this.createMap()
await this.getAlarmStats()
await this.getAubDevice()
await this.setAlarmInfos()
await this.setElectronicNumVo()
},
dispose(e) {
this.$confirm('该问题已处理?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
handleAlarmInfo({
alarmInfoId: e.no
}).then(e => {
if (e.code === 200) {
this.$message({
type: 'success',
message: '已处理!'
});
this.setTable3()
} else {
this.$message({
type: 'info',
message: '网络错误'
});
}
})
}).catch(() => {
this.$message({
type: 'info',
message: '已取消'
});
});
},
createMap() {
map = new AMap.Map('map', {
zoom: 11,
center: [113.4, 23.35],
});
},
setText(e) {
let position = e.areaPoints?.length > 0 ? e.areaPoints : e.centerPoint
if (position.length > 0) {
let length = position.length
let longitudes = e.areaPoints.map(e => e.longitude).reduce((a, b) => a + b)
let latitudes = e.areaPoints.map(e => e.latitude).reduce((a, b) => a + b)
position = [longitudes / length, latitudes / length]
} else {
position = [e.centerPoint.longitude, e.centerPoint.latitude]
}
let text = new AMap.Text({
text: '<div style="color:#fff;width: 100%;height: 100%;">' + '' + e.deviceCount + (e.abnormalCount ? ('/' + e.abnormalCount) : '') + '</div>',
anchor: 'center',
draggable: true,
cursor: 'pointer',
position: position
});
text.setStyle({
'background-color': e.abnormalCount? '#fe0000':'#0055fe',
padding:'4px 12px',
'font-size':'1vw'
})
map.add(text)
},
setPolygon(position, val) {
let e = position.map(val => {
return [val.longitude, val.latitude]
})
let thisPolygon = new AMap.Polygon({
path: e,
fillColor: val > 0 ? '#ff0000' : '#1791fc',
});
map.add(thisPolygon)
map.setFitView()
},
setCircle(center, radius, e) {
let circle = new AMap.Circle({
center,
radius,
borderWeight: 3,
strokeColor: e ? '#ff0000' : "#FF33FF",
strokeWeight: 6,
strokeOpacity: 0.2,
fillOpacity: 0.4,
strokeDasharray: [10, 10],
fillColor: e > 0 ? '#ff0000' : '#1791fc',
})
map.add(circle);
map.setFitView()
},
async getAlarmStats() {
if (this.$store.getters.sceneId === null) return
const {data} = await alarmStats(this.$store.getters.sceneId)
let option1 = {
...this.chart1Option,
yAxis: {
axisLine: {
show: true,
lineStyle: {
color: "#fffa",
},
},
splitLine: {
show: true,
lineStyle: {
color: "#fff4",
type: 'dashed'
},
},
type: "category",
data: data.map(e => e.monitorUnitName),
},
series: [
{
name: "数量",
type: "bar",
yAxisIndex: 0,
data: data.map(e => e.sum),
barWidth: '60%',
itemStyle: {
normal: {
show: true,
color: new echarts.graphic.LinearGradient(1, 0, 0, 0, [
{
offset: 0,
color: "#00faff",
},
{
offset: 1,
color: "#1eadf1",
},
]),
},
},
},
],
}
this.$refs.chart1.setData(option1)
},
async getAubDevice() {
let data = await subDevice(this.$store.getters.sceneId)
this.num1 = data.deviceNum
this.num2 = data.subSum
this.num3 = data.onlineDeviceNum
},
async setAlarmInfos() {
const {rows: data} = await getAlarmInfos({"sceneId": this.$store.getters.sceneId})
this.table1Data = data.map((e, i) => {
return {
value1: e.alarmInfoId,
value2: e.alarmTypeName,
value3: e.monitorUnitName,
status: e.handleStatus
}
})
},
async setElectronicNumVo() {
const {data} = await ElectronicNumVo(this.$store.getters.sceneId)
data.forEach(e => {
if (e.areaPoints?.length > 0) {
this.setPolygon(e.areaPoints, e.abnormalCount)
}
if (e.centerPoint) {
this.setCircle([e.centerPoint.longitude, e.centerPoint.latitude], e.radius, e.abnormalCount)
}
this.setText(e)
})
}
}
};
</script>
<style scoped>
.container {
background-image: url("~@/assets/board/GPS/bg.jpg");
background-repeat: no-repeat;
background-size: 100% 100%;
width: 100%;
height: calc(100vh);
position: relative;
}
.chart1 {
position: absolute;
width: 25%;
height: 21%;
top: 16%;
left: 3%;
}
.table1 {
position: absolute;
top: 48%;
left: 2.5%;
width: 26%;
height: 48%;
overflow: hidden;
}
.scrollTable {
color: rgb(185, 186, 192);
margin: auto 0px;
padding: 4px 0;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
text-align: center;
display: inline-block;
width: 25%;
}
.title1 {
position: absolute;
top: 13%;
left: 15.5%;
transform: translate(-50%, -50%);
font-size: 1vw;
color: #fff;
}
.title2 {
position: absolute;
top: 45.4%;
left: 15.6%;
transform: translate(-50%, -50%);
font-size: 1vw;
color: #fff;
}
.info1 {
position: absolute;
top: 18%;
left: 39%;
transform: translate(-50%, -50%);
font-size: 1vw;
color: #179ce1;
}
.info2 {
position: absolute;
top: 18%;
left: 62%;
transform: translate(-50%, -50%);
font-size: 1vw;
color: #179ce1;
}
.info3 {
position: absolute;
top: 18%;
left: 83%;
transform: translate(-50%, -50%);
font-size: 1vw;
color: #179ce1;
}
.num1 {
position: absolute;
top: 18%;
left: 47%;
transform: translate(-50%, -50%);
font-size: 1.4vw;
color: #fff;
}
.num2 {
position: absolute;
top: 18%;
left: 69%;
transform: translate(-50%, -50%);
font-size: 1.4vw;
color: #fff;
}
.num3 {
position: absolute;
top: 18%;
left: 91%;
transform: translate(-50%, -50%);
font-size: 1.4vw;
color: #fff;
}
.map {
position: absolute;
top: 28%;
left: 31%;
width: 67%;
height: 69%;
}
</style>