<template> <div> <!--搜索条件--> <div class="map-search-div"> <el-form ref="selectForm" :inline="true" :model="listQuery" class="form-container" > <el-row> <el-input v-model.trim="keywords" placeholder="闸井编号/地址" clearable > <el-button slot="append" class="filter-item" type="primary" icon="el-icon-search" @click="search" >搜索</el-button > </el-input> </el-row> </el-form> </div> <!--搜索结果弹出框--> <el-popover v-show="searchWells.length > 0" v-model="showSelectList" placement="bottom-end" width="290" trigger="click" > <el-card slot="reference" shadow="always" class="selectAnswer" >共找到 {{ searchWells.length }} 个符合条件的井</el-card > <div v-show="searchWells.length > 0"> <div v-for="(well, index) in searchPageWells" :key="well.wellCode" class="search-card" @click="clickSearchItem(well)" > <div class="card-left">{{ index + 1 }}</div> <div class="card-right"> <div class="card-title">{{ well.wellCode }}</div> <div> <span class="card-welltype">{{ well.positionInfo }}</span> </div> </div> </div> </div> <div class="clear" /> <el-pagination :total="searchWells.length" :current-page="page" :page-size="pagesize" :hide-on-single-page="true" small layout="prev, pager, next" @current-change="handleCurrentChange" /> </el-popover> <!--倒计时和刷新按钮--> <!--<div class="refresh-div">--> <!--<span class="font-red">{{ count }}</span> s后刷新<i class="el-icon-refresh" @click="refreshAlarm"/>--> <!--</div>--> <div class="draw-tools"> <draw-tool @click="drawBox" /> <!--重置工具--> <clear-tool :disabled="clearDisabled" @click="drawDelete" /> </div> <!--告警列表弹框--> <el-popover v-show="alarmShowList.length > 0" v-model="alarmShow" :visible-arrow="false" :title="alarmtitle" placement="left-start" popper-class="alarm-list-popper" trigger="manual" > <el-button slot="reference" type="danger" icon="el-icon-message-solid" class="alarmButton" circle @click="alarmShow = !alarmShow" /> <div class="map-alarm-content"> <el-scrollbar :class="{ moredatascollor: alarmList.length > 6 }" :native="false" > <el-table :data="alarmShowList" :header-row-style="{ background: '#F3F4F7' }" @row-click="alarmRowClick" > <el-table-column v-for="column in columns" :key="column.value" :label="column.text" :width="column.width" :align="column.align" show-overflow-tooltip > <template slot-scope="scope"> {{ scope.row[column.value] }} </template> </el-table-column> </el-table> </el-scrollbar> </div> </el-popover> <!--加载框和弹窗--> <div v-loading="loading" class="overview-map-container"> <!--地图--> <baidu-map ref="map" :center="center" :zoom="zoom" class="map-demo" @ready="mapReady" > <baidu-point-collection v-if="showNoDeviceWell || showDeviceWell" :points="showMarkers" :color="pointColor" shape="BMAP_POINT_SHAPE_CIRCLE" size="BMAP_POINT_SIZE_SMALL" @click="openInfoWindow" /> <div v-if="!showNoDeviceWell && !showDeviceWell"> <baidu-point-collection :points=" showMarkers.filter(function(marker) { if (marker.wellFlag !== '0') { return marker; } }) " color="#66CDAA" shape="BMAP_POINT_SHAPE_CIRCLE" size="BMAP_POINT_SIZE_SMALL" @click="openInfoWindow" /> <baidu-point-collection :points=" showMarkers.filter(function(marker) { if (marker.wellFlag === '0') { return marker; } }) " color="#f1c353" shape="BMAP_POINT_SHAPE_CIRCLE" size="BMAP_POINT_SIZE_SMALL" @click="openInfoWindow" /> </div> <!--报警的图标--> <baidu-map-marker v-for="alarm in alarmWells" v-show="alarm.visible" :key="'alarmmarker' + alarm.wellId" :position="alarm.position" :offset="offset" :z-index="320" :visible="alarm.visible" :icon="alarm.icon" @click="openAlarmWindow(alarm.wellId, alarm.position, alarm)" /> <!--符合筛选条件闸井marker--> <baidu-map-marker v-for="(marker, index) in searchPageWells" v-show="marker.visible" :key="'well' + marker.wellId" :position="marker.position" :offset="selectOffset" :top="true" :visible="marker.visible" @click="openInfoWindow(marker)" > <baidu-label :label-style="{ color: 'white', background: 'rgba(0,0,0,0.0)', border: 'none', fontSize: '12px' }" :offset="{ width: 5, height: 4 }" :content="'' + (index + 1)" /> </baidu-map-marker> <!--marker的弹出框窗口--> <baidu-map-info-window :position="currentWindow.position" :show="currentWindow.visible" :title="wellInfo.wellCode" :class="infoWindowClass" > <div v-if="currentWindow.windowType == 'info' ? true : false" class="info-window" > <!--<div class="info-header">{{ wellInfo.wellCode }}</div>--> <div class="info-body"> <div>闸井类型:{{ wellInfo.wellTypeName }}</div> <div>所属派出所:{{ wellInfo.deptName }}</div> <div>产权单位:{{ wellInfo.owner }}</div> <div>详细地址:{{ wellInfo.position }}</div> </div> </div> <div v-if="currentWindow.windowType == 'alarm' ? true : false" class="alarm-window" > <div class="alarm-header"> <svg-icon icon-class="alarm-red" /> {{ alarmInfo.wellCode }} </div> <div class="alarm-body"> <div v-for="alarm in alarmInfo.alarms" :key="alarm.id"> <div> 告警原因:<span class="alarm-red">{{ alarm.alarmContent }}</span> </div> <div> 设备编号:<span>{{ alarm.devcode }}</span> </div> <div> 告警时间:<span>{{ alarm.alarmTime }}</span> </div> </div> <el-divider /> <div>所属分局:{{ alarmInfo.pidName }}</div> <div>所属派出所:{{ alarmInfo.deptName }}</div> <div>产权单位:{{ alarmInfo.owner }}</div> <div>详细地址:{{ alarmInfo.position }}</div> </div> </div> <div v-if="currentWindow.visible && videoList.length > 1" style="width: 100%;display: flex;margin: 5px 0;font-size: 14px;" > <div v-for="(item, index) in videoList" style="width: 18%;border: 1px splid #ccc;text-align: center;cursor: pointer;padding: 2px;" :class="currentVideo === index ? 'active-btn-video' : ''" @click="changeVideo(index)" > 视频{{ index + 1 }} </div> </div> <div v-if="currentWindow.visible && videoList.length" style="width: 300px;height: 150px;background-color: #000" > <iframe style="width: 100%;height: 100%;border: none;" :src="videoUrl" frameborder="0" ></iframe> </div> </baidu-map-info-window> </baidu-map> </div> <!--数据筛选弹框--> <el-popover placement="bottom-end" title="数据筛选" width="250" trigger="click" > <el-button slot="reference" type="primary" icon="el-icon-menu" class="toolbox" circle /> <div class="selectDiv"> <el-form ref="selectForm" :model="listQuery" label-position="top" size="small" > <el-form-item label="派出所"> <el-cascader v-model="listQuery.deptid" :options="deptTreeList" :props="deptProps" :show-all-levels="false" style="width:100%" collapse-tags clearable /> </el-form-item> <el-form-item v-if="wellTypeList.length > 1" label="闸井类型"> <el-select v-model="listQuery.wellType" placeholder="选择闸井类型" style="width:100%" clearable > <el-option v-for="item in wellTypeList" :key="item.value" :label="item.name" :value="item.value" /> </el-select> </el-form-item> <el-button class="filter-item" type="primary" icon="el-icon-search" @click="filter" >筛选</el-button > <el-button class="filter-item" type="default" icon="el-icon-delete" @click="clearSelected" >清除</el-button > <div style="height:15px;" /> <el-divider style="padding-top:10px" /> <el-form-item style="margin-top:10px"> <el-checkbox v-model="showAll" @change="showAllWells" >显示全部闸井</el-checkbox > <el-checkbox v-model="showNoDeviceWell" @change="showNoDeviceWells" >显示未装设备闸井</el-checkbox > <el-checkbox v-model="showDeviceWell" @change="showDeviceWells" >显示已装设备闸井</el-checkbox > </el-form-item> </el-form> </div> </el-popover> </div> </template> <script> import SelectTree from "@/components/SelectTree/singleSelect"; import { getWellType } from "@/api/well"; import dayjs from 'dayjs'; import { getWellList, getWellInfo, getAlarmsNow, getWellAlarms, getWellVideo, getWellHistoryVideo } from "@/api/overview"; import { judgeTree, toTreeList } from "@/utils/structure"; import { getDeptTreeList } from "@/api/dept"; import DeptSelect from "../../components/DeptSelect/index"; import BaiduMap from "../../components/BMap/baiduMap"; import BaiduMapMarker from "../../components/BMap/baiduMapMarker"; import BaiduPointCollection from "../../components/BMap/baiduPointCollection"; import BaiduMapInfoWindow from "../../components/BMap/baiduInfoWindow"; import BaiduLabel from "../../components/BMap/baiduLabel"; import DrawTool from "./components/drawTool"; import ClearTool from "./components/clearTool"; export default { name: "OverviewBaidu", components: { ClearTool, DrawTool, BaiduLabel, BaiduMapInfoWindow, BaiduMap, BaiduMapMarker, BaiduPointCollection, DeptSelect, SelectTree }, data() { return { pointColor: "#66CDAA", map: null, // 地图 drawingManager: null, // 绘制管理器 currentPolygon: null, // 当前选取图像 clearDisabled: true, // 禁用重置 keywords: "", // 关键字 listQuery: { wellType: "", // 井类型 deptid: [], // 组织机构 isAlarm: "" // 是否报警 }, // 筛选条件 columns: [ { text: "闸井编号", value: "wellCode", width: 80, align: "center" }, // { // text: '设备编号', // value: 'devcode', // width: 120, // align: 'center' // }, // { // text: '告警原因', // value: 'alarmContent', // align: 'center', // width: 100 // }, { text: "时间", value: "alarmTime", width: 170, align: "center" } ], // 显示列 tableShow: true, // 是否显示告警列表 tableIcon: "el-icon-arrow-up", count: 30, count2: 5, showWellType: this.showWellType(), // 是否显示闸井类型下拉 wellTypeList: [], // 闸井类型列表 wellTypeDict: {}, deptProps: { multiple: true, value: "id", label: "name", children: "children" }, // 产权单位树形下拉菜单 deptTreeList: [], // 组织树列表数据 showDeptTree: 0, // 是否显示产权单位下拉,0不显示,1显示树,2显示平面 showDeptSelect: true, // 是否显示产权单位下拉 icons: { "1": "static/BMap/images/well-rain.svg", "2": "static/BMap/images/well-sewage.svg", "3": "static/BMap/images/well-gas.svg", "4": "static/BMap/images/well-heat.svg", "5": "static/BMap/images/well-power.svg" }, // 井类型图标字典 commonIcon: "static/BMap/images/well-common.svg", center: { lng: 116.4, lat: 39.9 }, // 地图中心 zoom: 15, // 地图缩放比例 markers: [], // 井列表标注marker showMarkers: [], // 要显示的标注marker selectedMarkers: [], // 筛选条件marker alarmList: [], // 报警列表 alarmShow: false, hideWellCodes: [], // 要隐藏的井编号 alarmWells: [], // 报警闸井列表 offset: { width: 0, height: -10 }, // 偏移量 alarmOffset: { width: -15, height: -30 }, // 偏移量 selectOffset: { width: 0, height: 0 }, // selectSize: { width: 40, height: 40}, wellInfo: { wellCode: "", position: "", wellTypeName: "", deptName: "", bfztName: "", deep: "" }, // 显示井详细信息气泡内容 alarmInfo: { wellCode: "", deptName: "", position: "", deep: "", alarms: [] }, // 显示报警详情气泡内容 currentWindow: { visible: false, // 窗体显示与否 position: { lng: 116.4, lat: 39.9 }, windowType: "info" // 窗体类型:详情info或报警alarm }, // 当前窗体属性 infoWindowClass: "nomal-info-window", smallalarmwindow: "small-alarm-window", deptShowTop: false, // 是否显示顶级 clock: null, // 30s计时器,刷新图标用 clock2: null, // 5s定时器,刷新地图中心用 timeOut: "", // 3分钟无操作定时器 hasAlarm: false, // 是否有报警, showAll: false, // 是否显示全部闸井(包含报警和不报警,为false时只显示报警) showNoDeviceWell: false, // 是否显示未装设备闸井 showDeviceWell: false, // 是否显示已经装设备闸井 firstAmount: false, // 是否第一次加载井数据 loading: true, // 加载按钮 alarmicon: "static/BMap/images/alarm-well.svg", // 报警按钮 alarmgificon: "static/BMap/images/timgq.gif", // 报警按钮 searchWells: [], // 查询结果 searchPageWells: [], // 当前页结果 showSelectList: false, // 是否显示查询结果列表 page: 1, // 查询结果页码 pagesize: 5, // 查询结果每页结果数 centerIndex: 0, // 地图中心在alarmWells列表中的位置 audio: "", videoList: [], currentVideo: "", videoUrl: "", locationInfo: {} }; }, computed: { // 要显示的markers // showMarkers: function() { // if (this.listQuery.isAlarm === '1') { // return this.markers.filter(function(marker) { // if (marker.wellStatus === 'alarm') { // return marker // } // }) // } else { // return this.markers // } // }, alarmShowList: function() { const hideWellCodes = this.hideWellCodes; const showAlarmList = this.alarmList.filter(function(item) { if (hideWellCodes.indexOf(item.wellCode) === -1) { return item; } }); if (showAlarmList.length === 0) { this.alarmShow = false; this.currentWindow.visible = false; } return showAlarmList; }, alarmFixedWindows: function() { return this.alarmWells.filter(function(item) { var nowTime = new Date().getTime(); var alarmTime = new Date(item.alarmTime).getTime(); // 临时用 >来看效果 if (nowTime - alarmTime < 60000) { // 时间差小于一分钟用动画,否则用静态图片 return item; } }); }, alarmtitle: function() { return "告警列表(" + this.alarmShowList.length + ")"; } }, watch: { showAll(val) { if (val) { this.showDeviceWell = false; this.showNoDeviceWell = false; } }, // 监控关键字,如果置空认为清空查询 keywords(val) { if (val === "") { this.searchWells = []; this.searchPageWells = []; } } }, created() { this.fetchWellType(); // 获取井类型下拉列表 this.getWellList(); // 获取报警的井列表 this.getNormalWellList(); // 获取正常的井列表 this.refreshAlarm(); // 刷新报警 this.countDown(); // 开启倒计时 this.fetchPcode(); // 获取部门下拉列表 this.webSocket(); // 开启webSocket监听 this.isTimeOut(); // this.refreshCenter() // 获取当前页面的完整URL const currentUrl = window.location.href; // 正则表达式匹配IP和端口 const ipPortRegex = /^(https?:\/\/)?([^\/:]+)(:\d+)?/i; const matches = currentUrl.match(ipPortRegex); let ip = ""; let port = ""; if (matches && matches[2]) { // 提取IP或域名 ip = matches[2]; // 处理IPv6地址(如[::1]) if (ip.startsWith("[") && ip.endsWith("]")) { ip = ip.substring(1, ip.length - 1); } // 提取端口号 if (matches[3]) { port = matches[3].substring(1); // 去掉前面的冒号 } else { // 默认端口 port = window.location.protocol === "https:" ? "443" : "80"; } } console.log("IP:", ip); console.log("Port:", port); // 返回结果对象 const result = { ip: ip, port: port, fullAddress: ip + (port ? ":" + port : "") }; this.locationInfo = result; console.log(this.locationInfo, "this.locationInfo"); }, methods: { // 切换视频 changeVideo(index) { this.currentVideo = index; this.videoUrl = `http://${this.locationInfo.ip}:${ this.locationInfo.port }/videoPlayer/#/index?url=${ this.videoList[this.currentVideo] }&plugin=hls.js`; }, // 点击显示全部闸井 showAllWells(val) { if (val) { // 显示全部 this.pointColor = "#66CDAA"; this.listQuery.isAlarm = "0"; this.zoom = 15; this.filterAlarm(false, ""); } else { // 仅显示报警 this.listQuery.isAlarm = "1"; this.filterAlarm(true, ""); } }, // 显示无设备的 showNoDeviceWells() { if (this.showNoDeviceWell) { this.pointColor = "#f1c353"; this.showAll = false; this.showDeviceWell = false; this.zoom = 15; this.filterAlarm("", false); } else { this.showMarkers = []; } }, // 显示有设备的 showDeviceWells() { if (this.showDeviceWell) { this.pointColor = "#66CDAA"; this.showAll = false; this.showNoDeviceWell = false; this.zoom = 15; this.filterAlarm("", true); } else { this.showMarkers = []; } }, // 30s倒计时 countDown() { this.clock = window.setInterval(() => { this.count--; if (this.count < 0) { // 当倒计时小于0时清除定时器 this.refreshAlarmIcon(); this.count = 30; } }, 1000); }, // 更换地图中心计时器,暂时无用 countDownCenter() { console.log("countDownCenter"); this.clock2 = window.setInterval(() => { this.refreshCenter(); }, 5000); }, // 加载组织列表树形下拉菜单 fetchPcode: function() { const listQuery = { deptType: "03" }; getDeptTreeList(listQuery).then(response => { const list = response.data.list; if (list.length <= 1) { this.showDeptSelect = false; } else { // list.push({ id: '0', name: '顶级', open: true, value: '0' }) if (list) { // 如果有必要转树 if (judgeTree(list)) { this.deptTreeList = toTreeList( response.data.list, "0", this.needTop ); } else { this.deptTreeList = list; } console.log(this.deptTreeList); } } }); }, webSocket() { const that = this; if (typeof WebSocket === "undefined") { this.$notify({ title: "提示", message: "当前浏览器无法接收实时报警信息,请使用谷歌浏览器或360浏览器极速模式!", type: "warning", duration: 0 }); } else { // 获取token保存到vuex中的用户信息,此处仅适用于本项目,注意删除或修改 // 实例化socket,这里我把用户名传给了后台,使后台能判断要把消息发给哪个用户,其实也可以后台直接获取用户IP来判断并推送 // const socketUrl = 'ws://192.168.0.203:9100/army/webSocket/' + this.$store.getters.username // const socketUrl = 'ws://111.198.10.15:11707/army/webSocket/' + this.$store.getters.username const socketUrl = "ws://10.9.39.8:8080/army/webSocket/" + this.$store.getters.username; // const socketUrl = 'ws://127.0.0.1:8090/ws/' + this.$store.getters.username console.log(socketUrl); this.socket = new WebSocket(socketUrl); // 监听socket打开 this.socket.onopen = function() { console.log("浏览器WebSocket已打开"); }; // 监听socket消息接收 this.socket.onmessage = function(msg) { // 转换为json对象 const data = JSON.parse(msg.data); that.refreshAlarm(true); that.playAudio(); that.$notify({ title: "新报警来了", // 这里也可以把返回信息加入到message中显示 message: data.message, type: "warning", onClick: () => { that.$router.push({ path: "/overview" }); } }); }; // 监听socket错误 this.socket.onerror = function() { that.$notify({ title: "服务器错误", message: "无法接收实时报警信息,请检查服务器后重新刷新页面", type: "error", duration: 0 }); }; // 监听socket关闭 this.socket.onclose = function() { console.log("WebSocket已关闭"); }; } }, // 清除选择 clearSelected() { this.listQuery.deptid = []; this.listQuery.wellType = ""; if (this.showAll) { this.filterAlarm(false, ""); } else { this.filterAlarm(true, ""); } }, // 获取闸井类型 fetchWellType() { getWellType().then(response => { this.wellTypeList = []; this.wellTypeDict = {}; const wellTypes = this.$store.getters.wellTypes; for (const wellType of response.data) { if (wellTypes.indexOf(wellType.value) !== -1) { this.wellTypeList.push(wellType); this.wellTypeDict[wellType.value] = wellType.name; } } if (this.wellTypeList.length <= 1) { this.showWellType = false; } }); }, // 数据查询,返回条符合查询结果的数据 search() { // 关闭显示的弹框 this.currentWindow.visible = false; // 查询条件判空 const keywords = this.keywords; // 输入查询条件 if (keywords === "") { this.$message.warning("查询条件不能为空"); return; } // 清空筛选条件 this.listQuery.deptid = []; this.listQuery.wellType = ""; this.showAll = false; // 查询全部井,是否匹配,匹配则显示marker this.searchWells = []; // 符合查询结果放入searchWells,查询前先置空 this.showMarkers = []; // 清空所有marker for (const alarmWell of this.alarmWells) { alarmWell.visible = true; } // this.showMarkers = [] // 需要显示的结果放入showMarkers for (const marker of this.markers) { let show = true; if ( keywords && keywords !== "" && !( marker.wellCode.indexOf(keywords) !== -1 || marker.positionInfo.indexOf(keywords) !== -1 ) ) { show = false; } if (show) { marker.icon = "static/BMap/images/well-common.svg"; this.searchWells.push(marker); // this.showMarkers.push(marker) } } // 如果没有找到符合要求的井 if (this.searchWells.length === 0) { this.$message.warning("查无结果"); } else { this.handleCurrentChange(1); this.center = this.searchWells[0].position; this.zoom = 17; this.showSelectList = true; } }, // 数据筛选 filter() { // 清空搜索条件 this.keywords = ""; this.searchWells = []; // 根据筛选条件部门,井类型,报警状态进行筛选 const deptid = []; for (const deptList of this.listQuery.deptid) { let lastIndex = deptList.length - 1; if (lastIndex >= 3) { lastIndex--; } deptid.push(deptList[lastIndex]); // deptid.concat(deptList) } console.log(deptid); const wellType = this.listQuery.wellType; // const isAlarm = this.listQuery.isAlarm const hideWellIds = []; const hideWellCodes = []; // 如果查询条件为空,直接全部返回 if (deptid && deptid.length === 0 && wellType === "") { this.showMarkers = this.markers; this.showAll = true; } else { this.showMarkers = []; const centerxs = []; const centerys = []; this.showAll = false; for (const marker of this.markers) { let show = true; // 部门不为空, 且没有匹配成功 if ( deptid && deptid.length > 0 && deptid.indexOf(marker.deptid) === -1 ) { show = false; } // 井类型不为空,且没有匹配成功 if (wellType && wellType !== "" && marker.wellType !== wellType) { show = false; } // 如果符合显示的条件 if (show) { this.showMarkers.push(marker); centerxs.push(parseFloat(marker.lng)); centerys.push(parseFloat(marker.lat)); marker.visible = true; } else { hideWellIds.push(marker.wellId); hideWellCodes.push(marker.wellCode); marker.visible = false; } } centerxs.sort(); centerys.sort(); const index = Math.floor(centerxs.length / 2); this.center = { lng: centerxs[index], lat: centerys[index] }; this.zoom = 15; } console.log(hideWellCodes.length); for (const alarmWell of this.alarmWells) { if (hideWellIds.indexOf(alarmWell.wellId) > -1) { alarmWell.visible = false; } else { alarmWell.visible = true; } } this.hideWellCodes = hideWellCodes; if (this.showMarkers) { this.$message.success( "共找到符合筛选条件的闸井 " + this.showMarkers.length + " 个" ); } }, // 报警筛选 filterAlarm(isAlarm, isDevice) { console.log(this.markers.length); // 清除筛选、搜索条件 this.listQuery.wellType = ""; this.listQuery.deptid = []; this.keywords = ""; this.searchWells = []; const hideWellCodes = []; if (isAlarm === false) { // 全部 for (const alarmWell of this.alarmWells) { alarmWell.visible = true; } this.hideWellCodes = hideWellCodes; this.showMarkers = this.markers; } else { // 报警 +‘’ this.showMarkers = []; for (const alarmWell of this.alarmWells) { alarmWell.visible = true; } if (isDevice === true) { this.showMarkers = this.markers.filter(function(marker) { if (marker.wellFlag !== "0") { return marker; } }); } else if (isDevice === false) { this.showMarkers = this.markers.filter(function(marker) { if (marker.wellFlag === "0") { return marker; } }); } } }, // 获取报警的闸井列表 getWellList() { this.loading = true; const listQuery = { keywords: "", // 关键字 wellType: "", // 井类型 deptid: "", // 组织机构 isAlarm: "1" // 报警状态 }; getWellList(listQuery).then(response => { this.loading = false; if (response.code === 200) { const wells = response.data; if (wells.length > 0) { // 正在报警的井 if (listQuery.isAlarm === "1") { const centerxs = []; const centerys = []; for (const well of wells) { const marker = { wellId: well.id, wellCode: well.wellCode, position: { lng: parseFloat(well.lngBaidu), lat: parseFloat(well.latBaidu) }, lng: parseFloat(well.lngBaidu), lat: parseFloat(well.latBaidu), positionInfo: well.position, wellType: well.wellType, wellFlag: well.wellFlag, wellTypeName: well.wellTypeName, deptName: well.deptName, deptid: well.deptid, bfzt: well.bfzt, visible: true, wellStatus: "normal" }; this.markers.push(marker); // this.showMarkers.push(marker) centerxs.push(parseFloat(well.lngBaidu)); centerys.push(parseFloat(well.latBaidu)); } centerxs.sort(); centerys.sort(); const index = Math.floor(centerxs.length / 2); this.center = { lng: centerxs[index], lat: centerys[index] }; } } } }); }, // 获取正常的闸井列表 getNormalWellList() { const listQuery = { keywords: "", // 关键字 wellType: "", // 井类型 deptid: "", // 组织机构 isAlarm: "0" }; getWellList(listQuery).then(response => { this.loading = false; if (response.code === 200) { const wells = response.data; if (wells.length > 0) { // 正在报警的井 if (listQuery.isAlarm === "0") { // 状态正常的井 this.firstAmount = true; for (const well of wells) { this.markers.push({ wellId: well.id, wellCode: well.wellCode, position: { lng: parseFloat(well.lngBaidu), lat: parseFloat(well.latBaidu) }, lng: parseFloat(well.lngBaidu), lat: parseFloat(well.latBaidu), positionInfo: well.position, wellType: well.wellType, wellFlag: well.wellFlag, deptid: well.deptid, bfzt: well.bfzt, // icon: this.icons[well.wellType], icon: this.commonIcon, visible: true, wellStatus: "normal" }); } } } } }); }, // 点击闸井详情气泡 openInfoWindow(point) { const wellId = point.wellId; console.log("click well"); this.videoList = []; this.currentVideo = ""; this.videoUrl = ""; this.currentWindow.visible = false; getWellInfo(wellId).then(response => { if (response.code === 200) { const wellInfo = response.data; this.wellInfo = { wellCode: wellInfo.wellCode, position: wellInfo.position, wellTypeName: wellInfo.wellTypeName, deptName: wellInfo.deptName, bfztName: wellInfo.bfztName, deep: wellInfo.deep, owner: wellInfo.owner, pidName: wellInfo.pidName }; this.currentWindow.position = { lng: wellInfo.lngBaidu, lat: wellInfo.latBaidu }; this.$nextTick(() => { this.currentWindow.visible = true; this.currentWindow.windowType = "info"; }); } }); // 获取摄像头列表 // this.videoList = [ // 'http://kbs-dokdo.gscdn.com/dokdo_300/definst/dokdo_300.stream/playlist.m3u8', // 'http://kbs-dokdo.gscdn.com/dokdo_300/definst/dokdo_300.stream/playl1ist.m3u8' // ] // this.currentVideo = 0; // this.videoUrl = `http://${this.locationInfo.ip}:${ // this.locationInfo.port // }/videoPlayer/#/index?url=${ // this.videoList[this.currentVideo] // }&plugin=hls.js`; getWellVideo(wellId).then(res => { this.videoList = res.data; if (this.videoList.length) { this.currentVideo = 0; // http://111.198.10.15:21904/videoPlayer/#/index?url=http://kbs-dokdo.gscdn.com/dokdo_300/definst/dokdo_300.stream/playlist.m3u8&plugin=hls.js this.videoUrl = `http://${this.locationInfo.ip}:${ this.locationInfo.port }/videoPlayer/#/index?url=${ this.videoList[this.currentVideo] }&plugin=hls.js`; } }); }, // 刷新报警列表 refreshAlarm(showWindow = false) { console.log("refreshAlarm"); this.count = 30; getAlarmsNow().then(response => { if (response.code === 200) { this.alarmList = response.data; if (this.alarmList.length > 0) { this.hasAlarm = true; } const nowTime = new Date().getTime(); this.alarmWells = []; for (const alarm of response.data) { const alarmTime = new Date(alarm.alarmTime).getTime(); // 判断图标 let icon = this.alarmicon; if (nowTime - alarmTime > 60000) { // 时间差小于一分钟用动画,否则用静态图片 icon = this.alarmicon; } else { icon = this.alarmgificon; } this.alarmWells.push({ wellCode: alarm.wellCode, wellId: alarm.wellId, wellType: alarm.wellType, position: { lng: alarm.lngBaidu, lat: alarm.latBaidu }, positionInfo: alarm.position, alarmTime: alarm.alarmTime, icon: icon, visible: true }); } // 如果要显示infoWindow, 将最新一条报警弹窗展示 if (showWindow) { this.alarmNew(); } } }); this.centerIndex = 0; }, // 筛选是否报警井 // 刷新地图中心,打开最新报警窗口,暂时无用 refreshCenter() { const centerIndex = this.centerIndex; if (this.alarmWells.length > 0) { const alarm = this.alarmWells[centerIndex]; this.center = alarm.position; this.centerIndex = centerIndex >= this.alarmWells.length - 1 ? 0 : centerIndex + 1; this.openAlarmWindow(alarm.wellId, alarm.position, alarm); } }, // 显示最新报警的弹窗 alarmNew() { if (this.alarmWells.length > 0) { const alarm = this.alarmWells[0]; this.center = alarm.position; this.openAlarmWindow(alarm.wellId, alarm.position, alarm); } }, // 刷新报警图片 refreshAlarmIcon() { const nowTime = new Date().getTime(); for (const alarmWell of this.alarmWells) { const alarmTime = new Date(alarmWell.alarmTime).getTime(); if (nowTime - alarmTime > 60000) { // 时间差小于一分钟用动画,否则用静态图片 alarmWell.icon = this.alarmicon; } else { alarmWell.icon = this.alarmgificon; } } }, // 点击报警详情 openAlarmWindow(wellId, position, alarm) { this.videoList = []; this.currentVideo = ""; this.videoUrl = ""; this.wellInfo.wellCode = ""; // 旧弹窗不显示 this.currentWindow.visible = false; // 清空查询条件 this.keywords = ""; // this.listQuery.wellType = '' // this.listQuery.deptid = [] getWellAlarms(wellId).then(response => { if (response.code === 200) { const wellInfo = response.data; this.alarmInfo = { wellCode: wellInfo.wellCode, position: wellInfo.position, deptName: wellInfo.deptName, alarms: wellInfo.alarmList, deep: wellInfo.deep, owner: wellInfo.owner, pidName: wellInfo.pidName }; this.currentWindow.position = position; this.$nextTick(() => { this.currentWindow.visible = true; this.currentWindow.windowType = "alarm"; }); } }); // 获取历史视频 // console.log(alarm, "123"); if (alarm.alarmTime) { getWellHistoryVideo( wellId, dayjs(well.alarmTime) .subtract(30, "second") .format("YYYY-MM-DD HH:mm:ss"), dayjs(well.alarmTime) .add(30, "second") .format("YYYY-MM-DD HH:mm:ss") ).then(res => { this.videoList = res.data; if (this.videoList.length) { this.currentVideo = 0; this.videoUrl = `http://${this.locationInfo.ip}:${ this.locationInfo.port }/videoPlayer/#/index?url=${ this.videoList[this.currentVideo] }&plugin=hls.js`; } }); } }, // 点击报警列表 alarmRowClick(row, column, event) { console.log("alarmRowClick"); const wellId = row.wellId; for (const alarmWell of this.alarmWells) { if (alarmWell.wellId === wellId) { if (this.zoom < 18) { this.zoom = 18; } this.openAlarmWindow(alarmWell.wellId, alarmWell.position, row); this.center = alarmWell.position; } } }, // 页码变化处理函数 handleCurrentChange(val) { console.log("handleCurrentChange"); const offset = val; const start = (offset - 1) * this.pagesize; const end = start + this.pagesize; this.searchPageWells = this.searchWells.slice(start, end); }, // 点击查询结果项,飞到中心且放大到18级 clickSearchItem(well) { this.center = well.position; this.zoom = 18; }, // 3分钟无操作定时器 startTimer() { console.log("instartTimer"); window.clearInterval(this.clock2); // 清除循环更换地图中心定时器 const that = this; window.clearTimeout(that.timeOut); that.timeOut = window.setTimeout(function() { console.log("startTimer"); that.filterAlarm(true, ""); // that.countDownCenter() }, 1000 * 60 * 1); }, // 判断超时 isTimeOut() { console.log("isTimout"); const that = this; this.startTimer(); // document.body.onmouseup = that.startTimer // document.body.onmousemove = that.startTimer document.body.onkeyup = that.startTimer; document.body.onclick = that.startTimer; // document.body.ontouchend = that.startTimer }, // 地图Ready回调 mapReady({ BMap, map }) { const that = this; this.map = map; var styleOptions = { strokeColor: "red", // 边线颜色。 fillColor: "red", // 填充颜色。当参数为空时,圆形将没有填充效果。 strokeWeight: 3, // 边线的宽度,以像素为单位。 strokeOpacity: 0.8, // 边线透明度,取值范围0 - 1。 fillOpacity: 0.6, // 填充的透明度,取值范围0 - 1。 strokeStyle: "solid" // 边线的样式,solid或dashed。 }; this.$nextTick(() => { this.drawingManager = new BMapLib.DrawingManager(map, { isOpen: false, // 是否开启绘制模式 enableDrawingTool: false, // 是否显示工具栏 drawingToolOptions: { anchor: BMAP_ANCHOR_TOP_RIGHT, // 位置 offset: new BMap.Size(70, 10), // 偏离值 drawingTypes: [ BMAP_DRAWING_CIRCLE, BMAP_DRAWING_POLYGON, BMAP_DRAWING_RECTANGLE ] }, circleOptions: styleOptions, // 圆的样式 polygonOptions: styleOptions, // 多边形的样式 rectangleOptions: styleOptions // 矩形的样式 }); // 多边形监听器 this.drawingManager.addEventListener("polygoncomplete", function( polygon ) { console.log("end polygon"); that.drawingManager.close(); that.currentPolygon = polygon; if (that.showMarkers.length > 0) { that.judgeWell(polygon); } else { that.judgeAlarmWell(polygon); } }); // 矩形监听器 this.drawingManager.addEventListener("rectanglecomplete", function( polygon ) { console.log("end rectangle"); that.drawingManager.close(); that.currentPolygon = polygon; if (that.showMarkers.length > 0) { that.judgeWell(polygon); } else { that.judgeAlarmWell(polygon); } }); }); // 实例化鼠标绘制工具 }, // 绘制选框 drawBox(type) { if (this.currentPolygon) { this.map.removeOverlay(this.currentPolygon); } if (type == "Polygon") { console.log("start polygon"); this.drawingManager.setDrawingMode(BMAP_DRAWING_POLYGON); } else if (type === "Rectangle") { console.log("start rectangle"); this.drawingManager.setDrawingMode(BMAP_DRAWING_RECTANGLE); } this.drawingManager.open(); this.clearDisabled = false; }, judgeWell(polygon) { let count = 0; const points = polygon.getPath(); const poly = new BMap.Polygon(points); const typeCount = {}; console.log(this.showMarkers.length); debugger; for (const item of this.showMarkers) { var ppoint = new BMap.Point( parseFloat(item.position.lng), parseFloat(item.position.lat) ); var result = BMapLib.GeoUtils.isPointInPolygon(ppoint, poly); if (result) { if ( item.wellType && typeof typeCount[item.wellType] !== "undefined" ) { typeCount[item.wellType]++; } else if (item.wellType) { typeCount[item.wellType] = 1; } count++; } } let typeStr = "其中包含"; let typeCountList = []; const typeStrList = []; // 生成井类型-数量对象数组 for (const key in typeCount) { typeCountList.push({ type: this.wellTypeDict[key], value: typeCount[key] }); // typeStrList.push(this.wellTypeDict[key]+typeCount[key]+'个') } // 按数量排序 typeCountList = typeCountList.sort((x, y) => y.value - x.value); // 转为字符串数组 for (const item of typeCountList) { // typeCountList.push({type:this.wellTypeDict[key],value:typeCount[key]}) typeStrList.push(item.type + item.value + "个"); } // 组装成字符串 typeStr += typeStrList.join(";") + "。"; const finalStr = "该区域内有" + count + "个井。" + (count > 0 ? typeStr : ""); this.$alert(finalStr, "区域统计", { confirmButtonText: "确定" }); }, judgeAlarmWell(polygon) { let count = 0; const points = polygon.getPath(); const poly = new BMap.Polygon(points); const typeCount = {}; for (const item of this.alarmWells) { var ppoint = new BMap.Point( parseFloat(item.position.lng), parseFloat(item.position.lat) ); var result = BMapLib.GeoUtils.isPointInPolygon(ppoint, poly); if (result) { debugger; if ( item.wellType && typeof typeCount[item.wellType] !== "undefined" ) { typeCount[item.wellType]++; } else if (item.wellType) { typeCount[item.wellType] = 1; } count++; } } let typeStr = "其中包含"; let typeCountList = []; const typeStrList = []; // 生成井类型-数量对象数组 for (const key in typeCount) { typeCountList.push({ type: this.wellTypeDict[key], value: typeCount[key] }); // typeStrList.push(this.wellTypeDict[key]+typeCount[key]+'个') } // 按数量排序 typeCountList = typeCountList.sort((x, y) => y.value - x.value); // 转为字符串数组 for (const item of typeCountList) { // typeCountList.push({type:this.wellTypeDict[key],value:typeCount[key]}) typeStrList.push(item.type + item.value + "个"); } // 组装成字符串 typeStr += typeStrList.join(";") + "。"; const finalStr = "该区域内有" + count + "个井。" + (count > 0 ? typeStr : ""); this.$alert(finalStr, "区域统计", { confirmButtonText: "确定" }); }, drawDelete() { // if(this.drawingManager.getDrawingMode()){ this.drawingManager.close(); if (this.currentPolygon) { this.map.removeOverlay(this.currentPolygon); this.clearDisabled = true; } // } } } }; </script> <style rel="stylesheet/scss" lang="scss"> .active-btn-video { border: 1px solid #000 !important; } // 查询框 .map-search-div { position: absolute; z-index: 100; left: 10px; top: 10px; .el-form-item { margin-bottom: 0px; } } // 报警列表 .map-alarm-div { position: absolute; z-index: 100; background-color: rgba(255, 234, 241, 0.8); top: 60px; left: 10px; .map-alarm-div-header { line-height: 40px; width: 504px; padding-left: 10px; .icon-right { position: absolute; right: 15px; } .icon-right:hover { color: #409eff; cursor: pointer; } } .el-table th { /*background-color: rgba(255, 229, 230, 0.8);*/ padding: 7px 0px; } .el-table td { /*background-color: rgba(255, 234, 241, 0.8);*/ padding: 5px 0px; /*line-height: 1;*/ } .el-table td:hover { /*background-color: rgba(255, 234, 241, 0.8);*/ } .transition-box { margin-bottom: 10px; width: 200px; height: 100px; border-radius: 4px; background-color: #409eff; text-align: center; color: #fff; padding: 40px 20px; box-sizing: border-box; margin-right: 20px; } } // 刷新框 .refresh-div { position: absolute; right: 10px; top: 7px; z-index: 100; padding: 10px; color: #ce8b74; font-size: 14px; background-color: rgba(244, 233, 230, 1); .font-red { color: red; font-weight: bold; } .el-icon-refresh:hover { color: red; font-weight: bold; cursor: pointer; } } // 地图 .overview-map-container { width: 100%; padding: 5px; .map-demo { width: 100%; height: calc(100vh - 78px); .svg-icon { width: 20px; height: 20px; } .alarm-icon { width: 30px; height: 30px; } .nomal-info-window { /*background-color: pink;*/ } .info-window { max-width: 280px; /*background-color: lightcyan;*/ .info-header { padding: 10px 10px 5px 10px; line-height: 30px; font-weight: bold; /*background-color: #eaf4ff;*/ } .info-body { padding: 5px 10px 5px 10px; line-height: 23px; font-size: 14px; } } .BMap_bubble_title { font-weight: bold; padding: 0px 10px 5px 10px; } .alarm-window { max-width: 250px; /*background-color: #ffeaf1;*/ .alarm-header { padding: 10px 10px 5px 10px; line-height: 30px; color: red; font-weight: bold; /*background-color: #ffecec;*/ } .alarm-body { padding: 5px 10px 10px 10px; line-height: 23px; font-size: 14px; .alarm-red { color: #ff0000; } } } } } .el-divider--horizontal { margin: 5px 0; } .toolbox { position: absolute; right: 20px; top: 70px; z-index: 100; } .toolbox-content { background-color: #e9eef2; width: 350px; top: 60px; z-index: 100; padding: 20px 5px -5px 10px; } .alarmButton { position: absolute; right: 20px; top: 20px; z-index: 100; } .alarm-list-popper { /*max-height: 200px;*/ /*overflow: hidden;*/ /*background-color: rgba(244, 233, 230, 1.0);*/ .map-alarm-content { .alarm-list-table { background-color: rgba(244, 233, 230, 1); } .alarm-list-header { background-color: red; } } .el-scrollbar { /*height: 200px;*/ width: 100%; } .moredatascollor { height: 250px; } .el-scrollbar__wrap { overflow-y: auto; overflow-x: hidden; margin-bottom: 0px !important; } } .selectAnswer { width: 290px; background-color: #ffffff; border: 1px solid #d3dce6; padding-left: 10px; padding-top: 8px; padding-bottom: 8px; position: absolute; border-radius: initial; left: 10px; top: 55px; z-index: 100; text-align: left; .el-card__body { padding: 5px; font-size: 14px; color: #409eff; } } .search-card { padding: 5px 10px; overflow: auto; .card-left, .card-right { float: left; } .card-left { width: 10%; line-height: 25px; } .card-right { width: 90%; } .card-title { font-size: 16px; font-weight: bold; line-height: 25px; } .card-welltype { line-height: 25px; } } .clear { clear: both; } .search-card:hover { background-color: #f5f5f5; cursor: pointer; } .small-alarm-window { } .selectDiv { .el-form--label-top .el-form-item__label { padding: 0 0 0px; } .el-form-item { margin-bottom: 15px; } } .draw-tools { position: absolute; top: 20px; right: 90px; z-index: 100; display: flex; } </style>