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.

723 lines
20 KiB
Vue

2 years ago
<template>
<div class="container">
<div class="centerImg"></div>
1 year ago
<div class="table2">
<div style="background-color: #094170">
1 year ago
<div class="scrollTable" style="font-weight: bold;width: 20%">
1 year ago
设备名称
</div>
1 year ago
<div class="scrollTable" style="font-weight: bold;width: 20%">
1 year ago
经度
</div>
1 year ago
<div class="scrollTable" style="font-weight: bold;width: 20%">
1 year ago
纬度
</div>
1 year ago
<div class="scrollTable" style="font-weight: bold;width: 40%">
1 year ago
操作
</div>
</div>
<vue-seamless-scroll
:class-option="{...chart1TableOption,limitMoveNum:10}"
:data="table2Data"
class="case-item"
style="height: 84%;overflow: hidden;"
>
<div
v-for="(item, index) in table2Data"
:key="index"
>
<div :style='"background-color:" + ((index % 2 === 0)? "#053460":"#032d57") '>
<div
1 year ago
class="scrollTable" style="width: 20%">
{{ item.deviceName }}
1 year ago
</div>
<div
1 year ago
class="scrollTable" style="width: 20%">
{{ item.longitude }}
1 year ago
</div>
<div
1 year ago
class="scrollTable" style="width: 20%">
{{ item.latitude }}
1 year ago
</div>
1 year ago
<div class="scrollTable" style="width: 40%">
<el-button size="mini" type="primary" @click=" mapOrientation(item)">地图定点</el-button>
12 months ago
<el-button size="mini" type="primary" @click="toEquipmentInfo(item)"></el-button>
1 year ago
</div>
</div>
</div>
</vue-seamless-scroll>
</div>
2 years ago
<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;">
告警单元
2 years ago
</div>
<div class="scrollTable" style="font-weight: bold;">
操作
</div>
</div>
<vue-seamless-scroll
:class-option="{...chart1TableOption,limitMoveNum:10}"
2 years ago
: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>
2 years ago
<div class="scrollTable" style="width: 25%">
2 years ago
<el-button v-if="item.status === '0'" size="mini" type="primary" @click="dispose(item)"></el-button>
2 years ago
<span v-else></span>
2 years ago
</div>
</div>
</div>
</vue-seamless-scroll>
</div>
<div>
1 year ago
<div class="title1">信标设备列表</div>
2 years ago
<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>
2 years ago
</div>
<div id="map" class="map"></div>
1 year ago
<div class="isRail">
<el-switch
v-model="isRail"
@change="RailChange"
active-text="显示电子围栏"
inactive-text="隐藏电子围栏">
</el-switch>
</div>
1 year ago
<el-dialog title="历史记录" :visible.sync="historyDialog">
12 months ago
<el-descriptions class="margin-top" :column="3" border>
<el-descriptions-item>
<template slot="label">
12 months ago
设备编号
12 months ago
</template>
12 months ago
{{ equipmentInfo.deviceId }}
12 months ago
</el-descriptions-item>
<el-descriptions-item>
<template slot="label">
12 months ago
设备名称
12 months ago
</template>
12 months ago
{{ equipmentInfo.deviceName }}
12 months ago
</el-descriptions-item>
<el-descriptions-item>
<template slot="label">
12 months ago
监控单元
12 months ago
</template>
12 months ago
{{ equipmentInfo.monitorUnitName }}
12 months ago
</el-descriptions-item>
<el-descriptions-item>
<template slot="label">
城市名称
</template>
{{ equipmentInfo.deviceLocation }}
</el-descriptions-item>
12 months ago
<el-descriptions-item>
<template slot="label">
经度
</template>
{{ equipmentInfo.longitude }}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label">
纬度
</template>
{{ equipmentInfo.latitude }}
</el-descriptions-item>
12 months ago
<el-descriptions-item>
<template slot="label">
备注
</template>
{{ equipmentInfo.remark }}
</el-descriptions-item>
</el-descriptions>
<el-form :inline="true" :model="form" class="demo-form-inline" style="margin-top: 12px">
1 year ago
<el-form-item label="查询时间">
<el-date-picker
v-model="form.time"
type="datetimerange"
range-separator="至"
start-placeholder="开始日期"
end-placeholder="结束日期">
</el-date-picker>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="getHistoryData"></el-button>
</el-form-item>
</el-form>
<el-table
12 months ago
v-loading="loading"
1 year ago
:data="historyData"
style="width: 100%">
12 months ago
<el-table-column
prop="deviceId"
label="设备编号"
width="180">
</el-table-column>
1 year ago
<el-table-column
prop="longitude"
label="经度"
width="180">
</el-table-column>
<el-table-column
prop="latitude"
label="纬度"
width="180">
</el-table-column>
<el-table-column
prop="speed"
label="速度">
</el-table-column>
<el-table-column
prop="ts"
label="采集时间">
12 months ago
<template slot-scope="scope">
{{ parseTime(scope.row.ts) }}
</template>
1 year ago
</el-table-column>
</el-table>
<pagination
v-show="total>0"
:total="total"
:page.sync="form.pageNum"
:limit.sync="form.pageSize"
@pagination="getHistoryData"
/>
</el-dialog>
12 months ago
<el-dialog
:visible.sync="isDispose"
width="30%">
<el-descriptions class="margin-top" :column="2" border>
<el-descriptions-item>
<template slot="label">
设备id
</template>
{{ warInfo.deviceId }}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label">
监控单元名称
</template>
{{ warInfo.monitorUnitName }}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label">
监控单元类型
</template>
{{ warInfo.monitorUnitTypeName }}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label">
告警编号
</template>
{{ warInfo.alarmInfoId }}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label">
告警类型
</template>
{{ warInfo.alarmTypeName }}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label">
告警位置
</template>
{{ warInfo.location }}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label">
告警信息
</template>
{{ warInfo.alarmLevelName }}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label">
告警时间
</template>
{{ warInfo.createTime }}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label">
告警区域
</template>
{{ warInfo.areaName }}
</el-descriptions-item>
</el-descriptions>
<span>备注</span>
<el-input
style="margin-top: 12px;margin-bottom:12px"
type="textarea"
:rows="2"
placeholder="请输入内容"
v-model="textarea">
</el-input>
<span slot="footer" class="dialog-footer">
<el-button @click="isDispose = false"> </el-button>
<el-button type="primary" @click="disposeThis"></el-button>
<el-button type="primary" @click="disposeAll"></el-button>
</span>
</el-dialog>
2 years ago
</div>
</template>
<script>
import Chart from "@/components/Charts/Chart";
import vueSeamlessScroll from "vue-seamless-scroll";
import * as echarts from 'echarts';
2 years ago
import {
alarmStats,
subDevice,
getAlarmInfos,
1 year ago
ElectronicNumVo,
selectDeviceLatitudeAndLongitude
2 years ago
} from '@/api/board/GPS'
2 years ago
import red from '@/assets/board/GPS/red.png'
import green from '@/assets/board/GPS/green.png'
2 years ago
import {handleAlarmInfo} from "@/api/board/index";
1 year ago
import {selectBeaconDevicesHistory} from "../../../api/board/GPS";
1 year ago
import {selectMonitorElectronic} from "../../../api/board";
let map = null
let polyEditor = null
1 year ago
let texts = []
let polygons = []
let circles = []
2 years ago
export default {
components: {
Chart,
vueSeamlessScroll,
},
2 years ago
watch: {
async $route(to, from) {
2 years ago
await this.getData()
}
},
2 years ago
data() {
return {
12 months ago
warInfo: {},
textarea: '',
isDispose: false,
disposeNo: '',
loading: false,
equipmentInfo: {},
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,
},
2 years ago
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: [],
1 year ago
table2Data: [],
sceneId: 0,
1 year ago
isRail: false,
form: {},
total: 100,
historyDialog: false,
historyData: []
2 years ago
}
},
2 years ago
async mounted() {
2 years ago
await this.getData()
2 years ago
},
methods: {
async getData() {
2 years ago
if (this.$store.getters.sceneId === null) return
await this.createMap()
await this.getAlarmStats()
await this.getAubDevice()
await this.setAlarmInfos()
await this.setElectronicNumVo()
1 year ago
await this.getTable2Data()
},
2 years ago
dispose(e) {
12 months ago
this.warInfo = e
this.textarea = ''
this.isDispose = true
this.disposeNo = e.no
2 years ago
},
createMap() {
2 years ago
map = new AMap.Map('map', {
// mapStyle: 'amap://styles/blue',
2 years ago
zoom: 11,
center: [113.4, 23.35],
});
},
setText(e) {
2 years ago
let position = e.areaPoints?.length > 0 ? e.areaPoints : e.centerPoint
if (position.length > 0) {
let length = position.length
2 years ago
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({
2 years ago
text: '<div style="color:#fff;width: 100%;height: 100%;">' + '总数:' + e.deviceCount + (e.abnormalCount ? ('/异常数量:' + e.abnormalCount) : '') + '</div>',
anchor: 'center',
draggable: true,
cursor: 'pointer',
2 years ago
position: position
});
2 years ago
text.setStyle({
1 year ago
'background-color': e.abnormalCount ? '#fe0000' : '#0055fe',
padding: '4px 12px',
'font-size': '1vw'
2 years ago
})
map.add(text)
1 year ago
texts.push(text)
},
2 years ago
setPolygon(position, val) {
let e = position.map(val => {
return [val.longitude, val.latitude]
})
let thisPolygon = new AMap.Polygon({
path: e,
2 years ago
fillColor: val > 0 ? '#ff0000' : '#1791fc',
});
map.add(thisPolygon)
map.setFitView()
1 year ago
polygons.push(thisPolygon)
},
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],
2 years ago
fillColor: e > 0 ? '#ff0000' : '#1791fc',
})
map.add(circle);
map.setFitView()
1 year ago
circles.push(circle)
2 years ago
},
async getAlarmStats() {
2 years ago
if (this.$store.getters.sceneId === null) return
2 years ago
const {data} = await alarmStats(this.$store.getters.sceneId)
2 years ago
},
async getAubDevice() {
2 years ago
let data = await subDevice(this.$store.getters.sceneId)
this.num1 = data.deviceNum
this.num2 = data.subSum
this.num3 = data.onlineDeviceNum
},
async setAlarmInfos() {
2 years ago
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() {
1 year ago
if (!this.isRail) {
return
}
2 years ago
const {data} = await ElectronicNumVo(this.$store.getters.sceneId)
data.forEach(e => {
if (e.areaPoints?.length > 0) {
2 years ago
this.setPolygon(e.areaPoints, e.abnormalCount)
}
if (e.centerPoint) {
this.setCircle([e.centerPoint.longitude, e.centerPoint.latitude], e.radius, e.abnormalCount)
}
this.setText(e)
})
1 year ago
},
1 year ago
RailChange(e) {
if (e) {
1 year ago
this.setElectronicNumVo()
1 year ago
} else {
1 year ago
map.remove(texts)
map.remove(polygons)
map.remove(circles)
}
1 year ago
},
async getTable2Data() {
const {data} = await selectDeviceLatitudeAndLongitude(this.$store.getters.sceneId)
this.table2Data = data
data.forEach(e => {
this.setMarker(e)
})
},
setMarker(e) {
let marker = new AMap.Marker({
position: [e.longitude, e.latitude], // 经纬度对象,也可以是经纬度构成的一维数组[116.39, 39.9]
title: `信息\n经度${e.longitude}\n纬度${e.latitude}\n名称${e.deviceLocation}\n备注${e.remark}`,
offset: new AMap.Pixel(-15, -30),
content: `<div >
<svg t="1718261114618" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4305" style="width: 30px;height: 30px;">
12 months ago
<path d="M512 64.5c-180.5 0-326.9 146.4-326.9 326.9 0 63.3 18 122.3 49.2 172.4 1.1 2 2.1 4 3.2 5.9 34.9 58.2 113.9 128.8 165.5 194.5 66.3 84.4 93.2 158 93.2 158 1.6 1.4 13.1 35.6 15.1 35.8 2.5 0.2 12.6-34 14.5-35.8 0 0 22-69.2 83.7-146.6 56-70.1 142.8-145.7 177-206 0.9-1.6 1.8-3.3 2.6-5 31.5-50.2 49.7-109.6 49.7-173.3 0.1-180.5-146.3-326.8-326.8-326.8z" fill="${(e.ifAlarm === '1') ? '#3D93FD' : '#ff0000'}" p-id="4306">
1 year ago
</path>
</svg>
</div>`
});
1 year ago
marker.on('click', async () => {
12 months ago
if (polygons.length > 0 || circles.length > 0) {
12 months ago
map.remove(polygons)
map.remove(circles)
polygons = []
circles = []
return
}
1 year ago
const {data} = await selectMonitorElectronic(e.deviceId)
data.map(e => e.hwFenceAreaList).flat(1).forEach(e => {
if (e.areaShapeFlag === '1') {
this.setPolygon(e.areaRange.split('_').map(e => e.split(',').map(v => parseFloat(v))))
}
if (e.areaShapeFlag === '2') {
let arr = e.areaRange.split(',')
this.setCircle([arr[0], arr[1]], arr[2])
}
})
1 year ago
})
map.add(marker);
},
mapOrientation(e) {
map.setZoomAndCenter(16, [e.longitude, e.latitude])
},
12 months ago
toEquipmentInfo(e) {
this.equipmentInfo = e
console.log(e)
1 year ago
this.historyDialog = true
this.form = {
pageNum: 1,
pageSize: 10,
deviceId: e.deviceId,
time: [],
}
this.getHistoryData()
// this.$router.push(`/board/senso?id=${e.deviceId}&deviceModeId=${e.deviceModeId}`)
1 year ago
},
async getHistoryData() {
12 months ago
this.loading = true
1 year ago
let query = this.form
query.startTime = this.form.time?.[0]?.getTime()
query.endTime = this.form.time?.[1]?.getTime()
delete query.time
const data = await selectBeaconDevicesHistory(query)
12 months ago
this.loading = false
1 year ago
this.historyData = data.rows
this.total = data.total
2 years ago
}
}
};
</script>
1 year ago
<style scoped lang="less">
2 years ago
.container {
background-image: url("~@/assets/board/GPS/bg.jpg");
background-repeat: no-repeat;
background-size: 100% 100%;
width: 100%;
height: calc(100vh);
position: relative;
}
1 year ago
.table2 {
2 years ago
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 {
2 years ago
position: absolute;
top: 28%;
left: 31%;
width: 67%;
height: 69%;
}
1 year ago
.isRail {
position: absolute;
top: 25%;
left: 31%;
/*transform: translate(-50%,-50%);*/
/deep/ .el-switch__label {
color: #fff;
}
/deep/ .el-switch__label.is-active {
color: #1890ff;
}
}
2 years ago
</style>