修改地图

breach-zhy
夜笙歌 3 months ago
parent dedabc579f
commit f52e3319f3

@ -7,7 +7,6 @@
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<title><%= webpackConfig.name %></title>
<script src="http://api.tianditu.gov.cn/api?v=4.0&tk=e0c4dfdc0b3c99c4b39eaaecf06eebee" type="text/javascript"></script>
<!--[if lt IE 11]><script>window.location.href='/html/ie.html';</script><![endif]-->
<style>
html,

@ -33,3 +33,21 @@ export function ElectronicNumVo(query) {
method: 'get',
})
}
// 右下
export function selectDeviceLatitudeAndLongitude(query) {
return request({
// baseURL:'/monitoring-api',
url: '/business/monitorPlatform/selectDeviceLatitudeAndLongitude/'+query,
method: 'get',
})
}
// 获取历史记录
export function selectBeaconDevicesHistory(query) {
return request({
// baseURL:'/monitoring-api',
url: 'business/monitorPlatform/selectBeaconDevicesHistory',
method: 'get',
params:query
})
}

@ -1,4 +1,4 @@
import request from '@/utils/request'
import request,{download} from '@/utils/request'
// 树
export function treeList(query=0) {
@ -35,3 +35,27 @@ export function publishControlCommand(query=0) {
data:query
})
}
// 历史记录
export function selectHistoryAndTrendAnalysis(data) {
return request({
url: 'business/monitorPlatform/selectHistoryAndTrendAnalysis',
method: 'get',
params:data
})
}
// 传感器属性
export function selectComparison(data) {
return request({
url: '/business/monitorPlatform/selectComparison',
method: 'get',
params:data
})
}
// 历史记录
export function exportData(data,name) {
return download('/business/monitorPlatform/export',data,name,{},{type:'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'})
}

@ -54,3 +54,41 @@ export function handleAlarmInfo(query) {
data:query
})
}
// 地图信息
export function getDeviceByAreaId(query) {
return request({
// baseURL:'/monitoring-api',
url: 'business/monitorPlatform/getDeviceByAreaId/'+query,
method: 'get',
})
}
// 获取租户信息
export function getTenantData(query) {
return request({
// baseURL:'/monitoring-api',
url: '/business/tenant/'+query,
method: 'get',
})
}
// 获取电子围栏
export function selectMonitorElectronic(query) {
return request({
// baseURL:'/monitoring-api',
url: '/business/monitorPlatform/selectMonitorElectronic/'+query,
method: 'get',
})
}
// 搜索地图标点
export function selectDeviceByName(query) {
return request({
// baseURL:'/monitoring-api',
url: '/business/monitorPlatform/selectDeviceByName',
method: 'post',
data:query
})
}

@ -1,6 +1,6 @@
<template>
<div>
<div class="title">智慧物联监控平台</div>
<div class="title">{{ tenantData.tenantBoardTopic || '智慧物联监控平台' }}</div>
<div>
<div v-if="isIndex" :class="`menu ${nowMenu==='1'? 'menuClick' :''}`" style="left: 2%"
@click="toLink('index','1')">
@ -14,7 +14,8 @@
{{ name }} <i class="el-icon-arrow-down el-icon--right"></i>
</span>
<el-dropdown-menu slot="dropdown">
<div class="topNavScroll" style="max-height: 300px;overflow: auto;background-color: #053563;padding: 0;border: none;">
<div class="topNavScroll"
style="max-height: 300px;overflow: auto;background-color: #053563;padding: 0;border: none;">
<el-dropdown-item v-for="i in selectSecnesList" :key="i.sceneId"
:command="{router:i.router,name:i.sceneName,sceneId:i.sceneId}">
<span style="color: #f8fefd">
@ -56,6 +57,10 @@ import {
selectSecnes
} from '@/api/board/nav'
import {
getTenantData
} from '@/api/board/index'
export default {
name: 'BoardTopNav',
data() {
@ -64,7 +69,8 @@ export default {
name: '智慧场景',
isIndex: true,
sceneId: this.$store.getters.sceneId,
nowMenu: '1'
nowMenu: '1',
tenantData:{},
}
},
// props: {
@ -75,6 +81,9 @@ export default {
// },
async mounted() {
getTenantData(this.$store.getters.tenantId).then(e=>{
this.tenantData = e.data
})
if (!this.$store.getters.sceneId) {
this.$router.replace({path: "/board/index"})
}
@ -205,10 +214,12 @@ export default {
padding: 0 !important;
border: none !important;
}
.topNavScroll::-webkit-scrollbar {
width: 0px;
height: 0px;
}
.el-dropdown-menu__item:not(.is-disabled):hover span {
color: #053563 !important;
}

@ -17,5 +17,6 @@ const getters = {
sidebarRouters:state => state.permission.sidebarRouters,
language: state => state.app.language,
sceneId: state => state.app.sceneId,
tenantId: state => state.user.tenantId,
}
export default getters

@ -7,7 +7,8 @@ const user = {
name: '',
avatar: '',
roles: [],
permissions: []
permissions: [],
tenantId:null
},
mutations: {
@ -20,6 +21,9 @@ const user = {
SET_NAME: (state, name) => {
state.name = name
},
SET_TENANTID: (state, tenantId) => {
state.tenantId = tenantId
},
SET_AVATAR: (state, avatar) => {
state.avatar = avatar
},
@ -56,6 +60,7 @@ const user = {
GetInfo({ commit, state }) {
return new Promise((resolve, reject) => {
getInfo().then(res => {
commit('SET_TENANTID', res.user.tenantId)
const user = res.user
const avatar = (user.avatar == "" || user.avatar == null) ? require("@/assets/images/hwlogo.png") : user.avatar;
if (res.roles && res.roles.length > 0) { // 验证返回的roles是否是一个非空数组

@ -117,7 +117,7 @@ service.interceptors.response.use(res => {
)
// 通用下载方法
export function download(url, params, filename, config) {
export function download(url, params, filename, config,type) {
downloadLoadingInstance = Loading.service({ text: "正在下载数据,请稍候", spinner: "el-icon-loading", background: "rgba(0, 0, 0, 0.7)", })
return service.post(url, params, {
transformRequest: [(params) => { return tansParams(params) }],
@ -127,7 +127,7 @@ export function download(url, params, filename, config) {
}).then(async (data) => {
const isBlob = blobValidate(data);
if (isBlob) {
const blob = new Blob([data])
const blob = new Blob([data],type)
saveAs(blob, filename)
} else {
const resText = await data.text();

@ -3,16 +3,16 @@
<div class="centerImg"></div>
<div class="table2">
<div style="background-color: #094170">
<div class="scrollTable" style="font-weight: bold;">
<div class="scrollTable" style="font-weight: bold;width: 20%">
设备名称
</div>
<div class="scrollTable" style="font-weight: bold;">
<div class="scrollTable" style="font-weight: bold;width: 20%">
经度
</div>
<div class="scrollTable" style="font-weight: bold;">
<div class="scrollTable" style="font-weight: bold;width: 20%">
纬度
</div>
<div class="scrollTable" style="font-weight: bold;">
<div class="scrollTable" style="font-weight: bold;width: 40%">
操作
</div>
</div>
@ -29,20 +29,20 @@
>
<div :style='"background-color:" + ((index % 2 === 0)? "#053460":"#032d57") '>
<div
class="scrollTable">
{{ item.value1 }}
class="scrollTable" style="width: 20%">
{{ item.deviceName }}
</div>
<div
class="scrollTable">
{{ item.value2 }}
class="scrollTable" style="width: 20%">
{{ item.longitude }}
</div>
<div
class="scrollTable">
{{ item.value3 }}
class="scrollTable" style="width: 20%">
{{ item.latitude }}
</div>
<div class="scrollTable" style="width: 25%">
<el-button size="mini" type="primary" @click="dispose(item)"></el-button>
<el-button size="mini" type="primary" @click="dispose(item)"></el-button>
<div class="scrollTable" style="width: 40%">
<el-button size="mini" type="primary" @click=" mapOrientation(item)">地图定点</el-button>
<el-button size="mini" type="primary" @click="equipmentInfo(item)"></el-button>
</div>
</div>
</div>
@ -114,6 +114,51 @@
inactive-text="隐藏电子围栏">
</el-switch>
</div>
<el-dialog title="历史记录" :visible.sync="historyDialog">
<el-form :inline="true" :model="form" class="demo-form-inline">
<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
:data="historyData"
style="width: 100%">
<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="采集时间">
</el-table-column>
</el-table>
<pagination
v-show="total>0"
:total="total"
:page.sync="form.pageNum"
:limit.sync="form.pageSize"
@pagination="getHistoryData"
/>
</el-dialog>
</div>
</template>
@ -125,11 +170,13 @@ import {
alarmStats,
subDevice,
getAlarmInfos,
ElectronicNumVo
ElectronicNumVo,
selectDeviceLatitudeAndLongitude
} 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";
import {selectBeaconDevicesHistory} from "../../../api/board/GPS";
let map = null
let polyEditor = null
@ -196,7 +243,11 @@ export default {
table1Data: [],
table2Data: [],
sceneId: 0,
isRail: true,
isRail: false,
form: {},
total: 100,
historyDialog: false,
historyData: []
}
},
async mounted() {
@ -210,6 +261,7 @@ export default {
await this.getAubDevice()
await this.setAlarmInfos()
await this.setElectronicNumVo()
await this.getTable2Data()
},
dispose(e) {
this.$confirm('该问题已处理?', '提示', {
@ -320,9 +372,11 @@ export default {
status: e.handleStatus
}
})
this.table2Data = this.table1Data
},
async setElectronicNumVo() {
if (!this.isRail) {
return
}
const {data} = await ElectronicNumVo(this.$store.getters.sceneId)
data.forEach(e => {
if (e.areaPoints?.length > 0) {
@ -334,14 +388,62 @@ export default {
this.setText(e)
})
},
RailChange(e){
if(e){
RailChange(e) {
if (e) {
this.setElectronicNumVo()
}else{
} else {
map.remove(texts)
map.remove(polygons)
map.remove(circles)
}
},
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;">
<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="#3D93FD" p-id="4306">
</path>
</svg>
</div>`
});
marker.on('click', () => {
this.historyDialog = true
this.form = {
pageNum: 1,
pageSize: 10,
deviceId: e.deviceId,
time: [],
}
this.getHistoryData()
})
map.add(marker);
},
mapOrientation(e) {
map.setZoomAndCenter(16, [e.longitude, e.latitude])
},
equipmentInfo(e) {
this.$router.push(`/board/senso?id=${e.deviceId}&deviceModeId=${e.deviceModeId}`)
},
async getHistoryData() {
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)
this.historyData = data.rows
this.total = data.total
}
}
};

@ -1,5 +1,6 @@
<template>
<div class="container" :style="'background-image: url('+((controlList&& controlList.length === 0) ? bgImg1 : bgImg)+')'">
<div class="container"
:style="'background-image: url('+((controlList&& controlList.length === 0) ? bgImg1 : bgImg)+')'">
<div class="title1">监控设备</div>
<div class="centerImg"></div>
<div class="title">监控单元</div>
@ -37,11 +38,6 @@
:style="'background-image: url('+(MonitorInfo.monitorPic ? MonitorInfo.monitorPic :defaultImg)+');'"
:class="((controlList&& controlList.length === 0) ? 'img1' : 'img')"></div>
<div class="terminal">
<!--el-form :model="form" class="demo-form-inline">
<el-form-item label="传感器名称:">
<el-input v-model="form.data1" placeholder="传感器名称" style="width:calc(100% - 100px)"></el-input>
</el-form-item>
</el-form-->
<div class="terminalList">
<div v-for="(i,k) in controlList" class="item">
<div :style="'background-image: url('+(i.devicePic ? i.devicePic :defaultImg1)+');'" class="icon"></div>
@ -107,6 +103,138 @@
</div>
</div>
</div>
<el-dialog title="历史记录" :visible.sync="historyDialog">
<el-form :inline="true" :model="form" class="demo-form-inline">
<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 label="查询类型">
<el-select v-model="form.type" placeholder="">
<el-option label="趋势分析" value="1"></el-option>
<el-option label="历史数据" value="2"></el-option>
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="getHistoryData"></el-button>
</el-form-item>
</el-form>
<div style="margin-bottom: 12px">
<el-button type="primary" @click="exportF"></el-button>
<el-button type="success" @click="comparison"></el-button>
</div>
<el-table
:data="historyData"
style="width: 100%">
<el-table-column
type="index"
width="50">
</el-table-column>
<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="采集时间">
</el-table-column>
</el-table>
<pagination
v-show="total>0"
:total="total"
:page.sync="form.pageNum"
:limit.sync="form.pageSize"
@pagination="getHistoryData"
/>
</el-dialog>
<el-dialog title="对比" :visible.sync="comparisonDialog">
<el-form ref="form1" :rules="rules" :inline="true" :model="form1" class="demo-form-inline">
<el-form-item label="查询时间" prop="time">
<el-date-picker
v-model="form1.time"
type="datetimerange"
range-separator="至"
start-placeholder="开始日期"
end-placeholder="结束日期">
</el-date-picker>
</el-form-item>
<el-form-item label="传感器" prop="sensor">
<el-cascader
v-model="sensorData"
:options="sensorOptions"
:props="props"
collapse-tags
@change="sensorChange"
clearable></el-cascader>
</el-form-item>
<el-form-item label="对比属性" prop="prop">
<el-select v-model="form1.prop" placeholder="">
<el-option v-for="i in comparisonOptions" :label="i" :value="i"></el-option>
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="getComparisonData"></el-button>
</el-form-item>
</el-form>
<!-- <div style="margin-bottom: 12px">-->
<!-- <el-button type="primary">导出</el-button>-->
<!-- <el-button type="success">对比</el-button>-->
<!-- </div>-->
<el-table
v-if="false"
:data="historyData"
style="width: 100%">
<el-table-column
type="index"
width="50">
</el-table-column>
<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="采集时间">
</el-table-column>
</el-table>
<div>
<Chart ref="chart" class="chart"></Chart>
</div>
<pagination
v-show="total>0"
:total="total"
:page.sync="form.pageNum"
:limit.sync="form.pageSize"
@pagination="getHistoryData"
/>
</el-dialog>
</div>
</template>
@ -115,37 +243,71 @@ import {
treeList,
selectDevicesByMonitorUnitId,
getMonitorById,
publishControlCommand
publishControlCommand,
selectHistoryAndTrendAnalysis,
selectComparison,
exportData
} from '@/api/board/equipment'
import defaultImg from '@/assets/board/equipment/icon.png'
import defaultImg1 from '@/assets/board/equipment/icon2.png'
import defaultImg2 from '@/assets/board/equipment/defaultImg.png'
import bgImg from '@/assets/board/equipment/bg.jpg'
import bgImg1 from '@/assets/board/equipment/bg2.jpg'
import Chart from '@/components/Charts/Chart'
let getDeviceInterval = null
export default {
components: {},
components: {Chart},
data() {
const validatePass = (rule, value, callback) => {
if (this.sensorData.length > 5) {
return callback(new Error('最多选择五个传感器'));
} else {
callback()
}
}
return {
defaultImg,
defaultImg1,
defaultImg2,
bgImg,
bgImg1,
rules: {
sensor: [
{validator: validatePass, trigger: 'change'}
],
prop: [
{required: true, message: '请选择对比属性', trigger: 'change'}
]
},
show: false,
monitorUnitId: '',
data1: true,
form: {
data1: ''
},
treeData: [],
controlList: [],
acquisitionList: [],
MonitorInfo: {},
sceneId: 0,
deviceId: ''
deviceId: '',
historyDialog: false,
form: {},
form1: {
time: [new Date(new Date().getTime() - 1000 * 60 * 60 * 24), new Date()],
},
historyData: [],
total: 100,
comparisonDialog: false,
sensorOptions: [],
sensorData: '',
comparisonOptions: [],
props: {
multiple: true,
value: 'voId',
label: 'voName',
children: 'voList'
},
propArr: [],
}
},
async mounted() {
@ -156,6 +318,9 @@ export default {
await this.treeClick({id: this.$route.query.monitorUnitId})
}
},
beforeDestroy() {
clearInterval(getDeviceInterval)
},
methods: {
async getData() {
await this.getTree()
@ -177,7 +342,9 @@ export default {
type: 'success',
message: '成功!'
});
this.controlList.find(e => e.deviceId === deviceId).deviceType === '1' ? this.controlList.find(e => e.deviceId === deviceId).deviceType = '0' : this.controlList.find(e => e.deviceId === deviceId).deviceType = '1'
const device = this.controlList.find(e => e.deviceId === deviceId);
device.deviceType = device.deviceType === '1' ? '0' : '1';
// this.controlList.find(e => e.deviceId === deviceId).deviceType === '1' ? this.controlList.find(e => e.deviceId === deviceId).deviceType = '0' : this.controlList.find(e => e.deviceId === deviceId).deviceType = '1'
} else {
this.$message({
type: 'info',
@ -201,8 +368,6 @@ export default {
async treeClick(e) {
if (!e.children?.length > 0) {
this.monitorUnitId = e.id
await this.getDevice(e.id)
await this.setMonitorById(e)
this.show = true
@ -227,13 +392,125 @@ export default {
this.MonitorInfo = data
},
toHistory(e, i) {
console.log(i)
this.$router.push({path: "/board/senso", query: {id: e, deviceModeId: i}});
// console.log(e)
// console.log(i)
// this.$router.push({path: "/board/senso", query: {id: e, deviceModeId: i}});
this.historyDialog = true
this.form = {
pageNum: 1,
pageSize: 10,
deviceIds: e,
time: [new Date(new Date().getTime() - 1000 * 60 * 60 * 24), new Date()],
type: "2",
}
this.getHistoryData()
},
async getHistoryData() {
let query = JSON.parse(JSON.stringify(this.form))
query.startTime = this.parseTime(this.form.time?.[0]?.getTime())
query.endTime = this.parseTime(this.form.time?.[1]?.getTime())
delete query.time
const data = await selectHistoryAndTrendAnalysis(query)
this.historyData = data.rows
this.total = data.total
},
async comparison() {
this.comparisonDialog = true
const data = await selectComparison()
let propArr = []
const f = (arr) => {
arr.forEach(v => {
if (v.voList) {
f(v.voList)
} else {
propArr.push({
id: v.voId,
name: v.voName,
props: (v.prop || '').split(',')
})
}
})
}
f(data.data)
this.propArr = propArr
this.sensorOptions = data.data
},
sensorChange(e) {
let comparisonData = []
let sensorArr = []
e.forEach(v => {
sensorArr.push(v.at(-1))
comparisonData = [...new Set([...comparisonData, ...(this.propArr.find(item => item.id === v.at(-1))?.props || [])])].filter(v => v)
})
this.comparisonOptions = comparisonData
this.form1.sensor = sensorArr
},
getComparisonData() {
this.$refs['form1'].validate(async (valid) => {
if (valid) {
let query = JSON.parse(JSON.stringify({
...this.form1,
deviceIds: this.form1.sensor.join(','),
startTime: this.parseTime(this.form1.time?.[0]?.getTime()),
endTime: this.parseTime(this.form1.time?.[1]?.getTime())
}))
delete query.time
delete query.sensor
const data = await selectHistoryAndTrendAnalysis(query)
let chartData = {}
data.rows.forEach(e => {
if (chartData[e.deviceId]) {
chartData[e.deviceId].push({
value: [new Date(e.ts), e.functionIdentifier]
})
} else {
chartData[e.deviceId] = [{
value: [new Date(e.ts), e.functionIdentifier]
}]
}
})
let series = Object.keys(chartData).map(e => {
return {
name: this.propArr.find(item => item.id === parseFloat(e)).name,
type: 'line',
stack: 'Total',
data: chartData[e]
}
})
this.$refs.chart.setData({
tooltip: {
trigger: 'axis'
},
legend: {},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true
},
xAxis: {
type: 'time',
boundaryGap: false,
},
yAxis: {
type: 'value'
},
series: series
})
} else {
return false;
}
});
},
async exportF() {
let query = JSON.parse(JSON.stringify(this.form))
query.startTime = this.parseTime(this.form.time?.[0]?.getTime())
query.endTime = this.parseTime(this.form.time?.[1]?.getTime())
delete query.time
const data = exportData(query, '历史数据')
console.log(data)
}
},
beforeDestroy() {
clearInterval(getDeviceInterval)
}
};
</script>
<style lang="less" scoped>
@ -333,7 +610,8 @@ export default {
width: 12%;
height: 20.4%;
}
.img1{
.img1 {
background-repeat: no-repeat;
background-size: 100% 100%;
position: absolute;
@ -528,4 +806,9 @@ export default {
}
}
}
.chart {
width: 100%;
height: 50vh;
}
</style>

@ -1,6 +1,7 @@
<template>
<div class="container">
<div class="centerImg"></div>
<div class="centerImg" v-if="!isMap"
:style="`background-image: url(${picUrl ? picUrl : containerPic})`"></div>
<div class="title">监控单元统计</div>
<Chart ref="chart1" class="chart1"></Chart>
<div class="chart1Right">
@ -132,10 +133,47 @@
</div>
</vue-seamless-scroll>
</div>
<div v-if="isMap">
<Chart ref="mapChart" class="mapChart"></Chart>
<el-button type="primary" style="position:absolute;bottom: 4%;left: 50%;transform: translateX(-50%)"
@click="toRealMap">打开地图
</el-button>
</div>
<el-dialog :visible.sync="realMap" width="80%">
<el-form :inline="true" :model="formInline" class="demo-form-inline">
<el-form-item label="名称">
<el-input v-model="formInline.name" placeholder="名称"></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="searchMap"></el-button>
</el-form-item>
</el-form>
<div id="map" class="map"></div>
</el-dialog>
<el-dialog
:visible.sync="isDispose"
width="30%">
<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>
</div>
</template>
<script>
import containerPic from "@/assets/board/index/container.png";
import Chart from "@/components/Charts/Chart";
import vueSeamlessScroll from "vue-seamless-scroll";
import * as echarts from 'echarts';
@ -145,21 +183,46 @@ import {
allNums,
getAlarmInfos,
getDeviceOperations,
handleAlarmInfo
handleAlarmInfo,
getDeviceByAreaId,
getTenantData,
selectMonitorElectronic,
selectDeviceByName
} from '@/api/board/index'
import ChinaMapData from '@/utils/ChinaMapData.json'
import gsByMap from '@/utils/map/gs_by.json'
import axios from "axios";
let map = null
let markers = []
let markerIds = []
let polygons = []
let circles = []
const vw = (document.documentElement.clientWidth || document.body.clientWidth) / 100
export default {
components: {
vueSeamlessScroll,
Chart,
},
data() {
return {
containerPic,
formInline:{},
textarea: '',
disposeNo: null,
isDispose: false,
realMap: false,
centerGeo: [],
picUrl: null,
code: 620000,
cityJson: null,
isMap: true,
centerNum: {},
chart1Option: {
tooltip: {
valueFormatter: (e)=>{return e+'%'},
valueFormatter: (e) => {
return e + '%'
},
},
angleAxis: {
max: 100,
@ -200,11 +263,11 @@ export default {
chart2Option: {
color: ["#22acfd", "#22fe97", "#f9e728", "#ff922b", "#ed1814"],
legend: {
type:'scroll',
type: 'scroll',
orient: "vertical",
x: "right",
y: "center",
width:'100px',
width: '100px',
textStyle: {
color: '#fff'
}
@ -287,17 +350,27 @@ export default {
table1Data: []
}
},
mounted() {
async mounted() {
getTenantData(this.$store.getters.tenantId).then(e => {
// this.isMap = e.data.tenantField === '2';
this.picUrl = e.data.tenantBoardPic
this.code = e.data.tenantMapCode || 620000
})
this.setChart1()
this.setChart2()
this.setAllNums()
this.setTable3()
this.setDeviceOperations()
let data = await axios.get(`https://geo.datav.aliyun.com/areas_v3/bound/${this.code}_full.json`)
let mapData = this.code === 100000 ? ChinaMapData : data.data
await this.getMap(mapData)
this.chartClick()
},
methods: {
async setChart1() {
const {rows: data} = await monitorPercentage()
let data1 = data.slice(0, 4)
let data1 = data.slice(0, 4)
data1.reverse()
let option1 = {
...this.chart1Option,
@ -362,7 +435,7 @@ export default {
no: e.alarmInfoId,
type: e.alarmTypeName,
location: e.monitorUnitName,
status:e.handleStatus
status: e.handleStatus
}
})
},
@ -370,12 +443,12 @@ export default {
let {data: data} = await getDeviceOperations()
let onlineDevicesTrend = data["onlineDevicesTrend"];
let sortArr = Object.keys(onlineDevicesTrend)
sortArr = sortArr.sort((a,b)=>{
sortArr = sortArr.sort((a, b) => {
return new Date(a).getTime() - new Date(b).getTime()
})
console.log(sortArr)
let x = sortArr
let y = sortArr.map(e=>{
let y = sortArr.map(e => {
return onlineDevicesTrend[e]
})
// this.inTransitNum = y.reduce((a, b) => {
@ -438,41 +511,351 @@ export default {
this.$refs.chart3.setData(option3)
},
dispose(e) {
console.log(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: '网络错误'
});
this.isDispose = true
this.disposeNo = e.no
},
disposeThis() {
handleAlarmInfo({
alarmInfoId: this.disposeNo,
alarmInfoField: this.textarea,
ifDisposalAll: 0,
}).then(e => {
if (e.code === 200) {
this.$message({
type: 'success',
message: '已处理!'
});
this.setTable3()
} else {
this.$message({
type: 'info',
message: '网络错误'
});
}
this.isDispose = false
})
},
disposeAll() {
handleAlarmInfo({
alarmInfoId: this.disposeNo,
alarmInfoField: this.textarea,
ifDisposalAll: 1,
}).then(e => {
if (e.code === 200) {
this.$message({
type: 'success',
message: '已处理!'
});
this.setTable3()
} else {
this.$message({
type: 'info',
message: '网络错误'
});
}
this.isDispose = false
})
},
async getMap(geoJson) {
this.cityJson = geoJson.features
echarts.registerMap('map', geoJson);
this.centerGeo = geoJson.features[0].properties.center || geoJson.features[0].properties.geo_wkt.split('(')[1].split(')')[0].split(' ').map(e => parseFloat(e))
const random = (val = 1) => {
return Math.ceil(Math.random() * val)
}
let Point = [
{value: [120.3, 36.0], index: random(5), type: random(5), state: random(5)},
{value: [104.065735, 30.659462], index: random(5), type: random(5), state: random(5)},
{value: [123.1238, 42.1216], index: random(5), type: random(5), state: random(5)},
{value: [114.4995, 38.1006], index: random(5), type: random(5), state: random(5)},
{value: [109.1162, 34.2004], index: random(5), type: random(5), state: random(5)},
{value: [106.3586, 38.1775], index: random(5), type: random(5), state: random(5)},
{value: [101.4038, 36.8207], index: random(5), type: random(5), state: random(5)},
{value: [113.0823, 28.2568], index: random(5), type: random(5), state: random(5)},
{value: [102.9199, 25.46639], index: random(5), type: random(5), state: random(5)},
]
Point = []
let option = {
grid: {
top: '0%',
left: '0%',
right: '0%',
bottom: '0%',
},
geo: {
map: "map",
show: false,
aspectScale: 0.75, //
zoom: 1.1,
label: {
show: true
},
roam: true,
layoutCenter: ["50%", "50%"], // position
layoutSize: 25 * vw,
itemStyle: {
normal: {
areaColor: {
type: "radial",
x: 0.5,
y: 0.5,
r: 0.8,
colorStops: [
{
offset: 0,
color: "#013B8F", // 0%
},
{
offset: 1,
color: "#013B8F", // 100%
},
],
globalCoord: true, // false
},
shadowColor: "#013B8F",
shadowOffsetX: 0,
shadowOffsetY: 8,
},
emphasis: {
areaColor: "#2AB8FF",
borderWidth: 0,
color: "green",
label: {
show: false,
},
},
},
},
series: [
{
type: "map",
roam: 'scale',
label: {
normal: {
show: true,
textStyle: {
color: "#1DE9B6",
},
},
},
itemStyle: {
normal: {
borderColor: "rgb(147, 235, 248,0.5)",
borderWidth: 1,
areaColor: {
type: "radial",
x: 0.5,
y: 0.5,
r: 0.8,
colorStops: [
{
offset: 0,
color: "#013B8F", // 0%
},
{
offset: 1,
color: "#013B8F", // 100%
},
],
globalCoord: true, // false
},
},
},
zoom: 1.1,
map: 'map', //使
aspectScale: 0.75, //
},
{
type: "effectScatter",
coordinateSystem: "geo",
showEffectOn: 'emphasis',
zlevel: 1,
rippleEffect: {
period: 15,
scale: 1,
brushType: "fill",
},
hoverAnimation: true,
itemStyle: {
normal: {
color: "#1DE9B6",
shadowBlur: 10,
shadowColor: "#333",
},
},
symbolSize: [0.5 * vw, 0.5 * vw],
data: Point,
label: {
padding: [-16, 0, 0, 5],
show: true,
position: 'bottom',
formatter: function (val) {
return [`{a|}{b|'点位${val.data.index}}`]
},
rich: {
a: {
width: 0.34 * vw,
height: 0.34 * vw,
borderColor: '#0FF32E',
borderWidth: 0.34 * vw,
borderRadius: 0.17 * vw,
shadowBlur: 20,
shadowColor: "#0FF32E",
},
b: {
padding: [0, 0, 0, 5],
color: '#0FF32E',
height: 40,
fontSize: 0.75 * vw,
},
}
}
},
],
};
this.$refs.mapChart.setData(option);
},
chartClick() {
this.$refs.mapChart.chart.on('click', async (params) => {
this.code = this.cityJson[params.dataIndex].properties.adcode || this.code || gsByMap.features[params.dataIndex].properties.unique_id
let mapData
if (this.code !== 620400 && this.code.toString().startsWith('6204')) {
mapData = {features: gsByMap.features.filter(e => e.properties.pid === this.code.toString())}
} else {
let data = await axios.get(`https://geo.datav.aliyun.com/areas_v3/bound/${this.code}_full.json`)
mapData = this.cityJson[params.dataIndex].properties.adcode === 100000 ? ChinaMapData : data.data
}
this.getMap(mapData)
})
this.$refs.mapChart.$el.addEventListener('dblclick', () => {
this.chartDblClick(this.code)
});
},
async chartDblClick(val) {
let a = val.toString().substr(0, 2)
let b = val.toString().substr(2, 2)
let c = val.toString().substr(4, 2)
let d = val.toString().substr(6, 9)
d = null
if (d && d !== '000') {
this.code = Number(a + b + c)
} else if (c !== '00') {
this.code = Number(a + b + '00')
} else if (b !== '00') {
this.code = Number(a + '0000')
} else if (a !== '10') {
this.code = 100000
}
let mapData
if (this.code !== 620400 && this.code.toString().startsWith('6204')) {
mapData = gsByMap
} else {
let data = await axios.get(`https://geo.datav.aliyun.com/areas_v3/bound/${this.code}_full.json`)
mapData = this.code === 100000 ? ChinaMapData : data.data
}
this.getMap(mapData)
},
async toRealMap() {
this.realMap = true
markerIds = []
this.$nextTick(async () => {
this.createMap()
const data = await getDeviceByAreaId(this.$store.getters.tenantId)
data.data.map(e => e.devicesList).flat(1).forEach(e => {
this.setMarker(e)
})
})
},
setMarker(e) {
let marker = new AMap.Marker({
position: [e.longitude, e.latitude],
title: `信息\n经度${e.longitude}\n纬度${e.latitude}\n名称${e.deviceName}\n`,
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;">
<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="#3D93FD" p-id="4306">
</path>
</svg>
</div>`
});
marker.on('click', async () => {
if (markerIds.includes(e.deviceId)) {
return
} else {
markerIds.push(e.deviceId)
}
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])
}
})
}).catch(() => {
this.$message({
type: 'info',
message: '已取消'
});
})
marker.on('dblclick', () => {
this.$router.push({path: '/board/equipment', query: {monitorUnitId: e.monitorUnitId}})
console.log(e)
});
map.add(marker);
markers.push(marker)
},
setPolygon(e, val) {
// let e = position.map(val => {
// return [val.longitude, val.latitude]
// })
let thisPolygon = new AMap.Polygon({
path: e,
fillColor: '#1791fc',
// fillColor: val > 0 ? '#ff0000' : '#1791fc',
});
console.log(thisPolygon)
map.add(thisPolygon)
map.setFitView(thisPolygon)
polygons.push(thisPolygon)
},
setCircle(center, radius, e) {
let circle = new AMap.Circle({
center,
radius,
borderWeight: 3,
strokeColor: "#FF33FF",
// strokeColor: e ? '#ff0000' : "#FF33FF",
strokeWeight: 6,
strokeOpacity: 0.2,
fillOpacity: 0.4,
strokeDasharray: [10, 10],
fillColor: '#1791fc',
// fillColor: e > 0 ? '#ff0000' : '#1791fc',
})
map.add(circle);
map.setFitView(circle)
circles.push(circle)
},
createMap() {
map = new AMap.Map('map', {
zoom: 11,
center: this.centerGeo,
});
},
async searchMap(){
const data = selectDeviceByName(this.formInline)
console.log(data)
map.remove(markers)
map.remove(polygons)
map.remove(circles)
}
}
}
;
</script>
<style scoped>
.title{
.title {
position: absolute;
top: 12%;
left: 13.6%;
@ -480,6 +863,7 @@ export default {
color: #00f8ff;
transform: translateX(-50%);
}
.container {
background-image: url("~@/assets/board/index/bg.jpg");
background-repeat: no-repeat;
@ -490,7 +874,6 @@ export default {
}
.centerImg {
background-image: url("~@/assets/board/index/container.png");
background-repeat: no-repeat;
background-size: 100% 100%;
position: absolute;
@ -595,4 +978,18 @@ export default {
top: 45.5%;
left: 76.3%;
}
.mapChart {
position: absolute;
width: 50%;
height: 60%;
top: 30%;
left: 25%;
}
.map {
width: 100%;
height: 80vh;
}
</style>

@ -36,8 +36,9 @@ module.exports = {
// detail: https://cli.vuejs.org/config/#devserver-proxy
[process.env.VUE_APP_BASE_API]: {
// target: `http://127.0.0.1:9080`,
target: `http://10.11.40.120:9080`,
// target: `http://10.11.40.120:9080`,
// target: `http://10.11.43.111:8080`,
target: `http://10.11.43.111:9088`,
// target: `http://175.27.215.92:9080`,
changeOrigin: true,
pathRewrite: {

Loading…
Cancel
Save