@@ -20,7 +20,7 @@ export function createTask(data) { | |||
*/ | |||
export function getTaskList(params) { | |||
return request({ | |||
url: '/mission/page', | |||
url: '/mission/page?type=1', | |||
method: 'GET', | |||
params | |||
}) | |||
@@ -190,6 +190,7 @@ export function emergencyRecord(params) { | |||
export function uavInfo(id) { | |||
return request({ | |||
url: `/airport/drone/data/${id}`, | |||
method: 'GET' | |||
method: 'GET', | |||
hideMessage: true | |||
}) | |||
} |
@@ -11,7 +11,7 @@ | |||
<ul ref="scrollRef"> | |||
<li v-for="(item,index) in list" :key="index" @click="handleClick(item)"> | |||
<n-ellipsis :tooltip="false"> | |||
{{ item.name }} | |||
{{ `${item.airportName}正在执行${item.name}, 飞行中` }} | |||
</n-ellipsis> | |||
</li> | |||
</ul> | |||
@@ -148,12 +148,12 @@ export default defineComponent({ | |||
display: flex; | |||
align-items: center; | |||
.header__scroll{ | |||
width: 250px; | |||
width: 450px; | |||
margin-right: 50px; | |||
position: relative; | |||
} | |||
.scroll__content{ | |||
width: 250px; | |||
width: 450px; | |||
height: 30px; | |||
overflow: hidden; | |||
position: absolute; | |||
@@ -164,7 +164,7 @@ export default defineComponent({ | |||
transition: all .5s; | |||
} | |||
li{ | |||
width: 250px; | |||
width: 450px; | |||
line-height: 30px; | |||
color: rgba(255,255,255,1); | |||
cursor: pointer; |
@@ -66,6 +66,7 @@ export default { | |||
{ icon: new URL('../../../assets/images/north.png', import.meta.url).href, indicatorValue: null, indicatorName: '风向' }, | |||
{ icon: new URL('../../../assets/images/atmosPressure.png', import.meta.url).href, indicatorValue: null, indicatorName: '大气压力' }, | |||
{ icon: new URL('../../../assets/images/airHumidity.png', import.meta.url).href, indicatorValue: null, indicatorName: '空气湿度' }, | |||
{ icon: new URL('../../../assets/images/rainfall.png', import.meta.url).href, indicatorValue: null, indicatorName: '降雨量' }, | |||
{ icon: new URL('../../../assets/images/airTemperature.png', import.meta.url).href, indicatorValue: null, indicatorName: '空气温度' }], | |||
innerMonitorOptions: { | |||
// width: '256px', | |||
@@ -90,14 +91,14 @@ export default { | |||
const initPlayer = (innerUrl, outerUrl) => { | |||
const inner = { | |||
width: '256px', | |||
height: '198px', | |||
width: '273px', | |||
height: '200px', | |||
source: innerUrl, | |||
isLive: true | |||
} | |||
const outer = { | |||
width: '256px', | |||
height: '198px', | |||
width: '273px', | |||
height: '200px', | |||
source: outerUrl, | |||
isLive: true | |||
} | |||
@@ -114,7 +115,7 @@ export default { | |||
getAirportInfo(data.detail.id) | |||
.then(res => { | |||
if (res.code === 0) { | |||
// console.log(res, '机场详情') | |||
console.log(res.data, '机场详情') | |||
data.mountedName = res.data.mountName | |||
const status = parseFloat(res.data.status) | |||
switch (status) { | |||
@@ -130,7 +131,7 @@ export default { | |||
item.indicatorValue = res.data.wspd | |||
break | |||
case 1: | |||
item.indicatorValue = res.data.wdir | |||
item.indicatorValue = res.data.wdirName | |||
break | |||
case 2: | |||
item.indicatorValue = res.data.hpa | |||
@@ -139,7 +140,12 @@ export default { | |||
item.indicatorValue = res.data.hum | |||
break | |||
case 4: | |||
item.indicatorValue = res.data.rainfull | |||
break | |||
case 5: | |||
item.indicatorValue = res.data.tmp | |||
break | |||
default: | |||
} | |||
}) | |||
} | |||
@@ -232,8 +238,8 @@ td{ | |||
justify-content: space-around; | |||
.innerMonitor { | |||
position: relative; | |||
width: 275px; | |||
height: 198px; | |||
width: 280px; | |||
height: 200px; | |||
.monitorName { | |||
position: absolute; | |||
bottom: 8px; |
@@ -103,7 +103,7 @@ import { cameraList } from '@/api/basic/monitor.js' | |||
import { materialList } from '@/api/basic/material.js' | |||
import { formatDate } from '@/utils/index.js' | |||
import { QUESTION_TYPE } from '@/utils/dictionary.js' | |||
import personnel_icon from '@/assets/images/personnelActivities.png' | |||
import smoke_icon from '@/assets/images/smoke.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' | |||
@@ -114,8 +114,8 @@ import { implement } from '@/api/task/index.js' | |||
const ICON_LIST = { | |||
'002000': problemSpot_icon, | |||
'002001': deadTree_icon, | |||
'002003': personnel_icon, | |||
'002004': fireHazard_icon | |||
'002003': fireHazard_icon, | |||
'002004': smoke_icon | |||
} | |||
export default { | |||
name: 'MapExtend', |
@@ -94,7 +94,6 @@ | |||
import { reactive, toRefs, watch } from 'vue' | |||
import { EARLY_SOURCE, TASK_STATUS } from '@/utils/dictionary.js' | |||
import { getWarningRecord, getWarningInfo, ignoreWarning, confirmWarning, pointflight } from '@/api/dashboard/index.js' | |||
import { useInspectionStore } from '@/store/modules/inspection.js' | |||
// turf 用于简单的空间计算 | |||
import * as turf from '@turf/turf' | |||
export default { | |||
@@ -110,9 +109,8 @@ export default { | |||
default: () => { } | |||
} | |||
}, | |||
emits: ['start'], | |||
emits: ['start', 'close'], | |||
setup(props, { emit }) { | |||
const inspectionStore = useInspectionStore() | |||
const data = reactive({ | |||
airpotOptions: [], | |||
airport: {}, | |||
@@ -181,7 +179,7 @@ export default { | |||
var status = '' | |||
var statusNum = 0 | |||
record?.data?.map((item) => { | |||
if (item?.status !== 3 || item?.status !== 1) { | |||
if (item?.status !== 3 && item?.status !== 1) { | |||
TASK_STATUS?.forEach((val) => { | |||
if (val.value === item.status) { | |||
status = val.label | |||
@@ -269,6 +267,7 @@ export default { | |||
const closeWarning = () => { | |||
closeAirport() | |||
data.warningShow = false | |||
emit('close') | |||
} | |||
const executeNow = async() => { |
@@ -29,7 +29,7 @@ | |||
/> | |||
</div> | |||
<fire-alarm ref="Warning" :data="warningDetail" :airport="airportsAll" @start="handleExecute" /> | |||
<fire-alarm ref="Warning" :data="warningDetail" :airport="airportsAll" @start="handleExecute" @close="closeWarningTab" /> | |||
<WarningDrawer v-model:visible="drawerShow" @refresh:id="refreshRecord" /> | |||
@@ -49,6 +49,7 @@ import { Style, Icon, Text, Fill, Circle } from 'ol/style' | |||
import * as control from 'ol/control' | |||
import uav_icon from '@/assets/images/airport.png' | |||
import warningIcon from '@/assets/gis/images/fire.png' | |||
import warningSelectIcon from '@/assets/gis/images/fire_select.png' | |||
import { reactive, toRefs, onMounted, computed, ref, watch, onBeforeUnmount, provide } from 'vue' | |||
import { Point } from 'ol/geom' | |||
import { | |||
@@ -112,7 +113,8 @@ export default { | |||
warningList: [], | |||
warningLayers: [], | |||
warningDetail: {}, | |||
drawerShow: false | |||
drawerShow: false, | |||
warningSelected: null | |||
}) | |||
const getMapOptions = computed(() => { | |||
@@ -185,6 +187,7 @@ export default { | |||
// 预警 | |||
if (properties.type === 'warning') { | |||
data.warningDetail = properties.props | |||
data.warningSelected = properties.props.id | |||
} | |||
} | |||
} | |||
@@ -504,34 +507,12 @@ export default { | |||
const addWarninglayer = (warningList) => { | |||
const Features = [] | |||
warningList?.map((item) => { | |||
// if (item.flag === 0) { | |||
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' | |||
}) | |||
}), | |||
new Style({ | |||
// 将点设置成圆形样式 | |||
image: new Circle({ | |||
// 点的颜色 | |||
fill: new Fill({ | |||
color: 'rgba(0,0,0,0)' | |||
}), | |||
// 圆形半径 | |||
radius: 20 | |||
}) | |||
}) | |||
]) | |||
// 要素设置属性 | |||
feature.setProperties({ | |||
// 类型设为 预警 | |||
@@ -539,8 +520,52 @@ export default { | |||
// 属性 | |||
props: item | |||
}) | |||
if (data.warningSelected === item.id) { | |||
// 要素设置样式 | |||
feature.setStyle([ | |||
new Style({ | |||
// 图标 | |||
image: new Icon({ | |||
src: warningSelectIcon, | |||
crossOrigin: 'anonymous' | |||
}) | |||
}), | |||
new Style({ | |||
// 将点设置成圆形样式 | |||
image: new Circle({ | |||
// 点的颜色 | |||
fill: new Fill({ | |||
color: 'rgba(0,0,0,0)' | |||
}), | |||
// 圆形半径 | |||
radius: 20 | |||
}) | |||
}) | |||
]) | |||
} else { | |||
// 要素设置样式 | |||
feature.setStyle([ | |||
new Style({ | |||
// 图标 | |||
image: new Icon({ | |||
src: warningIcon, | |||
crossOrigin: 'anonymous' | |||
}) | |||
}), | |||
new Style({ | |||
// 将点设置成圆形样式 | |||
image: new Circle({ | |||
// 点的颜色 | |||
fill: new Fill({ | |||
color: 'rgba(0,0,0,0)' | |||
}), | |||
// 圆形半径 | |||
radius: 20 | |||
}) | |||
}) | |||
]) | |||
} | |||
Features.push(feature) | |||
// } | |||
}) | |||
// 添加图层 | |||
@@ -702,6 +727,10 @@ export default { | |||
Warning.value.getRecord(id) | |||
} | |||
const closeWarningTab = () => { | |||
data.warningSelected = null | |||
} | |||
watch(() => inspectionStore.getList, (val) => { | |||
if (val) { | |||
data.drawerShow = true | |||
@@ -737,7 +766,8 @@ export default { | |||
getMaxZOverlay, | |||
Warning, | |||
handleExecute, | |||
refreshRecord | |||
refreshRecord, | |||
closeWarningTab | |||
} | |||
} | |||
} |
@@ -7,9 +7,9 @@ import { onMounted, reactive, toRefs, watch } from 'vue' | |||
export default { | |||
name: 'SpeedChart', | |||
props: { | |||
data: { | |||
type: Object, | |||
default: () => {} | |||
info: { | |||
type: Array, | |||
default: () => [] | |||
} | |||
}, | |||
setup(props) { | |||
@@ -17,20 +17,31 @@ export default { | |||
myChart: null, | |||
chartOption: {}, | |||
chartDom: null, | |||
chartData: {} | |||
uavData: [], | |||
uavSpeed: [], | |||
uavAlt: [], | |||
uavNo: [] | |||
}) | |||
watch(() => props.data, (value) => { | |||
if (JSON.stringify(value) !== '{}') { | |||
data.chartData = value | |||
data.myChart.dispose() | |||
initChart() | |||
watch(() => props.info, (value) => { | |||
if (value.length > 0) { | |||
data.uavData = value | |||
const uavCount = value.length | |||
data.uavSpeed.length = 0 | |||
data.uavAlt.length = 0 | |||
data.uavNo.length = 0 | |||
for (let i = 0; i < uavCount; i++) { | |||
data.uavSpeed.push(parseFloat(value[i]?.speed)) | |||
data.uavAlt.push(parseFloat(value[i]?.altitude)) | |||
data.uavNo.push(i) | |||
} | |||
setOption() | |||
data.myChart.setOption(data.chartOption) | |||
} | |||
}) | |||
const initChart = () => { | |||
data.chartDom = document.getElementById('myChart') | |||
data.myChart = echarts.init(data.chartDom) | |||
const setOption = () => { | |||
const yNumMax = Math.ceil(Math.max.apply(Math, data.uavAlt) / 10) * 10 // 划为5份,向上取整再乘5,结果为刚好大于等于最大值的5的倍数 | |||
data.chartOption = { | |||
legend: { | |||
top: '12', | |||
@@ -51,7 +62,7 @@ export default { | |||
}, | |||
xAxis: { | |||
type: 'category', | |||
data: [0, 1], | |||
data: data.uavNo, | |||
show: false | |||
}, | |||
yAxis: [ | |||
@@ -66,7 +77,9 @@ export default { | |||
textStyle: { | |||
color: 'rgba(255,255,255,1)' | |||
} | |||
} | |||
}, | |||
max: 20, | |||
interval: yNumMax / 5 | |||
}, | |||
{ | |||
type: 'value', | |||
@@ -80,14 +93,15 @@ export default { | |||
color: 'rgba(255,255,255,1)' | |||
}, | |||
formatter: '{value}' | |||
} | |||
}, | |||
max: yNumMax, | |||
interval: yNumMax / 5 | |||
} | |||
], | |||
series: [ | |||
{ | |||
name: '速度', | |||
data: data.chartData?.speed, | |||
data: data.uavSpeed, | |||
type: 'line', | |||
symbol: 'none', | |||
smooth: true, | |||
@@ -101,7 +115,7 @@ export default { | |||
}, | |||
{ | |||
name: '高度', | |||
data: data.chartData?.alt, | |||
data: data.uavAlt, | |||
type: 'line', | |||
smooth: true, | |||
symbol: 'none', | |||
@@ -115,17 +129,28 @@ export default { | |||
} | |||
] | |||
} | |||
} | |||
const initChart = () => { | |||
data.chartDom = document.getElementById('myChart') | |||
data.myChart = echarts.init(data.chartDom) | |||
data.myChart.setOption(data.chartOption) | |||
} | |||
const clearChart = () => { | |||
if (data.myChart !== null) { | |||
data.myChart.dispose() | |||
} | |||
} | |||
onMounted( | |||
() => { | |||
initChart() | |||
}) | |||
return { | |||
...toRefs(data) | |||
...toRefs(data), | |||
clearChart | |||
} | |||
} | |||
} |
@@ -48,7 +48,7 @@ | |||
</div> | |||
<div class="control__panel"> | |||
<!-- <SpeedChart :data="chartData" /> --> | |||
<SpeedChart ref="uavChart" :info="uavInfo" /> | |||
<ControlPanel v-if="showControl" mode="camera" @instruct="sendControl" /> | |||
<ControlPanel v-if="showControl" mode="locus" @instruct="sendControl" /> | |||
</div> | |||
@@ -102,6 +102,7 @@ export default defineComponent({ | |||
const sideRef = ref() | |||
const mapRef = ref() | |||
const baseMap = ref() | |||
const uavChart = ref() | |||
const videoRef = ref() | |||
const emergencyVideo = ref() | |||
const data = reactive({ | |||
@@ -109,14 +110,14 @@ export default defineComponent({ | |||
showControl: false, | |||
operate: '悬停', | |||
control: '手动控制', | |||
chartData: {}, | |||
uavFireDis: null, | |||
chartTimer: null, | |||
liveTimer: null, | |||
videoInfo: { | |||
url: null, | |||
status: 'init' | |||
} | |||
}, | |||
uavInfo: [] | |||
}) | |||
/* 获取抽屉的信息 */ | |||
@@ -142,6 +143,7 @@ export default defineComponent({ | |||
// inspectionStore.resetList() | |||
// 关闭定时器 | |||
clearTimer() | |||
uavChart.value.clearChart() | |||
} | |||
const getEmergencyRecord = async(id) => { | |||
@@ -189,18 +191,18 @@ export default defineComponent({ | |||
watch(() => inspectionStore.getList, (value) => { | |||
if (value) { | |||
// 获取无人机实时数据,绘制表格 | |||
// if (value.airportId) { | |||
// data.chartTimer = setInterval(() => { | |||
// getUavInfo(value.airportId) | |||
// }, 2000) | |||
// } | |||
if (value.airportId) { | |||
data.chartTimer = setInterval(() => { | |||
getUavInfo(value.airportId) | |||
}, 2000) | |||
} | |||
data.liveTimer = setInterval(async() => { | |||
const res = await getTaskDetail(value.id) | |||
if (res.code === 0) { | |||
if (res.data.playUrl) { | |||
clearInterval(data.liveTimer) | |||
data.liveTimer = null | |||
initOriginPlayer(value) | |||
initOriginPlayer(res.data.playUrl) | |||
} | |||
} | |||
}, 2000) | |||
@@ -210,25 +212,25 @@ export default defineComponent({ | |||
const getUavInfo = async(id) => { | |||
const res = await uavInfo(id) | |||
if (res.code === 0) { | |||
console.log(res.data) | |||
data.uavInfo = res.data | |||
} | |||
} | |||
/* 初始化播放器 */ | |||
function initOriginPlayer(value) { | |||
function initOriginPlayer(playUrl) { | |||
data.videoInfo.status = 'init' | |||
const origin = { | |||
width: '100%', | |||
height: '100%', | |||
source: value.playUrl, | |||
source: playUrl, | |||
isLive: true | |||
} | |||
emergencyVideo.value?.init(origin) | |||
setTimeout(() => { | |||
if (data.videoInfo.status === 'init') { | |||
initOriginPlayer() | |||
initOriginPlayer(playUrl) | |||
} | |||
}, 30000) | |||
}, 20000) | |||
} | |||
const calcDistance = (dis) => { | |||
@@ -241,7 +243,7 @@ export default defineComponent({ | |||
} | |||
const stopOrGo = async(value) => { | |||
if (value === '悬停') { | |||
const res = await controlAir({ | |||
await controlAir({ | |||
value: { | |||
'zhilin': '01', | |||
'taskId': inspectionStore.getList?.id, | |||
@@ -249,12 +251,8 @@ export default defineComponent({ | |||
'msg': '飞行任务' | |||
} | |||
}) | |||
if (res.code === 0) { | |||
console.log('悬停成功') | |||
} | |||
} else { | |||
const res = await controlAir({ | |||
await controlAir({ | |||
value: { | |||
'zhilin': '04', | |||
'taskId': inspectionStore.getList?.id, | |||
@@ -262,10 +260,6 @@ export default defineComponent({ | |||
'msg': '飞行任务' | |||
} | |||
}) | |||
if (res.code === 0) { | |||
console.log('继续飞行') | |||
} | |||
} | |||
} | |||
@@ -302,13 +296,12 @@ export default defineComponent({ | |||
}) | |||
if (res.code === 0) { | |||
console.log('返航成功') | |||
data.operate = '悬停' | |||
} | |||
} | |||
const airControl = async(params) => { | |||
const res = await controlAir({ | |||
await controlAir({ | |||
value: { | |||
...params, | |||
'taskId': inspectionStore.getList?.id, | |||
@@ -316,10 +309,6 @@ export default defineComponent({ | |||
'msg': '飞行任务' | |||
} | |||
}) | |||
if (res.code === 0) { | |||
console.log('成功') | |||
} | |||
} | |||
const clearTimer = () => { | |||
@@ -350,6 +339,7 @@ export default defineComponent({ | |||
sideRef, | |||
mapRef, | |||
videoRef, | |||
uavChart, | |||
...toRefs(data), | |||
getDrawerOptions, | |||
handleDrawerColse, |
@@ -25,12 +25,13 @@ | |||
<p class="title">火灾核实记录</p> | |||
<div class="content"> | |||
<p v-for="(item,index) in fireDetail.warningRecordVOList" :key="index" class="content"> | |||
{{ `${item.recordStartTime} ${item.airportName}执行任务,` }} | |||
<span>{{ `${item.recordStartTime}` }}</span> | |||
<span style="margin-left: 40px">{{ `${item.airportName}执行任务,` }}</span> | |||
<span>查看详情</span> | |||
</p> | |||
</div> | |||
<p class="title">处理记录</p> | |||
<p class="content">{{ fireDetail.checkResult }}</p> | |||
<p class="content">核实结果:{{ fireDetail.checkResult }}</p> | |||
<p class="content">处理人:{{ fireDetail.checkUser }}</p> | |||
<p class="content">处理时间:{{ fireDetail.checkTime }}</p> | |||
</template> | |||
@@ -41,6 +42,7 @@ | |||
import { defineComponent, ref, reactive, computed, toRefs, onMounted } from 'vue' | |||
import Modal from '@/components/Modal/index.vue' | |||
import { fireDetail } from '@/api/early/fire.js' | |||
import { EARLY_SOURCE } from '@/utils/dictionary.js' | |||
export default defineComponent({ | |||
name: 'UserModal', | |||
components: { Modal }, | |||
@@ -66,7 +68,8 @@ export default defineComponent({ | |||
const data = reactive({ | |||
fireDetail: { | |||
} | |||
}, | |||
warningList: [] | |||
}) | |||
const getModalOptions = computed(() => { | |||
@@ -87,6 +90,22 @@ export default defineComponent({ | |||
const res = await fireDetail(props.data.id) | |||
if (res.code === 0) { | |||
data.fireDetail = res.data | |||
data.warningList = [] | |||
EARLY_SOURCE?.map((item) => { | |||
if (item.value === parseInt(data.fireDetail?.discoveryWay)) { | |||
data.fireDetail.discoveryWay = item.label | |||
} | |||
}) | |||
// 过滤 飞行失败的任务 | |||
data.fireDetail.warningRecordVOList.map((item) => { | |||
if (item.status !== 3) { | |||
data.warningList.push(item) | |||
} | |||
}) | |||
data.fireDetail.warningRecordVOList.length = 0 | |||
data.warningList.map((item) => { | |||
data.fireDetail.warningRecordVOList.push(item) | |||
}) | |||
} else { | |||
handleClose() | |||
} |
@@ -123,7 +123,6 @@ export default { | |||
onMounted(() => { | |||
if (rowInfo) { | |||
data.rowData = JSON.parse(rowInfo) | |||
data.liveDrawer = true | |||
} | |||
}) |