Files
dyf-vue-ui/src/views/homeIndex/components/MapComponent.vue

706 lines
17 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="content">
<div class="map" id="map" v-loading="Status.loading" element-loading-background="#022D51a8"></div>
<div class="topTool">
<div class="form">
<div class="form-item">
<div class="vertiLine"></div>
<div class="input" @click.stop="showCheck('showCheckGroup')">
<div>{{ groupName }}</div>
<div class="iconContent">
<div class="arrow">
<el-icon v-show="!Status.showCheckGroup"><CaretBottom /></el-icon>
<el-icon v-show="Status.showCheckGroup"><CaretTop /></el-icon>
</div>
<div class="clear" @click.stop="search.groupId=''">
<el-icon ><CloseBold /></el-icon>
</div>
</div>
</div>
<div class="ul" :class="Status.showCheckGroup ? '' : 'displayNone'">
<div
class="li"
@click.stop="checkItem(item, 'groupId')"
:class="item.value === search.groupId ? 'active' : ''"
v-for="item in groups"
:style="{ paddingLeft: `${(item.level - 1) * 16}px` }"
>
{{ item.label }}
</div>
</div>
</div>
<div class="form-item">
<div class="vertiLine"></div>
<div class="input" @click.stop="showCheck('showCheckType')">
<div>{{ devType }}</div>
<div class="iconContent">
<div class="arrow">
<el-icon v-show="!Status.showCheckType"><CaretBottom /></el-icon>
<el-icon v-show="Status.showCheckType"><CaretTop /></el-icon>
</div>
<div class="clear" @click.stop="search.deviceType=''">
<el-icon ><CloseBold /></el-icon>
</div>
</div>
</div>
<div class="ul" :class="Status.showCheckType ? '' : 'displayNone'">
<div
class="li"
@click.stop="checkItem(item, 'deviceType')"
:class="item.value === search.deviceType ? 'active' : ''"
v-for="item in types"
>
{{ item.label }}
</div>
</div>
</div>
<div class="form-item">
<div class="vertiLine"></div>
<input type="text" class="input" @focus="hideCheck()" v-model="search.deviceImei" placeholder="设备IMEI" />
</div>
<div class="searchBtn" @click="getPoints()">查询</div>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import common from '@/utils/common';
import map from '@/api/largeScreen/mapOpt';
import request from '@/utils/request';
import mapPoint from '@/assets/images/mapPoint.png';
import mapWarn from '@/assets/images/mapWarn.png';
var groups = ref([]);
var types = ref([]);
var search = ref({
groupId: '',
deviceType: '',
deviceImei: ''
});
var points = ref([]);
var fens = ref([]);
var Status = reactive({
loading: false,
showCheckGroup: false,
showCheckType: false
});
//假数据
function getFakeData() {
return [
{
'deviceId': 1001,
'deviceName': '智能监控设备-01',
'longitude': '116.39748',
'latitude': '39.90882',
'isAlarming': true,
'fenceInfo': {
'id': 5002,
'name': '圆形电子围栏',
'description': '覆盖东城区主要街道',
'areaType': 1,
'coordinates': [{ 'longitude': '116.39768', 'latitude': '39.89482' }],
'radius': 500,
'isActive': 1
}
},
{
'deviceId': 1002,
'deviceName': '环境监测终端-02',
'longitude': '116.41748',
'latitude': '39.92882',
'isAlarming': false,
'fenceInfo': {
'id': 5001,
'name': '东城区电子围栏',
'description': '覆盖东城区主要街道',
'areaType': 0,
'coordinates': [
{ 'longitude': '116.38748', 'latitude': '39.91882' },
{ 'longitude': '116.40748', 'latitude': '39.90882' },
{ 'longitude': '116.39748', 'latitude': '39.89882' }
],
'radius': 500,
'isActive': 1
}
},
{
'deviceId': 1003,
'deviceName': '智能停车桩-03',
'longitude': '116.43748',
'latitude': '39.94882',
'isAlarming': true,
'fenceInfo': {
'id': 5001,
'name': '东城区电子围栏',
'description': '覆盖东城区主要街道',
'areaType': 0,
'coordinates': [
{ 'longitude': '116.38748', 'latitude': '39.91882' },
{ 'longitude': '116.40748', 'latitude': '39.90882' },
{ 'longitude': '116.39748', 'latitude': '39.89882' }
],
'radius': 500,
'isActive': 1
}
},
{
'deviceId': 1004,
'deviceName': '智慧路灯-04',
'longitude': '116.45748',
'latitude': '39.96882',
'isAlarming': true,
'fenceInfo': {
'id': 5001,
'name': '东城区电子围栏',
'description': '覆盖东城区主要街道',
'areaType': 0,
'coordinates': [
{ 'longitude': '116.38748', 'latitude': '39.91882' },
{ 'longitude': '116.40748', 'latitude': '39.90882' },
{ 'longitude': '116.39748', 'latitude': '39.89882' }
],
'radius': 500,
'isActive': 1
}
},
{
'deviceId': 1005,
'deviceName': '水质监测仪-05',
'longitude': '116.37748',
'latitude': '39.88882',
'isAlarming': false,
'fenceInfo': {
'id': 5001,
'name': '东城区电子围栏',
'description': '覆盖东城区主要街道',
'areaType': 0,
'coordinates': [
{ 'longitude': '116.38748', 'latitude': '39.91882' },
{ 'longitude': '116.40748', 'latitude': '39.90882' },
{ 'longitude': '116.39748', 'latitude': '39.89882' }
],
'radius': 500,
'isActive': 1
}
},
{
'deviceId': 1006,
'deviceName': '智能门禁-06',
'longitude': '116.35748',
'latitude': '39.99882',
'isAlarming': true,
'fenceInfo': {
'id': 5001,
'name': '东城区电子围栏',
'description': '覆盖东城区主要街道',
'areaType': 0,
'coordinates': [
{ 'longitude': '116.38748', 'latitude': '39.91882' },
{ 'longitude': '116.40748', 'latitude': '39.90882' },
{ 'longitude': '116.39748', 'latitude': '39.89882' }
],
'radius': 500,
'isActive': 1
}
},
{
'deviceId': 1007,
'deviceName': '消防传感器-07',
'longitude': '116.47748',
'latitude': '39.87882',
'isAlarming': true,
'fenceInfo': {
'id': 5001,
'name': '东城区电子围栏',
'description': '覆盖东城区主要街道',
'areaType': 0,
'coordinates': [
{ 'longitude': '116.38748', 'latitude': '39.91882' },
{ 'longitude': '116.40748', 'latitude': '39.90882' },
{ 'longitude': '116.39748', 'latitude': '39.89882' }
],
'radius': 500,
'isActive': 1
}
},
{
'deviceId': 1008,
'deviceName': '气象站-08',
'longitude': '116.49748',
'latitude': '39.91882',
'isAlarming': false,
'fenceInfo': {
'id': 5001,
'name': '东城区电子围栏',
'description': '覆盖东城区主要街道',
'areaType': 0,
'coordinates': [
{ 'longitude': '116.38748', 'latitude': '39.91882' },
{ 'longitude': '116.40748', 'latitude': '39.90882' },
{ 'longitude': '116.39748', 'latitude': '39.89882' }
],
'radius': 500,
'isActive': 1
}
},
{
'deviceId': 1009,
'deviceName': '智能垃圾桶-09',
'longitude': '116.33748',
'latitude': '39.86882',
'isAlarming': true,
'fenceInfo': {
'id': 5001,
'name': '东城区电子围栏',
'description': '覆盖东城区主要街道',
'areaType': 0,
'coordinates': [
{ 'longitude': '116.38748', 'latitude': '39.91882' },
{ 'longitude': '116.40748', 'latitude': '39.90882' },
{ 'longitude': '116.39748', 'latitude': '39.89882' }
],
'radius': 500,
'isActive': 1
}
},
{
'deviceId': 1010,
'deviceName': '充电桩-10',
'longitude': '116.31748',
'latitude': '39.93882',
'isAlarming': true,
'fenceInfo': {
'id': 5001,
'name': '东城区电子围栏',
'description': '覆盖东城区主要街道',
'areaType': 0,
'coordinates': [
{ 'longitude': '116.38748', 'latitude': '39.91882' },
{ 'longitude': '116.40748', 'latitude': '39.90882' },
{ 'longitude': '116.39748', 'latitude': '39.89882' }
],
'radius': 500,
'isActive': 1
}
}
];
}
let time = null;
function getPoints() {
hideCheck();
clearTimeout(time);
setTimeout(() => {
Status.loading = true;
let promise = request({
url:
'/api/largeScreen/getDeviceLocationInfo?groupId=' +
search.value.groupId +
'&deviceType=' +
search.value.deviceType +
'&deviceImei=' +
search.value.deviceImei,
method: 'get'
});
// let fakeData = getFakeData();
promise
.then((res) => {
map.clearOverLays();
if (res) {
if (res.code && res.code == 200) {
var array = res.data;
// if (!array.length) {
// // ElMessage.error('未查询到任何数据,以下展示假数据,仅供查看效果,正式上线时取消');
// // array = fakeData;
// // return;
// }
let promise = [];
for (let i = 0; i < array.length; i++) {
let v = array[i];
let json = {
deviceId: v.deviceId,
deviceName: v.deviceName,
longitude: v.longitude,
latitude: v.latitude,
fenceId: null,
isAlarming: v.isAlarming
};
if (v.fenceInfo) {
fens.value.find((item) => {
return item.id == v.fenceInfo.id;
});
json.fenceId = v.fenceInfo.id;
fens.value.push(v.fenceInfo);
}
points.value.push(json);
promise.push(map.AddPoint(json, '', null, null, json.isAlarming ? mapWarn : mapPoint));
}
if (fens.value && fens.value.length > 0) {
for (let i = 0; i < fens.value.length; i++) {
let f = fens.value[i];
if (f.areaType === 0) {
promise.push(map.DrawPoy(f));
} else {
promise.push(map.DrawCicle(f, f.radius, null));
}
}
}
Promise.allSettled(promise).then((res) => {
// map.setFitView();
let center=map.calcCenter();
map.setCenter(center.lng,center.lat);
});
} else {
console.error('接口getDeviceLocationInfo出现了未知的异常', res);
}
} else {
console.error('接口getDeviceLocationInfo出现了未知的异常', res);
}
})
.finally(() => {
Status.loading = false;
});
}, 200);
}
function getTypes() {
let promise = request({
url: '/api/deviceType/all',
method: 'get'
});
promise.then((res) => {
if (res && res.code && res.code == 200) {
if (res.data.length) {
types.value = res.data.map((v) => {
return {
value: v.id,
label: v.typeName
};
});
} else {
for (let i = 0; i < 5; i++) {
types.value.push({
value: i,
label: '类型' + (i + 1)
});
}
}
}
});
}
function getGroups() {
let promise = request({
url: '/api/device/group/list',
method: 'get',
params: {
status: 1,
isDeleted: 0,
pageNum: 1,
pageSize: 9999
}
});
let flattenTree = (nodes, currentLevel = 1) => {
let result = [];
nodes.forEach((node) => {
// 复制当前节点添加level字段移除children属性
const { children, ...rest } = node;
const nodeWithLevel = {
...rest,
level: currentLevel // 添加层级信息
};
// 将当前节点添加到结果数组
result.push(nodeWithLevel);
// 如果有子节点,递归处理并将层级+1
if (children && children.length > 0) {
result = result.concat(flattenTree(children, currentLevel + 1));
}
});
return result;
};
promise.then((res) => {
if (res && res.code && res.code == 200) {
let arr = res.data;
arr = flattenTree(arr);
if (arr.length) {
groups.value = arr.map((v) => {
return {
value: v.id,
label: v.groupName,
level: v.level
};
});
} else {
let array = [];
for (let i = 0; i < 5; i++) {
array.push({
value: i,
label: '假数据' + (i + 1),
level: (i % 3) + 1
});
}
groups.value = array;
}
}
});
}
function checkItem(item, type) {
if (search.value[type] === item.value) {
return;
}
search.value[type] = item.value;
hideCheck();
}
var groupName = computed(() => {
if (search.value.groupId) {
let f = groups.value.find((v) => {
return v.value === search.value.groupId;
});
if (f) {
return f.label;
}
}
return '所属分组';
});
var devType = computed(() => {
if (search.value.deviceType) {
let f = types.value.find((v) => {
return v.value === search.value.deviceType;
});
if (f) {
return f.label;
}
}
return '设备类型';
});
function hideCheck() {
Status.showCheckGroup = false;
Status.showCheckType = false;
}
function showCheck(type) {
if (type == 'showCheckGroup') {
Status.showCheckType = false;
} else {
Status.showCheckGroup = false;
}
Status[type] = !Status[type];
}
onMounted(() => {
map.initMap(hideCheck).then((res) => {
setInterval(getPoints,300000);
});
getTypes();
getGroups();
});
</script>
<style lang="scss" scoped>
.content {
width: 100vw;
height: 100vh;
}
.el-icon {
color: #007eff;
font-size: 1vw;
}
.map {
width: 100%;
height: 100%;
}
.topTool {
position: absolute;
width: 100%;
height: 45px;
z-index: 99;
background: #00000000;
top: 100px;
display: flex;
flex-direction: row;
flex-wrap: nowrap;
align-content: flex-start;
align-items: flex-start;
justify-content: center;
}
.topTool .form-item {
width: calc(calc(100% - 160px) / 3);
height: 5vh;
border: none;
}
:deep .el-select__wrapper,
:deep .el-input__wrapper {
border: none;
height: 7vh;
}
:deep .el-select__wrapper,
:deep .el-input__wrapper,
.topTool .form-item {
background: url(@/assets/homeIndex/select.png) no-repeat;
}
.topTool .form {
width: 43%;
display: flex;
flex-direction: row;
flex-wrap: nowrap;
align-content: center;
justify-content: space-around;
align-items: center;
}
.topTool .searchBtn {
background: linear-gradient(to bottom, #006aae2e, #0056b7);
font-family: MicrosoftYaHei;
font-size: 16px;
color: #ddf4ff;
line-height: 45px;
width: 100px;
height: 45px;
text-align: left;
font-style: normal;
text-transform: none;
text-align: center;
border-radius: 34px;
cursor: pointer;
}
.form-item1 {
width: 144px;
height: 44px;
background: linear-gradient(to bottom, #007eff 0%, /* 顶部红色 */ #00efed 48%, /* 中间蓝色 */ #1d5df4 100% /* 底部红色 */);
opacity: 0.35;
}
.topTool .form-item {
display: flex;
position: relative;
}
.topTool .form-item .input {
width: 100%;
height: 100%;
background-color: #00000000;
border: none;
box-sizing: border-box;
padding: 0px 10px;
line-height: 4.5vh;
outline: none;
font-family: MicrosoftYaHei;
font-size: 15px;
color: #deefff;
width: calc(100% - 6px);
display: flex;
flex-direction: row;
flex-wrap: nowrap;
align-content: center;
justify-content: space-between;
}
.topTool .form-item input::placeholder {
font-family: MicrosoftYaHei;
font-size: 15px;
color: #deefff;
line-height: 4vh;
}
.topTool .form-item input:focus {
outline: none;
caret-color: #ffffff;
}
.topTool .form-item .vertiLine {
width: 6px;
height: 100%;
// background: radial-gradient(0% 0% at 0% 0%, #00d6ef 0%, #007eff 100%);
}
.topTool .form-item .ul {
width: 100%;
height: auto;
position: absolute;
top: 100%;
left: 0px;
min-height: 30px;
background: #022e51cc;
}
.topTool .form-item .li {
height: 40px;
line-height: 40px;
text-indent: 10px;
cursor: pointer;
font-family: MicrosoftYaHei;
font-size: 15px;
color: #deefff;
text-align: left;
font-style: normal;
text-transform: none;
font-weight: 300;
box-sizing: border-box;
width: 100%;
}
.topTool .form-item .li.active {
color: #00fcff;
}
.topTool .form-item .li:hover {
background: #007eff59;
color: #00fcff;
}
.displayNone {
display: none !important;
}
.iconContent:hover .arrow{
display: none;
}
.iconContent .clear{
display: none;
}
.iconContent:hover .clear{
display: block;
}
</style>