multiple-police-situations/src/views/page/indexMim.vue

1357 lines
42 KiB
Vue
Raw Normal View History

2024-07-22 11:11:43 +08:00
<template>
<div class="box">
<div class="left">
<div class="left_top">
<div class="title1">
<span style="margin-left: 13px; font-weight: bold; font-size: 15px">接入总览</span>
</div>
<div style="display: flex; align-items: center; justify-content: center; padding: 10px 0px">
<img style="width: 15%; height: 15%" src="./indeximag/图2.png" alt="" />
<div style="text-align: center">
<p style="font-size: 13px; margin-bottom: 10px">接入数量</p>
<span class="fp">{{ getNthChar(data1.alarmPointTotal + '', 5) }}</span>
<span class="fp">{{ getNthChar(data1.alarmPointTotal + '', 4) }}</span>
<span class="fp">{{ getNthChar(data1.alarmPointTotal + '', 3) }}</span>
<span class="fp">{{ getNthChar(data1.alarmPointTotal + '', 2) }}</span>
<span class="fp">{{ getNthChar(data1.alarmPointTotal + '', 1) }}</span>
<span class="fp">{{ getNthChar(data1.alarmPointTotal + '', 0) }}</span>
</div>
</div>
<div id="EcharRef" style="width: 98%; height: 54%"></div>
</div>
<div class="left_cen">
<div class="title1">
<span style="margin-left: 13px; font-weight: bold; font-size: 15px">运营单位</span>
</div>
<div style="display: flex; justify-content: space-between; margin-top: 10px">
<div style="margin-left: 30px">
<span style="margin-right: 5px; font-size: 13px">接入数量</span>
<span class="fp">{{ getNthChar(config.data.length + '', 2) }}</span>
<span class="fp">{{ getNthChar(config.data.length + '', 1) }}</span>
<span class="fp">{{ getNthChar(config.data.length + '', 0) }}</span>
</div>
<div style="margin-right: 30px; padding-top: 6px">
<span style="display: inline-block; font-size: 13px">在线率</span>
<div style="display: inline-block">
<el-progress
style="width: 65px; display: inline-block; vertical-align: middle; margin-left: 10px; margin-top: -5px"
2024-08-08 17:34:43 +08:00
:percentage="+(i / config.data.length).toFixed(2) * 100"
:stroke-width="15"
:text-inside="true"
></el-progress>
</div>
</div>
</div>
<div style="width: 100%; height: 70%; margin-top: 5px">
<dv-scroll-board :config="config" @click="row1" style="" />
</div>
</div>
<div class="left_bottm">
<div class="title1">
<span style="margin-left: 13px; font-weight: bold; font-size: 15px">重点单位</span>
</div>
<div id="EcharRef1" style="width: 98%; height: 44%"></div>
<div style="width: 100%; height: 30%; margin-top: 10px">
<dv-scroll-board :config="config1" style="" />
</div>
</div>
</div>
<div class="cen" id="myMap">
<!-- <el-button icon="el-icon-search" circle></el-button> -->
</div>
<div class="right" style="position: relative">
<span style="position: absolute; left: -180px; top: 12px; z-index: 9; font-size: 23px; font-weight: bold">{{ maptitle }}</span>
<el-tooltip class="item" effect="dark" content="返回上一级" placement="top-start">
<el-button @click="hy()" type="primary" icon="refresh-left" circle style="position: absolute; left: -48px; top: 4px; z-index: 9"></el-button>
</el-tooltip>
<div class="right_top">
<div class="title1">
<span style="margin-left: 13px; font-weight: bold; font-size: 15px">今日警情</span>
<img src="" alt="" />
</div>
<div style="width: 100%; display: flex; justify-content: center; align-items: center; margin-top: 15px">
<div>
<span style="margin-right: 5px; font-size: 13px">报警次数</span>
<span class="fp">{{ getNthChar(drzs.countAlarm + '', 2) }}</span>
<span class="fp">{{ getNthChar(drzs.countAlarm + '', 1) }}</span>
<span class="fp">{{ getNthChar(drzs.countAlarm + '', 0) }}</span>
</div>
<div style="margin-left: 30px">
<span style="margin-right: 5px; font-size: 13px">警情数量</span>
<span class="fp">{{ getNthChar(drzs.countCase + '', 1) }}</span>
<span class="fp">{{ getNthChar(drzs.countCase + '', 0) }}</span>
</div>
</div>
<div id="EcharRef2" style="width: 98%; height: 73%; margin-top: 10px"></div>
</div>
<div class="right_cen">
<div class="title1">
<span style="margin-left: 13px; font-weight: bold; font-size: 15px">今日报警</span>
</div>
<div style="width: 100%; height: 80%; margin-top: 10px">
<el-empty v-if="config2.data.length == 0" :image-size="100" description="暂无数据"></el-empty>
<dv-scroll-board v-else :config="config2" @click="row2" style="" />
</div>
</div>
<div class="right_bottm">
<div class="title1">
<span style="margin-left: 13px; font-weight: bold; font-size: 15px">今日预警</span>
</div>
<div style="width: 100%; height: 70%; margin-top: 10px">
<el-empty v-if="config3.data.length == 0" :image-size="100" description="暂无数据"></el-empty>
<dv-scroll-board v-else :config="config3" @click="row3" style="" />
</div>
</div>
</div>
<el-dialog title="运营单位" v-model="dialogVisible1" width="800">
<div class="uploadBtn" style="text-align: right; margin-right: 10px">
<el-button
><el-icon> <Printer /> </el-icon></el-button
>
</div>
<el-descriptions title="" border direction="" :column="2">
<el-descriptions-item label="平台名称">{{ showrow1data.name }}</el-descriptions-item>
<el-descriptions-item label="公司">{{ showrow1data.company }}</el-descriptions-item>
<el-descriptions-item label="城市">{{ showrow1data.city }}</el-descriptions-item>
<el-descriptions-item label="区县">{{ showrow1data.district }}</el-descriptions-item>
<el-descriptions-item label="IP">{{ showrow1data.ip }}</el-descriptions-item>
<el-descriptions-item label="平台公钥">{{ showrow1data.platKey }}</el-descriptions-item>
<el-descriptions-item label="视频系统">{{ showrow1data.ipcSystem }}</el-descriptions-item>
<el-descriptions-item label="在线状态">{{ showrow1data.lineState }}</el-descriptions-item>
<el-descriptions-item label="启用状态">{{ showrow1data.useState }}</el-descriptions-item>
<el-descriptions-item label="联系人">{{ showrow1data.userName1 }}</el-descriptions-item>
<el-descriptions-item label="电话">{{ showrow1data.userPhone2 }}</el-descriptions-item>
</el-descriptions>
</el-dialog>
<el-dialog title="今日报警" v-model="dialogVisible2" width="800">
<div class="uploadBtn" style="text-align: right; margin-right: 10px">
<el-button
><el-icon> <Printer /> </el-icon></el-button
>
</div>
<el-descriptions title="" border direction="" :column="2">
<el-descriptions-item label="时间">{{ showrow2data.timestamp }}</el-descriptions-item>
<el-descriptions-item label="类型">{{ showrow2data.alarmCode }}</el-descriptions-item>
<el-descriptions-item label="报警单位">{{ showrow2data.alarmTarget }}</el-descriptions-item>
<el-descriptions-item label="地点">{{ showrow2data.address }}</el-descriptions-item>
<el-descriptions-item label="城市">{{ showrow2data.city }}</el-descriptions-item>
<el-descriptions-item label="区县">{{ showrow2data.district }}</el-descriptions-item>
<el-descriptions-item label="乡镇">{{ showrow2data.town }}</el-descriptions-item>
<el-descriptions-item label="报警类型">{{ showrow2data.alarmType }}</el-descriptions-item>
<el-descriptions-item label="设备类型">{{ showrow2data.deviceType }}</el-descriptions-item>
<el-descriptions-item label="设备号">{{ showrow2data.alarmSource }}</el-descriptions-item>
<el-descriptions-item label="描述信息">{{ showrow2data.description }}</el-descriptions-item>
<el-descriptions-item label="核验状态">{{ totypecn(showrow2data.fakeState) }}</el-descriptions-item>
<el-descriptions-item label="联系人">{{ showrow2data.user1Name }}</el-descriptions-item>
<el-descriptions-item label="联系人号码">{{ showrow2data.user1Phone }}</el-descriptions-item>
</el-descriptions>
</el-dialog>
<el-dialog title="今日预警" v-model="dialogVisible3" width="800">
<div class="uploadBtn" style="text-align: right; margin-right: 10px">
<el-button
><el-icon> <Printer /> </el-icon></el-button
>
</div>
<el-descriptions title="" border direction="" :column="2">
<el-descriptions-item label="时间">{{ showrow3data.timestamp }}</el-descriptions-item>
<el-descriptions-item label="类型">{{ showrow3data.alarmCode }}</el-descriptions-item>
<el-descriptions-item label="报警单位">{{ showrow3data.alarmTarget }}</el-descriptions-item>
<el-descriptions-item label="地点">{{ showrow3data.address }}</el-descriptions-item>
<el-descriptions-item label="城市">{{ showrow3data.city }}</el-descriptions-item>
<el-descriptions-item label="区县">{{ showrow3data.district }}</el-descriptions-item>
<el-descriptions-item label="乡镇">{{ showrow3data.town }}</el-descriptions-item>
<el-descriptions-item label="报警类型">{{ showrow3data.alarmType }}</el-descriptions-item>
<el-descriptions-item label="设备类型">{{ showrow3data.deviceType }}</el-descriptions-item>
<el-descriptions-item label="设备号">{{ showrow3data.alarmSource }}</el-descriptions-item>
<el-descriptions-item label="描述信息">{{ showrow3data.description }}</el-descriptions-item>
<el-descriptions-item label="核验状态">{{ totypecn(showrow3data.fakeState) }}</el-descriptions-item>
<el-descriptions-item label="联系人">{{ showrow3data.user1Name }}</el-descriptions-item>
<el-descriptions-item label="联系人号码">{{ showrow3data.user1Phone }}</el-descriptions-item>
</el-descriptions>
</el-dialog>
</div>
2024-07-22 11:11:43 +08:00
</template>
<script lang="ts" setup>
import effectScatterData from '@/utils/effectScatterData'
import linesData from '@/utils/linesData'
import 'echarts-gl'
// @ts-ignore
2024-08-12 11:08:14 +08:00
import {getAreaCode} from './js/area'
import {JsonResult} from '@/axios'
import {Ref, ref, watch, onMounted, onBeforeMount, reactive, getCurrentInstance, nextTick} from 'vue'
import * as echarts from 'echarts'
import api from '@/axios'
import {fa} from 'element-plus/es/locale'
2024-08-12 11:08:14 +08:00
const {proxy} = getCurrentInstance() as any
const day = proxy.day
onMounted(() => {
// gettotal();
seach({})
initMapdt(localStorage.getItem('mapdata'), JSON.parse(localStorage.getItem('totaldata')), JSON.parse(localStorage.getItem('user-stores'))['userInfo']['levelvalue'])
get1(JSON.parse(localStorage.getItem('user-stores'))['userInfo']['levelvalue'], '', '')
get3(JSON.parse(localStorage.getItem('user-stores'))['userInfo']['levelvalue'], '', '')
getaiyuji(JSON.parse(localStorage.getItem('user-stores'))['userInfo']['levelvalue'], '', '')
getdayline(JSON.parse(localStorage.getItem('user-stores'))['userInfo']['levelvalue'], '', '')
getAi(JSON.parse(localStorage.getItem('user-stores'))['userInfo']['levelvalue'], '', '')
})
//详情
const row1data = ref()
const showrow1data = ref()
const dialogVisible1 = ref(false)
const row1 = (row: any) => {
showrow1data.value = row1data.value[row.rowIndex]
dialogVisible1.value = true
}
const totypecn = (data: any) => {
if (data == '0') {
return '未核验'
} else if (data == '1') {
return '核验为假'
} else if (data == '2') {
return '核验为真'
}
}
//查询运营商
const config = reactive({
header: ['名称', 'ip', '地区', '状态'],
headerHeight: 28,
columnWidth: [150, 150, 180, 80],
waitTime: 3000,
data: [],
headerBGC: '#174F8A',
oddRowBGC: '#2C5784',
evenRowBGC: 'F3FDFF',
index: false,
2024-08-12 11:08:14 +08:00
align: ['left', 'left', 'left', 'center']
})
const i = ref(0)
const seach = (obj: any) => {
api.post('/multialarm/client/platform/getlist', obj).then((res: JsonResult<any>) => {
if (res.code == 0) {
row1data.value = res.data
let arr: any[] = []
res.data.forEach((x: any) => {
if (x.lineState == 'online') {
i.value++
arr.push([x.name, x.ip, x.address, '<span style="background:#038E4C;padding:2px 3px;color:#fff;font-size:12px;border-radius:3px">在线</span>'])
} else {
arr.push([x.name, x.ip, x.address, '<span style="background:red;padding:2px 3px;color:#fff;font-size:12px;border-radius:3px">离线</span>'])
}
})
config.data = arr
}
})
}
//还原
const hy = () => {
var tree4data = flattenTree(JSON.parse(localStorage.getItem('tree4data')))
// maptitle.value = tree4data.find(element => element.code == JSON.parse(data)['name'])['title'];
if (localStorage.getItem('nowCode') == JSON.parse(localStorage.getItem('user-stores'))['userInfo']['geoCode']) {
return
} else {
2024-08-12 11:08:14 +08:00
console.log(localStorage.getItem('nowCode'))
let fhcode = getAreaCode(localStorage.getItem('nowCode'))['codes'][0]
2024-08-12 11:08:14 +08:00
console.log(fhcode)
let ado = echarts.init(document.getElementById('myMap'))
ado.showLoading({
text: '地图加载中',
color: '#09A2DC', //设置加载颜色
textColor: '#09A2DC',
maskColor: 'rgba(255, 255, 255, 0.2)',
2024-08-12 11:08:14 +08:00
zlevel: 0
})
// const url = 'https://www.hndyjqrh.cn:8083/multialarm/pic/download?creator=geo&file=' + fhcode + '.geojson'
const url = 'https://www.hndyjqrh.cn/api/multialarm/pic/download?creator=geo&file=' + fhcode + '.geojson'
fetch(url)
.then((response) => {
var status = response['status']
if (status == 500) {
return new Promise((resovle) => {
resovle('无数据')
})
} else {
return response.text()
}
})
.then((data) => {
api
.post('multialarm/system/alarm/total', {
name: localStorage.getItem('loginname'),
2024-08-12 11:08:14 +08:00
parent: fhcode
})
.then((res) => {
if (res.code == 0) {
const myChart = echarts.init(document.getElementById('myMap'))
myChart.dispose()
initMapdt(data, res.data, tree4data.find((element) => element.code == fhcode)['title'])
// ado.hideLoading()
}
})
})
}
}
//详情
const row3data = ref()
const showrow3data = ref()
const dialogVisible3 = ref(false)
const row3 = (row: any) => {
showrow3data.value = row3data.value[row.rowIndex]
dialogVisible3.value = true
}
//查询当日预警
const config3 = reactive({
header: ['时间', '事件', '位置'],
waitTime: 3000,
rowNum: 6,
columnWidth: [220, 150, 200],
headerHeight: 38,
data: [],
headerBGC: '#174F8A',
oddRowBGC: '#2C5784',
evenRowBGC: 'F3FDFF',
index: false,
2024-08-12 11:08:14 +08:00
align: ['left', 'center', 'center', 'center']
})
const getAi = (city: any, district: any, town: any) => {
api
.post('/multialarm/ai/alarm/getlist/today', {
name: localStorage.getItem('loginname'),
city: city == '湖南省' ? null : city,
district: district,
2024-08-12 11:08:14 +08:00
town: town
})
.then((res: JsonResult<any>) => {
if (res.code == 0) {
row3data.value = res.data
let arr: any[] = []
res.data.forEach((x: any) => {
arr.push([x.timestamp, x.alarmName, x.address])
})
// res.data.forEach((x)={
// })
config3.data = arr
} else {
}
})
}
//2.3.5查询近7天报警数量
const drzs = ref<Data1Type>({})
const getdayline = (city: any, district: any, town: any) => {
api
.post('multialarm/system/alarm/count/dayline', {
name: localStorage.getItem('loginname'),
city: city == '湖南省' ? null : city,
district: district,
town: town,
start: day().format('YYYY-MM-DD HH:mm:ss'),
2024-08-12 11:08:14 +08:00
before: 1
})
.then((res: JsonResult<any>) => {
if (res.code == 0) {
drzs.value = res.data[6]
initMap2(res.data)
} else {
}
})
}
//详情
const dialogVisible2 = ref(false)
const row2data = ref()
const showrow2data = ref()
const row2 = (row: any) => {
showrow2data.value = row2data.value[row.rowIndex]
dialogVisible2.value = true
}
//查询指定区域的当天所有警报事件列表
const config2 = reactive({
header: ['时间', '类型', '报警单位', '地点'],
waitTime: 3000,
rowNum: 6,
columnWidth: [180, 100, 130, 180],
headerHeight: 38,
data: [],
headerBGC: '#174F8A',
oddRowBGC: '#2C5784',
evenRowBGC: 'F3FDFF',
index: false,
2024-08-12 11:08:14 +08:00
align: ['left', 'left', 'left', 'left']
})
const getaiyuji = (city: any, district: any, town: any) => {
api
.post('multialarm/client/sensor/alarm_event/getlist/today', {
name: localStorage.getItem('loginname'),
city: city == '湖南省' ? '' : city,
district: district,
2024-08-12 11:08:14 +08:00
town: town
})
.then((res: JsonResult<any>) => {
if (res.code == 0) {
row2data.value = res.data
let arr: any[] = []
res.data.forEach((x: any) => {
arr.push([x.timestamp, x.alarmCode, x.station, x.address])
})
config2.data = arr
} else {
}
})
}
//01
const getNthChar = (str: any, n: any) => {
let str1 = str.split('').reverse().join('')
return str1.charAt(n) || '0'
}
interface Data1Type {
[key: string]: any
}
const data1 = ref<Data1Type>({})
const get1 = (city: any, district: any, town: any) => {
api
.post('multialarm/system/count/devices', {
name: localStorage.getItem('loginname'),
city: city,
district: district,
2024-08-12 11:08:14 +08:00
town: town
})
.then((res) => {
if (res.code == 0) {
data1.value = res.data
initMap(res.data)
} else {
}
})
}
const config1 = ref({})
const get3 = (city: any, district: any, town: any) => {
api
.post('/multialarm/system/station/summary', {
name: localStorage.getItem('loginname'),
city: city,
district: district,
2024-08-12 11:08:14 +08:00
town: town
})
.then((res: JsonResult<any>) => {
if (res.code == 0) {
initMap1(res.data)
config1.value = {
header: ['行业名称', '总数', '在线总数', '在线率'],
waitTime: 3000,
rowNum: 2,
columnWidth: [150, 120, 180, 120],
headerHeight: 28,
data: [
['党政机关', res.data[0]['total'], res.data[0]['lineOnTotal'], res.data[0]['lineOnTotal'] == 0 ? '0%' : (res.data[0]['lineOnTotal'] / res.data[0]['total']) * 100 + '%'],
['金融机构', res.data[2]['total'], res.data[2]['lineOnTotal'], res.data[2]['lineOnTotal'] == 0 ? '0%' : (res.data[2]['lineOnTotal'] / res.data[2]['total']) * 100 + '%'],
['医疗单位', res.data[3]['total'], res.data[3]['lineOnTotal'], res.data[3]['lineOnTotal'] == 0 ? '0%' : (res.data[3]['lineOnTotal'] / res.data[3]['total']) * 100 + '%'],
['中小学', res.data[1]['total'], res.data[1]['lineOnTotal'], res.data[1]['lineOnTotal'] == 0 ? '0%' : (res.data[1]['lineOnTotal'] / res.data[1]['total']) * 100 + '%'],
2024-08-12 11:08:14 +08:00
['其他', res.data[4]['total'], res.data[4]['lineOnTotal'], res.data[4]['lineOnTotal'] == 0 ? '0%' : (res.data[4]['lineOnTotal'] / res.data[4]['total']) * 100 + '%']
],
headerBGC: '#174F8A',
oddRowBGC: '#2C5784',
evenRowBGC: 'F3FDFF',
index: false,
2024-08-12 11:08:14 +08:00
align: ['left', 'left', 'left', 'left']
}
// initMap(res.data);
} else {
}
})
}
const flattenTree = (treeData: any) => {
const result: any[] = []
function traverse(node: any) {
if (node.children && node.children.length > 0) {
for (const child of node.children) {
traverse(child)
}
}
delete node.children
result.push(node)
}
traverse(treeData)
return result
}
const maptitle = ref('')
const initMapdt = (data: any, podat: any, name: any) => {
console.log('initMapdt(name)_________', name)
var tree4data = flattenTree(JSON.parse(localStorage.getItem('tree4data')))
maptitle.value = name
localStorage.setItem('nowCode', JSON.parse(data)['name'])
const myChart = echarts.init(document.getElementById('myMap'))
// myChart.showLoading();
// myChart.hideLoading();
let langarr = JSON.parse(data)['features']
langarr.forEach((x: any, i: number) => {})
echarts.registerMap('myMap', data)
var option = {
tooltip: {
trigger: 'item',
// textStyle: {fontSize: '14', color: '#fff', fontFamily: 'Arial'},
// backgroundColor: '#092b6a',
// 当加入飞线lines 或 lines3D会和之前的 tooltip 配置发生冲突或覆盖,导致 tooltip 无法正常显示。
// 需要 tooltip 针对不同的系列进行正确配置,或者通过自定义 formatter 来处理多个系列的数据。
formatter: function (params: any) {
// console.log(111, params)
// 判断当前触发的系列类型
if (params.seriesType === 'map') {
console.log("params.seriesType === 'map'")
// 地图上的tooltip
let datat = podat
let itemWithId2 = datat.children.find((item: any) => item.grope === params.name)
if (!itemWithId2) {
return `
<div style="
background: url('/keji_border.png') no-repeat center center;
background-size: contain;
height: 150px;
width: 300px;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
color: #fff;
padding: 10px;
box-sizing: border-box;
">
报警: 0<br />
警情: 0<br />
AI预警: 0
</div>
`
} else {
return `
<div style="
background: url('/keji_border.png') no-repeat center center;
background-size: contain;
height: 150px;
width: 300px;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
color: #fff;
padding: 10px;
box-sizing: border-box;
">
报警: ${itemWithId2.alarmCount}<br />
警情: ${itemWithId2.caseCount}<br />
AI预警: ${itemWithId2.aiCount}
</div>
`
}
} else if (params.seriesType === 'lines') {
// 飞线上的tooltip
return `线路: ${params.data.fromName}${params.data.toName}`
} else if (params.seriesType === 'effectScatter') {
// 飞线终点的涟漪效果
return `终点: ${params.name}`
}
// 如果未匹配到系列类型,则返回空
return ''
2024-08-12 11:08:14 +08:00
}
},
geo: [
{
map: 'myMap',
aspectScale: 1,
zoom: 0.9,
layoutCenter: ['50%', '50%'],
layoutSize: '100%',
show: true,
roam: false,
label: {
show: true, //省市文字显示开关
color: '#fff'
},
itemStyle: {
areaColor: {
type: 'linear',
x: 1200,
y: 0,
x2: 0,
y2: 0,
colorStops: [
{
offset: 0,
color: 'rgba(3,27,78,0.75)'
},
{
offset: 1,
color: 'rgba(58,149,253,0.75)'
}
],
global: true // 缺省为 false
},
borderColor: '#c0f3fb',
borderWidth: 0.8
},
emphasis: {
itemStyle: {
show: false,
color: '#fff',
areaColor: 'rgba(0,254,233,0.6)'
// areaColor: '#3a69c1'
// areaColor: '#07315e'
},
label: {
show: true,
color: '#fff'
}
}
},
// 重影
{
type: 'map',
map: 'myMap',
zlevel: -1,
aspectScale: 1,
zoom: 0.9,
layoutCenter: ['50%', '51%'],
layoutSize: '100%',
roam: false,
silent: true,
itemStyle: {
borderWidth: 1,
borderColor: 'rgba(58,149,253,0.8)',
shadowColor: 'rgba(172, 122, 255,0.5)',
shadowOffsetY: 5,
shadowBlur: 15,
areaColor: 'rgba(5,21,35,0.1)'
}
},
{
type: 'map',
map: 'myMap',
zlevel: -2,
aspectScale: 1,
zoom: 0.9,
layoutCenter: ['50%', '52%'],
layoutSize: '100%',
roam: false,
silent: true,
itemStyle: {
borderWidth: 1,
borderColor: 'rgba(58,149,253,0.6)',
shadowColor: 'rgba(65, 214, 255,0.6)',
shadowOffsetY: 5,
shadowBlur: 15,
areaColor: 'rgba(5,21,35,0.1)'
}
},
{
type: 'map',
map: 'myMap',
zlevel: -3,
aspectScale: 1,
zoom: 0.9,
layoutCenter: ['50%', '53%'],
layoutSize: '100%',
roam: false,
silent: true,
itemStyle: {
borderWidth: 1,
borderColor: 'rgba(58,149,253,0.4)',
shadowColor: 'rgba(29, 111, 165,1)',
shadowOffsetY: 15,
shadowBlur: 10,
areaColor: 'rgba(5,21,35,0.1)'
}
},
{
type: 'map',
map: 'myMap',
zlevel: -4,
aspectScale: 1,
zoom: 0.9,
layoutCenter: ['50%', '54%'],
layoutSize: '100%',
roam: false,
silent: true,
itemStyle: {
borderWidth: 5,
borderColor: 'rgba(5,9,57,0.8)',
shadowColor: 'rgba(29, 111, 165,0.8)',
shadowOffsetY: 15,
shadowBlur: 10,
areaColor: 'rgba(5,21,35,0.1)'
}
}
],
series: [
{
type: 'map',
map: 'myMap',
geoIndex: 0, //geoIndex第一个图层
tooltip: {
trigger: 'item',
backgroundColor: 'rgba(0,0,0,0)',
borderColor: 'rgba(0,0,0,0)',
extraCssText: 'box-shadow: 0 0 0 rgba(0, 0, 0, 0);',
textStyle: {fontSize: '16', color: '#fff'},
formatter: function (params: any) {
// tooltip 是在这里生效的,而不是上面那个配置
// console.log(222, params)
let datat = podat
let itemWithId2 = datat.children.find((item: any) => item.grope === params.name)
if (!itemWithId2) {
return `
<div style="
background: url('/keji_border.png') no-repeat center center;
background-size: contain;
height: 150px;
width: 300px;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
color: #fff;
padding: 10px;
box-sizing: border-box;
">
报警: 0<br />
警情: 0<br />
AI预警: 0
</div>
`
} else {
return `
<div style="
background: url('/keji_border.png') no-repeat center center;
background-size: contain;
height: 150px;
width: 300px;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
color: #fff;
padding: 10px;
box-sizing: border-box;
">
报警: ${itemWithId2.alarmCount}<br />
警情: ${itemWithId2.caseCount}<br />
AI预警: ${itemWithId2.aiCount}
</div>
`
}
2024-08-12 11:08:14 +08:00
}
},
data: [] as any[] // 添加与你的数据相关联的数据
},
{
type: 'lines', // 飞线图
tooltip: {
show: false // 禁用飞线的 tooltip
},
zlevel: 2,
effect: {
show: true,
period: 3, //箭头指向速度,值越小速度越快
trailLength: 0.03, //特效尾迹长度[0,1]值越大,尾迹越长重
symbol: 'arrow', //箭头图标
symbolSize: 6 //图标大小
},
lineStyle: {
color: '#EE5652',
width: 1, //尾迹线条宽度
opacity: 1, //尾迹线条透明度
curveness: 0.3 //尾迹线条曲直度
},
data: linesData,
symbol: ['none', 'circle'], //飞线起点终点点位样式
symbolSize: 10 // 飞线起点终点点位大小
},
{
// 散点图
type: 'effectScatter', //在地图上绘制具有动态效果的散点图,实现视觉上的效果,比如涟漪效果或闪烁效果
zlevel: 3, //图层的深度,值越大表示图层越高,覆盖在其他图层之上。通常用于分层显示效果
coordinateSystem: 'geo',
tooltip: {
show: false // 禁用散点的 tooltip
},
data: effectScatterData,
symbol: 'circle', // 设置散点的图形为圆形
symbolSize: [10, 10], // 设置散点的大小,宽度为 20高度为 10
itemStyle: {
color: 'orange', // 散点颜色设置为橙色
shadowBlur: 10, // 设置散点的阴影模糊大小
shadowColor: 'orange' // 阴影颜色为橙色
},
effectType: 'ripple', //动画效果类型设置为涟漪效果,即散点会呈现出波纹扩散的效果
// showEffectOn:emphasis移入显示动画render一开始显示动画
// showEffectOn:render: 表示在图表渲染时立即显示动画效果
showEffectOn: 'render',
rippleEffect: {
scale: 5, // 涟漪效果的扩展倍数,越大波纹越大
brushType: 'stroke' // 涟漪效果的绘制方式stroke 表示仅绘制波纹的边框,不填充
2024-08-12 11:08:14 +08:00
}
}
]
}
if (name !== '湖南省') {
// option.series = option.series.filter((series) => series.type !== 'lines')
option.series[1].data = []
option.series[2].data = []
myChart.setOption(option)
} else {
myChart.setOption(option)
}
window.addEventListener('resize', function () {
myChart.resize()
})
myChart.on('click', (x) => {
// let tree4data = flattenTree(JSON.parse(localStorage.getItem('tree4data')));
tree4data.forEach((item) => {
if (item.stationId === undefined) {
if (item.code.length < 9) {
if (x.name == item.title) {
myChart.dispose()
let ado = echarts.init(document.getElementById('myMap'))
ado.showLoading({
text: '地图加载中',
color: '#09A2DC', //设置加载颜色
textColor: '#09A2DC',
maskColor: 'rgba(255, 255, 255, 0.2)',
2024-08-12 11:08:14 +08:00
zlevel: 0
})
get1(x.name, '', '')
get3(x.name, '', '')
getaiyuji(x.name, '', '')
getdayline(x.name, '', '')
getAi(x.name, '', '')
//item.code
// const url = 'https://www.hndyjqrh.cn:8083/multialarm/pic/download?creator=geo&file=' + item.code + '.geojson'
const url = 'https://www.hndyjqrh.cn/api/multialarm/pic/download?creator=geo&file=' + item.code + '.geojson'
fetch(url)
.then((response) => {
var status = response['status']
if (status == 500) {
return new Promise((resovle) => {
resovle('无数据')
})
} else {
return response.text()
}
})
.then((data) => {
api
.post('multialarm/system/alarm/total', {
name: localStorage.getItem('loginname'),
2024-08-12 11:08:14 +08:00
parent: item.code
})
.then((res) => {
if (res.code == 0) {
initMapdt(data, res.data, x.name)
ado.hideLoading()
}
})
})
}
}
}
})
})
}
const initMap = (data1: any) => {
const domMap = document.getElementById('EcharRef')
domMap.removeAttribute('_echarts_instance_')
const myChart = echarts.init(domMap)
var option = {
tooltip: {
2024-08-12 11:08:14 +08:00
trigger: 'item'
},
legend: {
top: '15px',
left: '230px',
orient: 'vertical',
type: 'scroll',
itemHeight: 5,
textStyle: {
2024-08-12 11:08:14 +08:00
color: '#fff'
}
},
series: [
{
type: 'pie',
radius: ['45%', '70%'],
avoidLabelOverlap: false,
label: {
show: false,
2024-08-12 11:08:14 +08:00
position: 'right'
},
emphasis: {
label: {
show: true,
fontSize: 12,
fontWeight: 'bold',
2024-08-12 11:08:14 +08:00
color: '#fff'
}
},
labelLine: {
2024-08-12 11:08:14 +08:00
show: true
},
center: ['35%', '50%'],
data: [
2024-08-12 11:08:14 +08:00
{value: data1.alarmPointZone, name: '防区报警'},
{value: data1.alarmPointTalk, name: '对讲报警'},
{value: data1.mdevTotal, name: '移动报警'},
{value: data1.alarmPointPushButton, name: '一键报警'},
{value: data1.ipcTotal, name: '报警复合'}
]
}
]
}
// 使用刚指定的配置项和数据显示图表。
myChart.setOption(option)
}
const initMap1 = (data1: any) => {
const domMap = document.getElementById('EcharRef1')
domMap.removeAttribute('_echarts_instance_')
const myChart = echarts.init(domMap)
var option = {
tooltip: {
2024-08-12 11:08:14 +08:00
trigger: 'item'
},
xAxis: {
type: 'category',
splitLine: {
2024-08-12 11:08:14 +08:00
show: false //去掉网格线
},
axisLine: {
//这是y轴文字颜色
lineStyle: {
2024-08-12 11:08:14 +08:00
color: '#fff'
}
},
data: ['党政机关', '金融机构', '医疗单位', '中小学', '其他'],
axisLabel: {
formatter: (val: any) => {
let txt = val
if (val.length > 4) {
txt = val.substr(0, 4) + '...'
}
return txt
2024-08-12 11:08:14 +08:00
}
}
},
grid: {
top: '8%',
left: '1%',
right: '1%',
bottom: '3%',
2024-08-12 11:08:14 +08:00
containLabel: true
},
yAxis: {
type: 'value',
axisLine: {
//这是y轴文字颜色
lineStyle: {
2024-08-12 11:08:14 +08:00
color: '#fff'
}
},
splitLine: {
// 设置x轴轴线相关配置
2024-08-12 11:08:14 +08:00
show: false // 不显示x轴轴线
}
},
series: [
{
barWidth: '24%',
data: [data1[0]['total'], data1[2]['total'], data1[3]['total'], data1[1]['total'], data1[4]['total']],
type: 'bar',
itemStyle: {
normal: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{
offset: 0,
2024-08-12 11:08:14 +08:00
color: '#0386F6' // 起始颜色(红)
},
{
offset: 1,
2024-08-12 11:08:14 +08:00
color: '#0FBBC4' // 结束颜色(蓝)
}
])
}
}
}
]
}
myChart.setOption(option)
}
const initMap2 = (arr: any) => {
let time: any[] = []
let data1: any[] = []
let data2: any[] = []
arr.forEach((x: any) => {
time.push(x.month + '-' + x.day)
data1.push(parseInt(x.countAlarm))
data2.push(parseInt(x.countCase))
})
const domMap = document.getElementById('EcharRef2')
domMap.removeAttribute('_echarts_instance_')
const myChart = echarts.init(domMap)
var option = {
tooltip: {
trigger: 'item',
formatter: (params: any) => {
return '警情数量:' + params.seriesIndex + '<br /> 报警次数:' + params.data
2024-08-12 11:08:14 +08:00
}
},
grid: {
top: '15%',
left: '1%',
right: '1%',
bottom: '3%',
2024-08-12 11:08:14 +08:00
containLabel: true
},
legend: {
data: [
{
name: '报警次数',
textStyle: {
2024-08-12 11:08:14 +08:00
color: '#fff'
}
},
{
name: '警情数量',
textStyle: {
2024-08-12 11:08:14 +08:00
color: '#fff'
}
}
]
},
xAxis: [
{
type: 'category',
splitLine: {
2024-08-12 11:08:14 +08:00
show: false //去掉网格线
},
data: time,
axisLine: {
//这是y轴文字颜色
lineStyle: {
2024-08-12 11:08:14 +08:00
color: '#fff'
}
},
axisPointer: {
2024-08-12 11:08:14 +08:00
type: 'shadow'
}
}
],
yAxis: [
{
type: 'value',
name: '',
min: 0,
// max: 250,
interval: 50,
splitLine: {
// 设置x轴轴线相关配置
2024-08-12 11:08:14 +08:00
show: false // 不显示x轴轴线
},
axisLine: {
//这是y轴文字颜色
lineStyle: {
2024-08-12 11:08:14 +08:00
color: '#fff'
}
},
axisLabel: {
2024-08-12 11:08:14 +08:00
formatter: '{value}次'
}
},
{
type: 'value',
min: 0,
splitLine: {
// 设置x轴轴线相关配置
2024-08-12 11:08:14 +08:00
show: false // 不显示x轴轴线
},
max: 25,
interval: 5,
axisLabel: {
2024-08-12 11:08:14 +08:00
formatter: ''
}
}
],
series: [
{
name: '报警次数',
type: 'bar',
tooltip: {
valueFormatter: function (value: any) {
// return value + ' ml';
2024-08-12 11:08:14 +08:00
}
},
barWidth: '24%',
itemStyle: {
2024-08-12 11:08:14 +08:00
color: '#3F7AD1' // 设置折线的颜色为红色
},
2024-08-12 11:08:14 +08:00
data: data1
},
{
name: '警情数量',
type: 'line',
smooth: true,
yAxisIndex: 1,
tooltip: {
valueFormatter: function (value: any) {
// return value + '°C';
2024-08-12 11:08:14 +08:00
}
},
itemStyle: {
2024-08-12 11:08:14 +08:00
color: '#81A2CF' // 设置折线的颜色为红色
},
2024-08-12 11:08:14 +08:00
data: data2
}
]
}
myChart.setOption(option)
}
2024-07-22 11:11:43 +08:00
</script>
<style scoped lang="scss">
:deep(.dv-scroll-board .header) {
font-size: 13px;
;
}
:deep(.dv-scroll-board .rows .row-item) {
font-size: 12px;
}
:deep(.el-descriptions) {
width: 98%;
margin: 10px auto;
text-align: center;
border: 1px solid #1F9BD9;
--el-descriptions-table-border: {
1px solid #1F9BD9
}
;
--el-descriptions-item-bordered-label-background: {
transparent
}
;
}
:deep(.el-descriptions__body) {
background: transparent;
}
:deep(.el-descriptions__label) {
width: 130px;
color: rgb(12, 214, 254);
background: transparent;
}
:deep(.el-descriptions__content.el-descriptions__cell.is-bordered-content) {
color: #fff;
}
:deep(.el-descriptions__body .el-descriptions__table.is-bordered .el-descriptions__cell) {
border: 1px solid #1F9BD9;
}
:deep(.el-dialog__body) {
padding: 10px;
color: #fff;
}
.uploadBtn .el-button {
background-color: transparent;
border-color: #1F9BD9;
color: #1F9BD9;
}
.uploadBtn .el-button i {
font-size: 16px;
margin-right: 3px;
}
.uploadBtn .el-button:hover {
color: rgb(12, 214, 254);
border: 1px solid rgb(12, 214, 254);
}
:deep(.el-dialog) {
--el-dialog-bg-color: #071D4D;
border: 3px solid #387dbf;
}
:deep(.el-dialog__header) {
padding: 13px;
border-bottom: 1px solid #3374b4 !important;
margin-right: 0px;
}
:deep(.el-dialog__title) {
color: #067bc1 !important;
font-weight: 500;
}
:deep(.el-input__inner) {
color: #000;
}
:deep(.el-dialog__headerbtn .el-dialog__close) {
color: #fff;
font-weight: 500;
font-size: 18px;
}
.tabs_a {
background-image: url(./indeximag/able.jpg);
background-size: 100% 100%;
}
:deep(.el-tabs__nav-wrap) {
margin-bottom: 1px;
}
:deep(.el-tabs--border-card>.el-tabs__content) {
height: calc(100% - 40px);
background: red;
padding: 0px;
}
:deep(.el-tabs--border-card>.el-tabs__header .el-tabs__item.is-active) {
color: #d1dbe5;
background-color: #29d;
border-right-color: #29d;
border-left-color: #29d;
}
:deep(.el-tabs--border-card>.el-tabs__header) {
background-color: transparent;
border-bottom: none;
}
:deep(.el-tabs--border-card) {
background: #022C54;
border: none;
}
:deep(.el-progress-bar__outer) {
background-color: #174771;
}
:deep(.el-progress-bar__inner) {
background-color: #3BC5F3;
}
.title1 {
width: 100%;
height: 30px;
background-image: url(./indeximag/一级标题.png);
background-size: 100% 100%;
line-height: 30px;
}
.fp {
background-image: url(./indeximag/数字背景.png);
width: 15px;
height: 22px;
display: inline-block;
background-size: 100% 100%;
line-height: 22px;
text-align: center;
margin-right: 10px;
font-size: 13px;
font-weight: 500;
}
.box {
width: 100%;
height: 100%;
display: flex;
background-color: #022C54;
.left {
width: 450px;
height: 98%;
margin-top: 0.5%;
margin-left: 0.5%;
border: 1px solid #3876B9;
.left_top {
width: 97%;
height: 33%;
padding: 5px;
}
.left_cen {
width: 97%;
height: 33%;
padding: 5px;
}
.left_bottm {
width: 97%;
height: 33%;
padding: 5px;
}
}
.right {
width: 450px;
height: 98%;
margin-top: 0.5%;
border: 1px solid #3876B9;
margin-right: 5px;
.right_top {
width: 97%;
height: 33%;
padding: 5px;
}
.right_cen {
width: 97%;
height: 33%;
padding: 5px;
}
.right_bottm {
width: 97%;
height: 35%;
padding: 5px;
}
}
.cen {
width: calc(100% - 900px);
height: 98%;
margin-top: 0.5%;
margin-left: 0.5%;
margin-right: 0.5%;
border: 1px solid #3876B9;
background-image: url(./indeximag/able.jpg);
// background-image: url(./indeximag/bg4.jpg);
background-size: 100% 100%;
}
}
</style>