@@ -5,7 +5,7 @@ VITE_PUBLIC_PATH = '/' | |||
VITE_APP_USE_MOCK = false | |||
# proxy | |||
VITE_PROXY = [["/api-local","http://127.0.0.1:8002/api"],["/api-mock","http://127.0.0.1:8003"]] | |||
VITE_PROXY = [["/api-local","https://lcxj-test.t-aaron.com/api"],["/api-mock","http://127.0.0.1:8003"]] | |||
# base api | |||
VITE_APP_GLOB_BASE_API = '/api-local' |
@@ -62,11 +62,10 @@ export function missionLive(id) { | |||
* @description:获取机场详细信息 | |||
* @param id 机场id | |||
*/ | |||
export function getAirportInfo(data) { | |||
export function getAirportInfo(id) { | |||
return request({ | |||
url: `/index/getAirportDetail/${data.airportId}`, | |||
method: 'POST', | |||
data | |||
url: `/index/getAirportDetail/${id}`, | |||
method: 'GET' | |||
}) | |||
} | |||
/** | |||
@@ -104,3 +103,20 @@ export function getQuestionList(data) { | |||
}) | |||
} | |||
// 预警列表 | |||
export function getWarning() { | |||
return request({ | |||
url: `/warning/list?status=1`, | |||
method: 'GET' | |||
}) | |||
} | |||
// 根据预警ID获取预警记录列表 | |||
export function getWarningRecord(params) { | |||
return request({ | |||
url: `/warning/record/list/by/warningid`, | |||
method: 'GET', | |||
params | |||
}) | |||
} | |||
@@ -107,8 +107,7 @@ export default { | |||
watch(() => props.data, (value) => { | |||
if (JSON.stringify(value) !== '{}') { | |||
// console.log(props.data) | |||
data.detail = props.data | |||
data.detail = value | |||
innerVideoRef.value?.disposeVideo() | |||
outVideoRef.value?.disposeVideo() | |||
initPlayer(data.detail.internalMonitorUrl, data.detail.externalMonitorUrl) |
@@ -8,15 +8,15 @@ | |||
</div> | |||
<p class="alarm-detail"> | |||
<span>火灾位置:</span> | |||
<span>xxxxxxxxxxxxxx位置</span> | |||
<span>{{ fireDetail.location }}</span> | |||
</p> | |||
<p class="alarm-detail"> | |||
<span>发现方式:</span> | |||
<span>监控摄像、无人机巡检、人工巡检</span> | |||
<span>{{ fireDetail.discoveryWay }}</span> | |||
</p> | |||
<p class="alarm-detail"> | |||
<span>上报时间:</span> | |||
<span>2023-01-28 10:00:00</span> | |||
<span>{{ fireDetail.time }}</span> | |||
</p> | |||
</div> | |||
<p class="dividing-line" /> | |||
@@ -25,6 +25,7 @@ | |||
<p class="dispatch-detail"> | |||
<span>选择机场:</span> | |||
<n-select v-model:value="value" :options="airpotOptions" /> | |||
<a>可用机场列表</a> | |||
</p> | |||
<p class="dispatch-detail"> | |||
<span>飞行高度:</span> | |||
@@ -56,16 +57,26 @@ | |||
</div> | |||
<div class="available-airports"> | |||
<p>可用机场列表</p> | |||
<div> | |||
<p class="alarm-title">可用机场列表</p> | |||
<div class="airport-params"> | |||
<p> | |||
<span>机场1</span> | |||
<span>发现隐患的机场</span> | |||
<span class="airport-name">机场1</span> | |||
<span class="airport-find">发现隐患的机场</span> | |||
</p> | |||
<p> | |||
<p class="uav-params"> | |||
<img src="@/assets/gis/images/range.png"> | |||
<span>6km</span> | |||
<span>续航里程</span> | |||
</p> | |||
<p class="uav-params"> | |||
<img src="@/assets/gis/images/power.png"> | |||
<span>60%</span> | |||
<span>无人机电量</span> | |||
<span>机场距离火灾隐患点</span> | |||
</p> | |||
<p class="uav-params" style="width: 252px"> | |||
<img src="@/assets/gis/images/measure.png"> | |||
<span style="width: 130px">3km</span> | |||
<span style="width: 130px">机场距离火灾隐患点</span> | |||
</p> | |||
</div> | |||
</div> | |||
@@ -73,7 +84,8 @@ | |||
<script> | |||
import { reactive, toRefs, watch } from 'vue' | |||
import { EARLY_SOURCE } from '@/utils/dictionary.js' | |||
import { getWarningRecord } from '@/api/dashboard/index.js' | |||
export default { | |||
name: 'FireAlarm', | |||
components: { }, | |||
@@ -95,13 +107,33 @@ export default { | |||
label: '机场2', | |||
value: 'airport2' | |||
} | |||
] | |||
], | |||
fireDetail: {} | |||
}) | |||
watch(() => props.data, (value) => { | |||
if (JSON.stringify(value) !== '{}') { | |||
data.warningList = props.data | |||
showDetail(data.warningList) | |||
} | |||
}) | |||
const showDetail = async(value) => { | |||
data.fireDetail.location = value?.location | |||
data.fireDetail.discoveryWay = '' | |||
EARLY_SOURCE?.map((item) => { | |||
if (item.value === parseInt(value?.discoveryWay)) { | |||
data.fireDetail.discoveryWay = item.label | |||
} | |||
}) | |||
data.fireDetail.time = value?.updateTime | |||
const res = await getWarningRecord({ | |||
warningId: value.id | |||
}) | |||
console.log(res) | |||
} | |||
const formatHeight = (value) => { | |||
return value + 'm' | |||
} | |||
@@ -127,19 +159,21 @@ export default { | |||
} | |||
.alarm-title { | |||
width: 100%; | |||
width: 200px; | |||
height: 30px; | |||
line-height: 30px; | |||
font-size: 14px; | |||
color: #fff; | |||
padding-left: 6px; | |||
margin-top: 10px; | |||
display: inline-block; | |||
} | |||
.alarm-detail { | |||
width: 100%; | |||
height: 30px; | |||
span:first-child { | |||
width: 90px; | |||
width: 85px; | |||
height: 30px; | |||
line-height: 30px; | |||
display: inline-block; | |||
@@ -148,7 +182,7 @@ export default { | |||
text-align: right; | |||
} | |||
span:nth-child(2){ | |||
width: 310px; | |||
width: 320px; | |||
height: 30px; | |||
line-height: 30px; | |||
display: inline-block; | |||
@@ -165,7 +199,7 @@ export default { | |||
opacity: 1; | |||
background: rgba(112, 112, 112, 1); | |||
border: 0.2px solid rgba(107, 107, 107, 1); | |||
margin: 15px 0; | |||
margin: 15px 0 0 0; | |||
} | |||
::v-deep(.dispatch-detail) { | |||
@@ -195,9 +229,13 @@ export default { | |||
display: inline-block; | |||
margin-left: 6px; | |||
vertical-align: middle; | |||
.n-slider-handle-indicator--top { | |||
margin-bottom: 0; | |||
} | |||
} | |||
a { | |||
color: rgba(0, 119, 255, 1); | |||
font-size: 10px; | |||
margin-left: 6px; | |||
cursor: pointer; | |||
} | |||
} | |||
@@ -276,5 +314,56 @@ export default { | |||
background: rgba(0, 0, 0, 1); | |||
} | |||
.airport-params { | |||
width: 278px; | |||
height: 191px; | |||
display: inline-block; | |||
border-radius: 3px; | |||
background: rgba(44, 44, 44, 1); | |||
margin-left: 3px; | |||
margin-top: 10px; | |||
} | |||
.airport-name { | |||
width: 180px; | |||
height: 30px; | |||
display: inline-block; | |||
line-height: 30px; | |||
color: #fff; | |||
font-size: 14px; | |||
padding-left: 5px; | |||
} | |||
.airport-find { | |||
width: 80px; | |||
height: 30px; | |||
font-size: 12px; | |||
color: rgba(255, 141, 26, 1); | |||
} | |||
.uav-params { | |||
width: 121px; | |||
height: 64px; | |||
border-radius: 3px; | |||
background: rgba(66, 66, 66, 1); | |||
float: left; | |||
margin: 10px 0 0 13px; | |||
img { | |||
width: 34px; | |||
height: 34px; | |||
margin: 16px 0 14px 10px; | |||
float: left; | |||
} | |||
span { | |||
width: 60px; | |||
display: inline-block; | |||
height: 30px; | |||
line-height: 30px; | |||
text-align: center; | |||
color: #fff; | |||
font-size: 12px; | |||
} | |||
} | |||
</style> | |||
@@ -29,7 +29,7 @@ | |||
/> | |||
</div> | |||
<!-- <fire-alarm /> --> | |||
<fire-alarm :data="warningDetail" /> | |||
</template> | |||
@@ -46,14 +46,11 @@ import { transform, fromLonLat } from 'ol/proj' | |||
import { Style, Icon, Text, Fill } from 'ol/style' | |||
import * as control from 'ol/control' | |||
import uav_icon from '@/assets/images/airport.png' | |||
import personnel_icon from '@/assets/images/personnelActivities.png' | |||
import problemSpot_icon from '@/assets/images/problemSpot.png' | |||
import deadTree_icon from '@/assets/images/deadTree.png' | |||
import fireHazard_icon from '@/assets/images/fireHazard.png' | |||
import warningIcon from '@/assets/gis/images/fire.png' | |||
import { reactive, toRefs, onMounted, computed, ref, watch, onBeforeUnmount } from 'vue' | |||
import { Point } from 'ol/geom' | |||
import { | |||
airportList | |||
airportList, getWarning | |||
} from '@/api/dashboard/index.js' | |||
import { getQuestions } from '@/api/task/index.js' | |||
import { gcj02towgs84 } from '@/utils/coordinate-util.js' | |||
@@ -102,7 +99,12 @@ export default { | |||
suppliesOverlay: null, | |||
suppliesDetail: {}, | |||
monitorOverlay: null, | |||
montiorName: null | |||
montiorName: null, | |||
// 预警定时器 | |||
warningTimer: null, | |||
warningList: [], | |||
warningLayers: [], | |||
warningDetail: {} | |||
}) | |||
const getMapOptions = computed(() => { | |||
@@ -179,6 +181,13 @@ export default { | |||
data.map.on('click', (evt) => { | |||
click2ShowInfo(evt) | |||
}) | |||
// 鼠标移到要素上时改变鼠标样式,由箭头变成小手 | |||
data.map.on('pointermove', function(evt) { | |||
data.map.getTargetElement().style.cursor = data.map.hasFeatureAtPixel(evt.pixel) | |||
? 'pointer' | |||
: '' | |||
}) | |||
} | |||
/** | |||
@@ -284,6 +293,8 @@ export default { | |||
const coord = properties.coordinate | |||
data.map.addOverlay(data.airOverlay) | |||
data.airOverlay.setPosition(coord) | |||
// 设置z-index | |||
data.airOverlay.getElement().parentElement.style.zIndex = getMaxZOverlay() + 1 | |||
} | |||
// 监控视频 | |||
if (properties.type === 'camera') { | |||
@@ -300,6 +311,8 @@ export default { | |||
source: properties.props.flvUrl, | |||
isLive: true | |||
}) | |||
// 设置z-index | |||
data.monitorOverlay.getElement().parentElement.style.zIndex = getMaxZOverlay() + 1 | |||
} | |||
// 监控视频 | |||
if (properties.type === 'materials') { | |||
@@ -309,16 +322,43 @@ export default { | |||
data.suppliesOverlay.setPosition(coord) | |||
// 设置属性 | |||
data.suppliesOverlay.setProperties({ 'type': properties.type }) | |||
// 设置z-index | |||
data.suppliesOverlay.getElement().parentElement.style.zIndex = getMaxZOverlay() + 1 | |||
} | |||
// 问题 | |||
if (properties.type === 'question') { | |||
data.problemDetail = properties.pros | |||
data.problemDetail = properties.props | |||
const coord = properties.geometry.flatCoordinates | |||
data.problemPopupShow = true | |||
data.map.addOverlay(data.problemOverlay) | |||
data.problemOverlay.setPosition(coord) | |||
// 设置属性 | |||
data.problemOverlay.setProperties({ 'code': properties.props.type }) | |||
// 设置z-index | |||
data.problemOverlay.getElement().parentElement.style.zIndex = getMaxZOverlay() + 1 | |||
} | |||
// 预警 | |||
if (properties.type === 'warning') { | |||
data.warningDetail = properties.props | |||
} | |||
} | |||
} | |||
/** | |||
* 获取打开overlay中最大的 z-index | |||
*/ | |||
const getMaxZOverlay = () => { | |||
let maxZIndex = 0 | |||
const overlays = data.map.getOverlays().array_ | |||
if (overlays.length) { | |||
overlays.forEach((item) => { | |||
const zIndex = item.getElement().parentElement.style.zIndex | |||
if (zIndex > maxZIndex) { | |||
maxZIndex = zIndex | |||
} | |||
}) | |||
} | |||
return maxZIndex | |||
} | |||
/** | |||
@@ -348,12 +388,23 @@ export default { | |||
} | |||
} | |||
/** | |||
* 关闭显示问题图层信息 | |||
*/ | |||
const hideProblemInfo = () => { | |||
if (data.map.getOverlayById('problem_overlay')) { | |||
data.problemDetail = {} | |||
data.map.removeOverlay(data.problemOverlay) | |||
} | |||
} | |||
const addPonit = (res) => { | |||
// 火灾预警 | |||
if (res.tabs === 0) { | |||
// 清除问题图层 | |||
removeProblemLayer() | |||
// 移除问题弹窗 | |||
hideProblemInfo() | |||
if (data.vectorLayers.length === 0) { | |||
res.data?.map((item) => { | |||
addVectorLayer(item) | |||
@@ -375,6 +426,9 @@ export default { | |||
if (layer.getProperties().type === 'camera') { | |||
monitorVideo.value?.disposeVideo() | |||
} | |||
if (layer.getProperties().type === 'materials') { | |||
data.suppliesDetail = {} | |||
} | |||
}) | |||
} | |||
} else { | |||
@@ -382,6 +436,9 @@ export default { | |||
} | |||
}) | |||
} | |||
// 展示预警 | |||
showWarning() | |||
} else { // 森林巡检 | |||
// 清除火灾预警中所有已加载的图层 | |||
removeVectorLayer() | |||
@@ -390,6 +447,7 @@ export default { | |||
if (res.ops === 'query') { | |||
removeProblemLayer() | |||
hideProblemInfo() | |||
if (res.data.length) { | |||
addProblemLayer(res.data) | |||
} | |||
@@ -397,6 +455,18 @@ export default { | |||
data.problemLayers?.map((layer) => { | |||
if (res.type.indexOf(layer.getProperties().code) === -1) { | |||
layer.setVisible(false) | |||
// 若问题图层 某种类型对应的弹框打开, 则将其关闭 | |||
// 获取所有打开的overlay | |||
const overlays = data.map.getOverlays().array_ | |||
if (overlays.length) { | |||
overlays.forEach((item) => { | |||
// 遍历 找到图层对应的overlay一并移除 | |||
if (layer.getProperties().code === item.values_.code) { | |||
data.map.removeOverlay(item) | |||
data.problemDetail = {} | |||
} | |||
}) | |||
} | |||
} else { | |||
layer.setVisible(true) | |||
} | |||
@@ -405,6 +475,74 @@ export default { | |||
} | |||
} | |||
const showWarning = () => { | |||
data.warningTimer = setInterval(() => { | |||
getWarningList().then((warningList) => { | |||
removeWarningLayer() | |||
addWarninglayer(warningList) | |||
}) | |||
}, 2000) | |||
} | |||
const getWarningList = async() => { | |||
const res = await getWarning() | |||
if (res.code === 0) { | |||
const warningList = res.data | |||
data.warningList = warningList | |||
return warningList | |||
} | |||
} | |||
const addWarninglayer = (warningList) => { | |||
const Features = [] | |||
warningList?.map((item) => { | |||
const lngLat = | |||
[parseFloat(item.lng), | |||
parseFloat(item.lat)] | |||
const feature = new Feature({ | |||
geometry: new Point(fromLonLat(lngLat)) | |||
}) | |||
// 要素设置样式 | |||
feature.setStyle( | |||
new Style({ | |||
// 图标 | |||
image: new Icon({ | |||
src: warningIcon, | |||
crossOrigin: 'anonymous' | |||
}) | |||
}) | |||
) | |||
// 要素设置属性 | |||
feature.setProperties({ | |||
// 类型设为 预警 | |||
type: 'warning', | |||
// 属性 | |||
props: item | |||
}) | |||
Features.push(feature) | |||
}) | |||
// 添加图层 | |||
const warningLayer = new VectorLayer({ | |||
source: new VectorSource({ | |||
features: Features | |||
}), | |||
visible: true | |||
}) | |||
// 添加图层 | |||
data.map.addLayer(warningLayer) | |||
data.warningLayers.push(warningLayer) | |||
} | |||
const removeWarningLayer = () => { | |||
data.warningLayers.map((layer) => { | |||
if (layer !== null) { | |||
data.map.removeLayer(layer) | |||
} | |||
}) | |||
data.warningLayers.length = 0 | |||
} | |||
/** | |||
* 添加问题图层 | |||
* @param {*} item | |||
@@ -543,7 +681,9 @@ export default { | |||
monitorVideo, | |||
hideMonitor, | |||
removeAllOverlays, | |||
removeProblemLayer | |||
removeProblemLayer, | |||
hideProblemInfo, | |||
getMaxZOverlay | |||
} | |||
} | |||
} |
@@ -66,6 +66,7 @@ export default { | |||
}) | |||
watch(() => props.detail, (value) => { | |||
console.log(value) | |||
if (JSON.stringify(value) !== '{}') { | |||
const fileImageList = value.fileMarkerUrl.split(',') | |||
data.fileImageList = [] |
@@ -1,6 +1,6 @@ | |||
<template> | |||
<div class="basic"> | |||
<OneMap ref="Map"/> | |||
<OneMap ref="Map" /> | |||
<Extend ref="extendRef" class="extend" @send="getmessage" /> | |||
</div> | |||
</template> |