"vite-plugin-svg-icons": "^2.0.1", | "vite-plugin-svg-icons": "^2.0.1", | ||||
"vue": "^3.2.16", | "vue": "^3.2.16", | ||||
"vue-router": "^4.0.14", | "vue-router": "^4.0.14", | ||||
"vue3-video-play": "^1.3.1-beta.6", | |||||
"vuedraggable": "^4.1.0" | "vuedraggable": "^4.1.0" | ||||
}, | }, | ||||
"devDependencies": { | "devDependencies": { |
* @description: 获取巡检机场 | * @description: 获取巡检机场 | ||||
* @return {*} | * @return {*} | ||||
*/ | */ | ||||
export function airportList(params) { | |||||
export function airportList (params) { | |||||
return request({ | return request({ | ||||
url: '/inspection/airport', | url: '/inspection/airport', | ||||
method: 'GET', | method: 'GET', | ||||
* @description: 获取航线 | * @description: 获取航线 | ||||
* @return {*} | * @return {*} | ||||
*/ | */ | ||||
export function airportLine(id) { | |||||
export function airportLine (id) { | |||||
return request({ | return request({ | ||||
url: `/inspection/airport/line/${id}`, | url: `/inspection/airport/line/${id}`, | ||||
method: 'GET' | method: 'GET' | ||||
* @param {*} id 机场id | * @param {*} id 机场id | ||||
* @return {*} | * @return {*} | ||||
*/ | */ | ||||
export function airportWeather(id) { | |||||
export function airportWeather (id) { | |||||
return request({ | return request({ | ||||
url: `/inspection/airport/weather/${id}`, | url: `/inspection/airport/weather/${id}`, | ||||
method: 'GET' | method: 'GET' | ||||
* @param {*} id 机场id | * @param {*} id 机场id | ||||
* @return {*} | * @return {*} | ||||
*/ | */ | ||||
export function airportTrack(id) { | |||||
export function airportTrack (id) { | |||||
return request({ | return request({ | ||||
url: `/inspection/track/${id}`, | url: `/inspection/track/${id}`, | ||||
method: 'GET' | method: 'GET' | ||||
* @param {*} id 机场id | * @param {*} id 机场id | ||||
* @return {*} | * @return {*} | ||||
*/ | */ | ||||
export function missionLive(id) { | |||||
export function missionLive (id) { | |||||
return request({ | return request({ | ||||
url: `/mission/live/${id}`, | url: `/mission/live/${id}`, | ||||
method: 'GET' | method: 'GET' | ||||
}) | }) | ||||
} | } | ||||
/** | |||||
* @description:获取机场详细信息 | |||||
* @param id 机场id | |||||
*/ | |||||
export function getAirportInfo (data) { | |||||
return request({ | |||||
url: `/index/getAirportDetail`, | |||||
method: 'POST', | |||||
data | |||||
}) | |||||
} | |||||
/** | |||||
* @description:获取任务列表接口 | |||||
* @param page 页数 | |||||
* @param limit 每页显示数 | |||||
*/ | |||||
export function getMissionList (data) { | |||||
return request({ | |||||
url: `/index/getMissionList`, | |||||
method: 'POST', | |||||
data | |||||
}) | |||||
} | |||||
/** | |||||
* @description:获取问题多选类型 | |||||
* | |||||
*/ | |||||
export function getQuestionType () { | |||||
return request({ | |||||
url: `/question/type`, | |||||
method: 'GET' | |||||
}) | |||||
} | |||||
/** | |||||
* @description:获取问题列表数据 | |||||
*/ | |||||
export function getQuestionList (data) { | |||||
return request({ | |||||
url: `/index/getQuestionList`, | |||||
method: 'POST', | |||||
data | |||||
}) | |||||
} |
method: 'GET' | method: 'GET' | ||||
}) | }) | ||||
} | } | ||||
/** | |||||
* 新的接口 | |||||
* 获取问题列表(限制200条) | |||||
* @param {startTime} 开始时间 | |||||
* @param {endTime} 结束时间 | |||||
*/ | |||||
export function getQuestions(params) { | |||||
return request({ | |||||
url: '/index/getQuestionList', | |||||
method: 'POST', | |||||
params | |||||
}) | |||||
} |
const res = await airportList({ page: 1, limit: 60 }) | const res = await airportList({ page: 1, limit: 60 }) | ||||
if (res.code === 0) { | if (res.code === 0) { | ||||
data.airOptionsAll = res.data | data.airOptionsAll = res.data | ||||
// console.log(data.airOptionsAll) | |||||
data.airOptions = dataToSelect(res.data, { label: 'name', value: 'id' }) | data.airOptions = dataToSelect(res.data, { label: 'name', value: 'id' }) | ||||
data.videoForm.airportId = res.data[0].id | data.videoForm.airportId = res.data[0].id | ||||
getAirportInfo(res.data[0].id) | getAirportInfo(res.data[0].id) |
<template> | |||||
<div class="content"> | |||||
<table> | |||||
<tr> | |||||
<th class="title">机场名称:</th> | |||||
<th>机场A</th> | |||||
</tr> | |||||
<tr> | |||||
<th class="title">机场状态:</th> | |||||
<th>正常</th> | |||||
</tr> | |||||
<tr> | |||||
<th class="title">可选挂载:</th> | |||||
<th>高清相机、多光谱相机、喊话器</th> | |||||
</tr> | |||||
</table> | |||||
<div class="deviceInfo"> | |||||
<div | |||||
v-for="(item,index) in indicatorList" | |||||
:key="index" | |||||
class="item" | |||||
> | |||||
<img :src="item.icon"> | |||||
<div class="value">{{ item.indicatorValue }}</div> | |||||
<div class="name">{{ item.indicatorName }}</div> | |||||
</div> | |||||
</div> | |||||
<div class="monitorList"> | |||||
<div class="innerMonitor"> | |||||
<div class="monitorName">机场内部监控</div> | |||||
<img src="../../../assets/images/webScreen.png" @click="videoShowStyle"> | |||||
<videoPlay | |||||
v-bind="innerMonitorOptions" | |||||
style="z-index:1" | |||||
/> | |||||
</div> | |||||
<div class="innerMonitor"> | |||||
<div class="monitorName">机场外部监控</div> | |||||
<img src="../../../assets/images/webScreen.png" @click="outerVideoShowStyle"> | |||||
<videoPlay | |||||
v-bind="outsideMonitorOptions" | |||||
style="z-index:1" | |||||
/> | |||||
</div> | |||||
</div> | |||||
</div> | |||||
</template> | |||||
<script> | |||||
import { reactive, toRefs, watch } from 'vue' | |||||
import { getAirportInfo } from '@/api/dashboard/index.js' | |||||
import 'vue3-video-play/dist/style.css' | |||||
import { videoPlay } from 'vue3-video-play' | |||||
export default { | |||||
name: 'OneMap', | |||||
components: { videoPlay }, | |||||
props: { | |||||
data: { | |||||
type: Object, | |||||
default: () => { } | |||||
} | |||||
}, | |||||
setup(props) { | |||||
const data = reactive({ | |||||
detail: props.data, | |||||
indicatorList: [ | |||||
{ icon: new URL('../../../assets/images/wind.png', import.meta.url).href, indicatorValue: '3m/s', indicatorName: '风速' }, | |||||
{ icon: new URL('../../../assets/images/north.png', import.meta.url).href, indicatorValue: '正北', indicatorName: '风向' }, | |||||
{ icon: new URL('../../../assets/images/atmosPressure.png', import.meta.url).href, indicatorValue: '0.1Mpa', indicatorName: '大气压力' }, | |||||
{ icon: new URL('../../../assets/images/airHumidity.png', import.meta.url).href, indicatorValue: '25rh', indicatorName: '空气湿度' }, | |||||
{ icon: new URL('../../../assets/images/rainfall.png', import.meta.url).href, indicatorValue: '5ml', indicatorName: '降雨量' }, | |||||
{ icon: new URL('../../../assets/images/airTemperature.png', import.meta.url).href, indicatorValue: '25°C', indicatorName: '空气温度' }], | |||||
innerMonitorOptions: { | |||||
width: '256px', | |||||
height: '198px', | |||||
controls: false, | |||||
src: '', | |||||
webFullScreen: false | |||||
}, | |||||
outsideMonitorOptions: { | |||||
width: '256px', | |||||
height: '198px', | |||||
controls: false, | |||||
src: '', | |||||
webFullScreen: false | |||||
} | |||||
}) | |||||
watch(() => props.data, (value) => { | |||||
if (value) { | |||||
// console.log(props.data) | |||||
data.detail = props.data | |||||
data.innerMonitorOptions.src = data.detail.internalMonitorUrl | |||||
data.outsideMonitorOptions.src = data.detail.externalMonitorUrl | |||||
getAirportInfo({ | |||||
airportId: data.detail.id | |||||
}) | |||||
.then(res => { | |||||
if (res.code === 0) { | |||||
// console.log('机场详情') | |||||
data.indicatorList.map((item, index) => { | |||||
switch (index) { | |||||
case 0: | |||||
item.indicatorValue = res.data.wspd | |||||
break | |||||
case 1: | |||||
item.indicatorValue = res.data.wdir | |||||
break | |||||
case 2: | |||||
item.indicatorValue = res.data.hpa | |||||
break | |||||
case 3: | |||||
item.indicatorValue = res.data.hum | |||||
break | |||||
case 5: | |||||
item.indicatorValue = res.data.tmp | |||||
} | |||||
}) | |||||
} | |||||
}) | |||||
} | |||||
}) | |||||
const videoShowStyle = () => { | |||||
data.innerMonitorOptions.webFullScreen = !data.innerMonitorOptions.webFullScreen | |||||
} | |||||
const outerVideoShowStyle = () => { | |||||
data.outsideMonitorOptions.webFullScreen = !data.outsideMonitorOptions.webFullScreen | |||||
} | |||||
return { | |||||
...toRefs(data), | |||||
videoShowStyle, | |||||
outerVideoShowStyle | |||||
} | |||||
} | |||||
} | |||||
</script> | |||||
<style lang="scss" scoped> | |||||
.map-container { | |||||
width: 100vw; | |||||
height: 100vh; | |||||
} | |||||
.layer-management { | |||||
height: calc(100vh - 84%); | |||||
position: absolute; | |||||
width: 100px; | |||||
/* margin-right: 10px; */ | |||||
left: 100px; | |||||
top: 100px; | |||||
background-color: rgba(0, 0, 0, 0.6); | |||||
} | |||||
.content { | |||||
box-sizing: border-box; | |||||
padding: 25px 5px; | |||||
} | |||||
table { | |||||
width: 100%; | |||||
height: 90px; | |||||
font-size: 15px; | |||||
font-family: Noto Sans SC-Regular, Noto Sans SC; | |||||
font-weight: 400; | |||||
border-collapse: collapse; | |||||
background: #2c2c2c; | |||||
.title { | |||||
color: #8b8b8b; | |||||
} | |||||
} | |||||
table, | |||||
td, | |||||
th { | |||||
border: 1px solid #707070; | |||||
color: white; | |||||
font-weight: 400; | |||||
} | |||||
.deviceInfo { | |||||
margin-top: 5px; | |||||
width: 100%; | |||||
height: 83px; | |||||
background: #2c2c2c; | |||||
display: flex; | |||||
justify-content: space-between; | |||||
.item { | |||||
color: white; | |||||
display: flex; | |||||
justify-content: center; | |||||
flex-direction: column; | |||||
align-items: center; | |||||
.value { | |||||
font-size: 14px; | |||||
font-family: Noto Sans SC-Regular, Noto Sans SC; | |||||
font-weight: 400; | |||||
color: #ffffff; | |||||
} | |||||
.name { | |||||
font-size: 15px; | |||||
font-family: Noto Sans SC-Regular, Noto Sans SC; | |||||
font-weight: 400; | |||||
color: #8b8b8b; | |||||
} | |||||
} | |||||
} | |||||
.monitorList { | |||||
margin-top: 10px; | |||||
display: flex; | |||||
justify-content: space-around; | |||||
.innerMonitor { | |||||
position: relative; | |||||
width: 256px; | |||||
height: 198px; | |||||
.monitorName { | |||||
position: absolute; | |||||
bottom: 8px; | |||||
left: 10px; | |||||
font-size: 14px; | |||||
font-family: Noto Sans SC-Regular, Noto Sans SC; | |||||
font-weight: 400; | |||||
color: #ffffff; | |||||
z-index: 100; | |||||
} | |||||
img { | |||||
position: absolute; | |||||
right: 10px; | |||||
bottom: 8px; | |||||
z-index: 100; | |||||
} | |||||
} | |||||
} | |||||
</style> | |||||
<template> | |||||
<div class="container"> | |||||
<div | |||||
class="map-container" | |||||
:="getMapOptions" | |||||
/> | |||||
<!-- <div class="layer-management"> | |||||
<div class="list-manage"> | |||||
<p>列表</p> | |||||
<n-switch v-model:value="listShow" /> | |||||
</div> | |||||
<div class="air-manage"> | |||||
<p>机场</p> | |||||
<n-switch v-model:value="airShow" | |||||
@update:value="airShowHide" /> | |||||
</div> | |||||
</div> --> | |||||
<div | |||||
id="airOverlay" | |||||
class="airport-overlay" | |||||
> | |||||
<span | |||||
id="closeAir" | |||||
class="close-overlay" | |||||
@click="hideAirInfo" | |||||
>x</span> | |||||
<air-info :data="airDetail" /> | |||||
</div> | |||||
<div | |||||
id="problemOverlay" | |||||
class="problem-overlay" | |||||
> | |||||
<span | |||||
class="close-overlay" | |||||
@click="hideProblemInfo" | |||||
>x</span> | |||||
<problem-info :detail="problemDetail" /> | |||||
</div> | |||||
<div | |||||
v-show="false" | |||||
class="task-question" | |||||
> | |||||
<n-card style="margin-bottom: 16px"> | |||||
<n-tabs | |||||
type="line" | |||||
animated | |||||
> | |||||
<!-- <n-tab-pane name="task" tab="任务"> | |||||
任务 | |||||
</n-tab-pane> --> | |||||
<n-tab-pane | |||||
name="question" | |||||
tab="问题" | |||||
> | |||||
<n-date-picker | |||||
:on-update:formatted-value="abc" | |||||
:default-formatted-value="efg" | |||||
type="daterange" | |||||
:default-value="[Date.now() - 6.048e8, Date.now()]" | |||||
:is-date-disabled="disablePreviousDate" | |||||
/> | |||||
<!-- <n-checkbox-group :value="cities" @update:value="handleUpdateValue"> | |||||
<n-space style="display: block;"> | |||||
<n-checkbox value="Beijing" label="北京" /> | |||||
<n-checkbox value="Shanghai" label="上海" /> | |||||
<n-checkbox value="Guangzhou" label="广州" /> | |||||
<n-checkbox value="Shenzen" label="深圳" /> | |||||
</n-space> | |||||
</n-checkbox-group> --> | |||||
</n-tab-pane> | |||||
</n-tabs> | |||||
</n-card> | |||||
</div> | |||||
<div | |||||
v-show="listChecked" | |||||
class="menu" | |||||
> | |||||
<div class="tabBar"> | |||||
<span | |||||
:class="[tabIndex==1?'checkedColor':'uncheckedColor']" | |||||
style="margin-right:97px" | |||||
@click="showTask" | |||||
>任务</span> | |||||
<span | |||||
:class="[tabIndex==1?'uncheckedColor':'checkedColor']" | |||||
@click="showProblem" | |||||
>问题</span> | |||||
</div> | |||||
<div | |||||
v-if="tabIndex==1" | |||||
class="listDetail" | |||||
> | |||||
<ul> | |||||
<li | |||||
v-for="(item,index) in taskList" | |||||
:key="index" | |||||
style="display:flex;font-size:14px" | |||||
> | |||||
<div style="width:145px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis">{{ item.taskName }}</div> | |||||
<div style="42px">{{ item.statusInfo }}</div> | |||||
<!-- <div v-if="item.status==1" | |||||
@click="performTask(item)">立即执行</div> --> | |||||
<!-- <n-button v-if="item.status==1" | |||||
@click="handleConfirm">立即执行</n-button> --> | |||||
<n-popconfirm | |||||
v-if="item.status==1" | |||||
@positive-click="handlePositiveClick(item)" | |||||
@negative-click="handleNegativeClick" | |||||
> | |||||
<template #trigger> | |||||
<span style="color:#22D33D">立即执行</span> | |||||
</template> | |||||
是否立即开始执行任务? | |||||
</n-popconfirm> | |||||
<div | |||||
v-else | |||||
style="color:#1890FF" | |||||
@click="liveShow(item)" | |||||
>直播</div> | |||||
</li> | |||||
</ul> | |||||
<n-pagination | |||||
v-model:page="page" | |||||
:page-count="pageCount" | |||||
:page-slot="7" | |||||
style="color:#FFFFFF;position:absolute;bottom:10px;left:10px" | |||||
/> | |||||
</div> | |||||
<div | |||||
v-else | |||||
class="listDetail" | |||||
> | |||||
<n-date-picker | |||||
:on-update:formatted-value="abc" | |||||
:default-formatted-value="efg" | |||||
type="daterange" | |||||
:default-value="[Date.now() - 6.048e8, Date.now()]" | |||||
:is-date-disabled="disablePreviousDate" | |||||
style="margin-bottom:15px" | |||||
/> | |||||
<!-- 多选框 --> | |||||
<n-checkbox-group | |||||
v-model:value="problemTypeSelected" | |||||
@update:value="handleProblemTypeValue" | |||||
> | |||||
<div | |||||
v-for="(item,index) in problemTypeList" | |||||
:key="index" | |||||
> | |||||
<n-checkbox | |||||
:value="item.content" | |||||
:label="item.content" | |||||
style="color:#FFFFFF" | |||||
/> | |||||
</div> | |||||
</n-checkbox-group> | |||||
</div> | |||||
</div> | |||||
<div class="menuControl"> | |||||
<div | |||||
style="border-bottom:1px solid rgba(1122,112,112,0.65)" | |||||
class="item" | |||||
> | |||||
<div @click="showList"> | |||||
<img | |||||
v-if="listChecked==true" | |||||
src="../../../assets/images/listChecked.png" | |||||
> | |||||
<img | |||||
v-else | |||||
src="../../../assets/images/listUnchecked.png" | |||||
> | |||||
</div> | |||||
<span :style="{'color':listChecked?'#1890FF':'#666666'}">列表</span> | |||||
</div> | |||||
<div class="item"> | |||||
<div @click="showAirportList"> | |||||
<img | |||||
v-if="airportSelected==true" | |||||
src="../../../assets/images/airportChecked.png" | |||||
> | |||||
<img | |||||
v-else | |||||
src="../../../assets/images/airportUnchecked.png" | |||||
> | |||||
</div> | |||||
<span :style="{'color':airportSelected?'#1890FF':'#666666'}">机场</span> | |||||
</div> | |||||
</div> | |||||
</div> | |||||
</template> | |||||
<script> | |||||
import { Map, View, Feature, Overlay } from 'ol' | |||||
import { useRouter } from 'vue-router' | |||||
import { XYZ, Vector as VectorSource } from 'ol/source' | |||||
import TileLayer from 'ol/layer/Tile.js' | |||||
import WMTS from 'ol/source/WMTS.js' | |||||
import TileWMS from 'ol/source/TileWMS.js' | |||||
import WMTSTileGrid from 'ol/tilegrid/WMTS.js' | |||||
import { Tile, Vector as VectorLayer } from 'ol/layer' | |||||
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 { reactive, toRefs, onMounted, computed, ref, watch } from 'vue' | |||||
import { Point } from 'ol/geom' | |||||
import { airportList, getMissionList, getQuestionType, getQuestionList } from '@/api/dashboard/index.js' | |||||
import { getQuestions } from '@/api/task/index.js' | |||||
import { gcj02towgs84 } from '@/utils/coordinate-util.js' | |||||
import AirInfo from './AirInfo.vue' | |||||
import ProblemInfo from './ProblemInfo.vue' | |||||
import { startOfDay } from 'date-fns/esm' | |||||
import { useMessage, useDialog } from 'naive-ui' | |||||
import { implement } from '@/api/task/index.js' | |||||
import { get as getProjection } from 'ol/proj.js' | |||||
import { getTopLeft, getWidth } from 'ol/extent.js' | |||||
const projection = getProjection('EPSG:4326') | |||||
const projectionExtent = projection.getExtent() | |||||
const size = getWidth(projectionExtent) / 256 | |||||
const resolutions = new Array(19) | |||||
const matrixIds = new Array(19) | |||||
for (let z = 0; z < 19; ++z) { | |||||
// generate resolutions and matrixIds arrays for this WMTS | |||||
resolutions[z] = size / Math.pow(2, z) | |||||
matrixIds[z] = z | |||||
} | |||||
var message = useMessage() | |||||
export default { | |||||
name: 'OneMap', | |||||
components: { AirInfo, ProblemInfo }, | |||||
props: { | |||||
id: { | |||||
type: String, | |||||
default: 'map' | |||||
} | |||||
}, | |||||
setup(props) { | |||||
const router = useRouter() | |||||
const dialog = useDialog() | |||||
const data = reactive({ | |||||
map: null, | |||||
// 机场数组 | |||||
airportsAll: [], | |||||
// 机场显隐 | |||||
airShow: true, | |||||
// 机场要素集 | |||||
airFeatures: [], | |||||
// 机场图层 | |||||
airLayer: null, | |||||
// 机场信息容器 | |||||
airOverlay: null, | |||||
// 问题信息容器 | |||||
problemOverlay: null, | |||||
// 机场细节信息 | |||||
airDetail: {}, | |||||
// 问题细节信息 | |||||
problemDetail: {}, | |||||
listShow: false, | |||||
// 时间范围是一周前至今天 | |||||
efg: '', | |||||
listIcon: new URL('../../../assets/images/listChecked.png', import.meta.url).href, | |||||
airportIcon: new URL('../../../assets/images/airportChecked.png', import.meta.url).href, | |||||
listFontStyle: { | |||||
'color': '#666666' | |||||
}, | |||||
airportFontStyle: { | |||||
'color': '#1890FF' | |||||
}, | |||||
problemPopupShow: false, | |||||
tabIndex: 1, | |||||
page: ref(1), | |||||
pageCount: 1, | |||||
taskList: [], | |||||
range: (['2012-09-10', '2022-09-10']), | |||||
problemTypeSelected: null, | |||||
problemTypeList: [], | |||||
listChecked: false, | |||||
airportSelected: true, | |||||
problemLayerList: [], | |||||
airportPopupShow: false | |||||
}) | |||||
watch(() => data.page, (newValue, oldValue) => { | |||||
if (newValue !== oldValue) { | |||||
initTaskList() | |||||
} | |||||
}) | |||||
const getMapOptions = computed(() => { | |||||
return { | |||||
id: props.id | |||||
} | |||||
}) | |||||
const initMap = () => { | |||||
// 天地图影像图 | |||||
const tdtImgMap = | |||||
new Tile({ | |||||
visible: true, | |||||
source: new XYZ({ | |||||
url: 'https://t0.tianditu.gov.cn/DataServer?T=img_w&x={x}&y={y}&l={z}&tk=f634525a82da65f715d168d7ba1899c0' | |||||
}) | |||||
}) | |||||
var wmsSource = new Tile({ | |||||
source: new TileWMS({ | |||||
url: 'https://geoserver.t-aaron.com:4080/geoserver/jiangning/wms', | |||||
params: { 'LAYERS': 'jiangning:town' } | |||||
}) | |||||
}) | |||||
data.map = new Map({ | |||||
// 地图容器 | |||||
target: props.id, | |||||
view: new View({ | |||||
center: transform([118.773136, 31.828065], 'EPSG:4326', 'EPSG:3857'), | |||||
zoom: 11, | |||||
maxZoom: 17 | |||||
}), | |||||
layers: [ | |||||
tdtImgMap | |||||
], | |||||
controls: control.defaults({ | |||||
attribution: false, | |||||
rotate: false, | |||||
zoom: false | |||||
}) | |||||
}) | |||||
data.map.addLayer(wmsSource) | |||||
wmsSource.setOpacity(0.3) | |||||
} | |||||
/** | |||||
* @description: 获取机场数据 | |||||
* @param {*} res | |||||
* @return {*} | |||||
*/ | |||||
const loadAirport = (async function() { | |||||
const res = await airportList({ page: 1, limit: 100 }) | |||||
if (res.code === 0) { | |||||
data.airportsAll = res.data | |||||
showAirport() | |||||
} | |||||
})() | |||||
/** | |||||
* @description:分页器改变时改变任务列表信息 | |||||
*/ | |||||
const changePage = (v) => { | |||||
} | |||||
/** | |||||
* 展示机场 | |||||
*/ | |||||
const showAirport = () => { | |||||
if (data.airportsAll.length > 0) { | |||||
for (let i = 0; i < data.airportsAll.length; i++) { | |||||
const airport = data.airportsAll[i] | |||||
const lngLat = gcj02towgs84(parseFloat(airport.longitude), parseFloat(airport.latitude)) | |||||
const feature = new Feature({ | |||||
geometry: new Point(fromLonLat(lngLat)) | |||||
}) | |||||
// 要素设置样式 | |||||
feature.setStyle( | |||||
new Style({ | |||||
image: new Icon({ | |||||
src: uav_icon | |||||
}), | |||||
text: new Text({ | |||||
// 文字内容 | |||||
text: airport.name, | |||||
// 位置 | |||||
textAlign: 'center', | |||||
// 基准线 | |||||
textBaseline: 'top', | |||||
offsetY: 30, | |||||
// 文字样式 | |||||
font: 'normal 20px Microsoft YaHei', | |||||
backgroundFill: new Fill({ | |||||
color: '#1890FF' | |||||
}), | |||||
padding: [3, 6, 3, 6], | |||||
// 文字颜色 | |||||
fill: new Fill({ | |||||
color: '#fff' | |||||
}) | |||||
}) | |||||
}) | |||||
) | |||||
// 要素设置id | |||||
feature.setId(airport.id) | |||||
// 要素设置属性 | |||||
feature.setProperties({ | |||||
id: airport.id, | |||||
code: airport.code, | |||||
name: airport.name, | |||||
// 设置类别 | |||||
type: 'airport', | |||||
coordinate: fromLonLat(lngLat), | |||||
// 机场外部监控地址 | |||||
externalMonitorUrl: airport.externalMonitorUrl, | |||||
// 机场内部监控地址 | |||||
internalMonitorUrl: airport.internalMonitorUrl | |||||
}) | |||||
data.airFeatures.push(feature) | |||||
} | |||||
} | |||||
data.airLayer = new VectorLayer({ | |||||
source: new VectorSource({ | |||||
features: data.airFeatures | |||||
}), | |||||
visible: data.airShow | |||||
}) | |||||
data.map.addLayer(data.airLayer) | |||||
// 机场信息覆盖物 | |||||
data.airOverlay = new Overlay({ | |||||
id: 'air_overlay', | |||||
element: document.getElementById('airOverlay'), | |||||
autoPan: true, | |||||
offset: [10, 10] | |||||
}) | |||||
data.airportPopupShow = true | |||||
// 点击事件 | |||||
data.map.on('click', (evt) => { | |||||
showAirInfo(evt) | |||||
}) | |||||
// console.log(new Date().getFullYear()) | |||||
} | |||||
/** | |||||
* 展示机场信息 | |||||
* @param {} e | |||||
*/ | |||||
const showAirInfo = (e) => { | |||||
// 防止冒泡 | |||||
e.stopPropagation() | |||||
// 点击位置的经纬度 | |||||
var feature = data.map.forEachFeatureAtPixel(e.pixel, (feature) => { | |||||
return feature | |||||
}) | |||||
if (feature) { | |||||
// 要素类别为机场 | |||||
if (feature.getProperties().type === 'airport') { | |||||
data.airDetail = feature.getProperties() | |||||
// 为了overlay位置更加精确 | |||||
const coord = feature.getProperties().coordinate | |||||
data.airOverlay.setPosition(coord) | |||||
data.map.addOverlay(data.airOverlay) | |||||
} | |||||
if (feature.getProperties().typeName) { | |||||
data.problemDetail = feature.getProperties() | |||||
// console.log(data.problemDetail, '详情') | |||||
const coord = feature.getProperties().coordinate | |||||
data.problemPopupShow = true | |||||
data.problemOverlay.setPosition(coord) | |||||
data.map.addOverlay(data.problemOverlay) | |||||
// data.problemOverlay.setPosition(coord) | |||||
// data.map.addOverlay(data.problemOverlay) | |||||
} | |||||
} | |||||
} | |||||
/** | |||||
* 关闭展示机场信息 | |||||
*/ | |||||
const hideAirInfo = () => { | |||||
if (data.map.getOverlayById('air_overlay')) { | |||||
data.airDetail = {} | |||||
data.map.removeOverlay(data.airOverlay) | |||||
data.airportPopupShow = false | |||||
} | |||||
} | |||||
/** | |||||
* 关闭显示问题图层信息 | |||||
*/ | |||||
const hideProblemInfo = () => { | |||||
if (data.map.getOverlayById('problem_overlay')) { | |||||
data.problemDetail = {} | |||||
data.map.removeOverlay(data.problemOverlay) | |||||
} | |||||
} | |||||
/** | |||||
* 显示问题信息 | |||||
*/ | |||||
const showProblem = () => { | |||||
data.tabIndex = 0 | |||||
} | |||||
/** | |||||
* 显示任务列表信息 | |||||
*/ | |||||
const showTask = () => { | |||||
data.tabIndex = 1 | |||||
} | |||||
/** | |||||
* 机场图层控制显隐 | |||||
* @param { } value | |||||
*/ | |||||
const airShowHide = (isShow) => { | |||||
data.airLayer.setVisible(isShow) | |||||
if (!isShow) { | |||||
hideAirInfo() | |||||
} | |||||
} | |||||
/** | |||||
* @description:执行任务 | |||||
*/ | |||||
const performTask = (item) => { | |||||
// console.log(router, '路径') | |||||
router.push({ path: '/taskManage/all', query: { rowInfo: JSON.stringify(item) }}) | |||||
} | |||||
const abc = (value) => { | |||||
getQuestionList({ | |||||
startTime: value[0], | |||||
endTime: value[1] | |||||
}).then(res => { | |||||
if (res.code === 0) { | |||||
const arr = res.data | |||||
var resArr = [] | |||||
var narr = [] | |||||
for (var i = 0; i < arr.length; i++) { | |||||
var n = resArr.indexOf(arr[i].typeName) | |||||
if (n == -1) { | |||||
resArr.push(arr[i].typeName) | |||||
narr.push({ 'name': arr[i].typeName, fraction: [arr[i]] }) | |||||
} else { | |||||
narr[n].fraction.push(arr[i]) | |||||
} | |||||
} | |||||
// 添加问题图层 | |||||
addproblemLayer(narr) | |||||
} | |||||
}) | |||||
} | |||||
// 添加问题图层 | |||||
const addproblemLayer = (narr) => { | |||||
data.problemOverlay = new Overlay({ | |||||
id: 'problem_overlay', | |||||
element: document.getElementById('problemOverlay'), | |||||
autoPan: true, | |||||
offset: [10, 10] | |||||
}) | |||||
narr.map((item) => { | |||||
const Features = [] | |||||
if (item.fraction.length > 0) { | |||||
item.fraction.map((iitem) => { | |||||
const problem = iitem | |||||
const lngLat = gcj02towgs84(parseFloat(problem.lng), parseFloat(problem.lat)) | |||||
const feature = new Feature({ | |||||
geometry: new Point(fromLonLat(lngLat)) | |||||
}) | |||||
let icon | |||||
switch (iitem.typeName) { | |||||
case '林场问题图斑': | |||||
icon = problemSpot_icon | |||||
break | |||||
case '病死树': | |||||
icon = deadTree_icon | |||||
break | |||||
case '人员活动': | |||||
icon = personnel_icon | |||||
break | |||||
case '火灾隐患': | |||||
icon = fireHazard_icon | |||||
} | |||||
// 要素设置样式 | |||||
feature.setStyle( | |||||
new Style({ | |||||
image: new Icon({ | |||||
src: icon | |||||
}) | |||||
}) | |||||
) | |||||
// 要素设置id | |||||
feature.setId(problem.questionId) | |||||
// 要素设置属性 | |||||
problem.coordinate = fromLonLat(lngLat) | |||||
feature.setProperties(problem) | |||||
Features.push(feature) | |||||
}) | |||||
// 添加图层 | |||||
const layer = new VectorLayer({ | |||||
source: new VectorSource({ | |||||
features: Features | |||||
}), | |||||
visible: true | |||||
}) | |||||
const obj = { type: item.name, layer: layer } | |||||
data.problemLayerList.push(obj) | |||||
data.map.addLayer(layer) | |||||
} | |||||
}) | |||||
} | |||||
/** | |||||
* 初始化任务列表信息 | |||||
* | |||||
*/ | |||||
const initTaskList = () => { | |||||
getMissionList({ | |||||
page: data.page, | |||||
limit: 12 | |||||
}).then(res => { | |||||
if (res.code === 0) { | |||||
data.taskList = res.data.records | |||||
data.pageCount = res.data.pages | |||||
data.taskList.map((item) => { | |||||
const arr = item.executionStartTime.split(/[ ]+/)// 以空格分开 | |||||
item.taskName = arr[0] + item.name | |||||
switch (item.status) { | |||||
case 1: | |||||
item.statusInfo = '待执行' | |||||
break | |||||
case 2: | |||||
item.statusInfo = '执行中' | |||||
break | |||||
} | |||||
}) | |||||
} | |||||
}) | |||||
} | |||||
/** | |||||
* 获取问题多选类型 | |||||
*/ | |||||
const initProblemType = () => { | |||||
getQuestionType().then(res => { | |||||
if (res.code === 0) { | |||||
data.problemTypeList = res.data | |||||
data.problemTypeSelected = [] | |||||
data.problemTypeList.map((item) => { | |||||
data.problemTypeSelected.push(item.content) | |||||
}) | |||||
} | |||||
}) | |||||
} | |||||
/** | |||||
* @description:是否展示列表 | |||||
*/ | |||||
const showList = () => { | |||||
data.listChecked = !data.listChecked | |||||
} | |||||
/** | |||||
* | |||||
*/ | |||||
const handleProblemTypeValue = (value) => { | |||||
// console.log(value, '选中的值') | |||||
data.problemLayerList.map((item) => { | |||||
const a = value.indexOf(item.type) | |||||
if (a == -1) { | |||||
item.layer.setVisible(false) | |||||
} else { | |||||
item.layer.setVisible(true) | |||||
} | |||||
}) | |||||
} | |||||
/** | |||||
* @description:是否显示机场 | |||||
*/ | |||||
const showAirportList = () => { | |||||
data.airportSelected = !data.airportSelected | |||||
data.airLayer.setVisible(data.airportSelected) | |||||
if (!data.airportSelected) { | |||||
hideAirInfo() | |||||
} | |||||
} | |||||
/** | |||||
* 展示直播视频 | |||||
*/ | |||||
const liveShow = (rowInfo) => { | |||||
router.push({ path: '/taskManage/all', query: { rowInfo: JSON.stringify(rowInfo) }}) | |||||
} | |||||
onMounted(() => { | |||||
initMap() | |||||
initTaskList() | |||||
initProblemType() | |||||
}) | |||||
return { | |||||
...toRefs(data), | |||||
getMapOptions, | |||||
loadAirport, | |||||
showProblem, | |||||
showTask, | |||||
airShowHide, | |||||
hideAirInfo, | |||||
changePage, | |||||
showList, | |||||
disablePreviousDate(ts, type, range) { | |||||
const d = 864e5 | |||||
// return ts > Date.now() | |||||
if (type === 'start' && range !== null) { | |||||
return startOfDay(range[1]).valueOf() - startOfDay(ts).valueOf() >= d * 8 | |||||
} | |||||
if (type === 'end' && range !== null) { | |||||
return startOfDay(ts).valueOf() - startOfDay(range[0]).valueOf() >= d * 8 | |||||
} | |||||
return ts > Date.now() | |||||
}, | |||||
abc, | |||||
showAirportList, | |||||
handleProblemTypeValue, | |||||
hideProblemInfo, | |||||
performTask, | |||||
handleConfirm() { | |||||
dialog.warning({ | |||||
title: '警告', | |||||
content: '你确定?', | |||||
positiveText: '确定', | |||||
negativeText: '不确定', | |||||
onPositiveClick: () => { | |||||
message.success('确定') | |||||
}, | |||||
onNegativeClick: () => { | |||||
message.error('不确定') | |||||
} | |||||
}) | |||||
}, | |||||
handlePositiveClick(row) { | |||||
$message.info('机场设备开始自检,请稍等') | |||||
implement(row.id) | |||||
.then(res => { | |||||
if (res.code === 0) { | |||||
$message.info('操作成功') | |||||
} | |||||
}) | |||||
}, | |||||
handleNegativeClick() { | |||||
}, | |||||
liveShow | |||||
} | |||||
} | |||||
} | |||||
</script> | |||||
<style lang="scss" scoped> | |||||
.container{ | |||||
width:100vw; | |||||
height:100vh; | |||||
position:relative; | |||||
overflow:hidden; | |||||
} | |||||
.map-container { | |||||
width: 100%; | |||||
height:100%; | |||||
} | |||||
.layer-management { | |||||
height: calc(100vh - 84%); | |||||
position: absolute; | |||||
width: 100px; | |||||
/* margin-right: 10px; */ | |||||
left: 100px; | |||||
top: 100px; | |||||
background-color: rgba(0, 0, 0, 0.6); | |||||
} | |||||
.layer-management p { | |||||
color: #fff; | |||||
} | |||||
.airport-overlay { | |||||
width: 530px; | |||||
height: 430px; | |||||
background-color: rgba(0, 0, 0, 0.5); | |||||
} | |||||
.problem-overlay { | |||||
width: 530px; | |||||
background-color: rgba(0, 0, 0, 0.5); | |||||
} | |||||
.close-overlay { | |||||
width: 28px; | |||||
height: 28px; | |||||
position: relative; | |||||
color: #fff; | |||||
font-size: 20px; | |||||
cursor: pointer; | |||||
float: right; | |||||
text-align: center; | |||||
line-height: 28px; | |||||
} | |||||
/* 任务-问题面板 */ | |||||
.task-question { | |||||
width: 500px; | |||||
height: 800px; | |||||
position: absolute; | |||||
top: 100px; | |||||
right: 140px; | |||||
} | |||||
.menu { | |||||
position: absolute; | |||||
top: 64px; | |||||
right: 90px; | |||||
width: 355px; | |||||
height: 428px; | |||||
background: #000000; | |||||
box-sizing: border-box; | |||||
padding: 5px; | |||||
.tabBar { | |||||
height: 35px; | |||||
width: 100%; | |||||
font-size: 15px; | |||||
font-family: Noto Sans SC-Regular, Noto Sans SC; | |||||
font-weight: 400; | |||||
display: flex; | |||||
justify-content: center; | |||||
.checkedColor { | |||||
color: #1890ff; | |||||
} | |||||
.uncheckedColor { | |||||
color: #ffffff; | |||||
} | |||||
} | |||||
.listDetail { | |||||
width: 345px; | |||||
height: 383px; | |||||
background: #2c2c2c; | |||||
font-size: 14px; | |||||
font-family: Noto Sans SC-Regular, Noto Sans SC; | |||||
font-weight: 400; | |||||
color: #ffffff; | |||||
position: relative; | |||||
box-sizing: border-box; | |||||
padding: 10px 19px; | |||||
ul { | |||||
li { | |||||
display: flex; | |||||
justify-content: space-between; | |||||
padding: 8px 2px; | |||||
margin-bottom: 15px; | |||||
} | |||||
} | |||||
} | |||||
} | |||||
// 列表机场控制显隐菜单 | |||||
.menuControl { | |||||
position: absolute; | |||||
top: 200px; | |||||
right: 40px; | |||||
background: #ffffff; | |||||
box-shadow: 2px 2px 2px 1px rgba(31, 31, 31, 0.38); | |||||
border-radius: 2px; | |||||
width: 40px; | |||||
.item { | |||||
width: 100%; | |||||
height: 60px; | |||||
font-size: 14px; | |||||
font-family: Noto Sans SC-Regular, Noto Sans SC; | |||||
font-weight: 400; | |||||
display: flex; | |||||
flex-direction: column; | |||||
justify-content: center; | |||||
align-items: center; | |||||
} | |||||
} | |||||
:deep(.n-pagination-item) { | |||||
color: #ffffff !important; | |||||
} | |||||
:deep(.n-checkbox__label) { | |||||
color: #ffffff !important; | |||||
} | |||||
:deep(.n-pagination | |||||
.n-pagination-item.n-pagination-item--disabled.n-pagination-item--button) { | |||||
background-color: rgba(0, 0, 0, 0) !important; | |||||
} | |||||
</style> |
<template> | |||||
<div class="content"> | |||||
<table> | |||||
<tr> | |||||
<th class="title">问题类型:</th> | |||||
<td>{{ detail.typeName }}</td> | |||||
</tr> | |||||
<tr> | |||||
<th class="title">任务名称:</th> | |||||
<td>{{ detail.missionName }}</td> | |||||
</tr> | |||||
<tr> | |||||
<th class="title">巡检时间:</th> | |||||
<td>{{ detail.inspectionTime }}</td> | |||||
</tr> | |||||
<tr> | |||||
<th class="title">问题图片:</th> | |||||
<td> | |||||
<img | |||||
v-for="(item,index) in fileImageList" | |||||
:key="index" | |||||
:src="item.src" | |||||
> | |||||
</td> | |||||
</tr> | |||||
<tr v-show="detail.handlerResult"> | |||||
<th class="title">处理后描述:</th> | |||||
<td>{{ detail.handlerResult }}</td> | |||||
</tr> | |||||
<tr v-show="detail.handlerImage"> | |||||
<th class="title">处理后图片:</th> | |||||
<td> | |||||
<img | |||||
v-for="(item,index) in handlerImageList" | |||||
:key="index" | |||||
:src="item.src" | |||||
> | |||||
</td> | |||||
</tr> | |||||
<tr> | |||||
<th class="title">处理人:</th> | |||||
<td>{{ detail.handlerUserName }}</td> | |||||
</tr> | |||||
<tr v-show="detail.handlerTime"> | |||||
<th class="title">处理时间:</th> | |||||
<td>{{ detail.handlerTime }}</td> | |||||
</tr> | |||||
</table> | |||||
</div> | |||||
</template> | |||||
<script> | |||||
import { reactive, toRefs, watch, onMounted } from 'vue' | |||||
export default { | |||||
props: { | |||||
detail: { | |||||
type: Object, | |||||
default: () => { } | |||||
} | |||||
}, | |||||
setup(props) { | |||||
const data = reactive({ | |||||
detail: props.detail, | |||||
fileImageList: [], | |||||
handlerImageList: [] | |||||
}) | |||||
watch(() => props.detail, (value) => { | |||||
if (JSON.stringify(value) !== '{}') { | |||||
const fileImageList = value.fileMarkerUrl.split(',') | |||||
data.fileImageList = [] | |||||
fileImageList.map((item) => { | |||||
const obj = {} | |||||
obj.src = new URL(item, import.meta.url).href | |||||
data.fileImageList.push(obj) | |||||
}) | |||||
data.handlerImageList = [] | |||||
if (value.handlerImage) { | |||||
const handlerImageStr = value.handlerImage.split(',') | |||||
handlerImageStr.map((item) => { | |||||
const obj = {} | |||||
obj.src = new URL(item, import.meta.url).href | |||||
data.handlerImageList.push(obj) | |||||
}) | |||||
// console.log(data.handlerImageList, '444') | |||||
} | |||||
} | |||||
}) | |||||
return { | |||||
...toRefs(data) | |||||
} | |||||
} | |||||
} | |||||
</script> | |||||
<style lang='scss' scoped> | |||||
.content { | |||||
box-sizing: border-box; | |||||
padding: 25px 5px; | |||||
} | |||||
table { | |||||
width: 100%; | |||||
height: 90px; | |||||
font-size: 15px; | |||||
font-family: Noto Sans SC-Regular, Noto Sans SC; | |||||
font-weight: 400; | |||||
border-collapse: collapse; | |||||
background: #2c2c2c; | |||||
img { | |||||
width: 56px; | |||||
height: 56px; | |||||
margin: 5px 0; | |||||
} | |||||
.title { | |||||
color: #8b8b8b; | |||||
} | |||||
td { | |||||
box-sizing: border-box; | |||||
padding-left: 11px; | |||||
display: flex; | |||||
align-items: center; | |||||
} | |||||
// td { | |||||
// padding: 5px 11px; | |||||
// display: flex; | |||||
// } | |||||
} | |||||
table, | |||||
td, | |||||
th { | |||||
border: 1px solid #707070; | |||||
color: white; | |||||
font-weight: 400; | |||||
} | |||||
</style> |
<template> | |||||
<div class="dashboard__main"> | |||||
<div class="dashboard__top"> | |||||
<TaskCard /> | |||||
<VideoCard /> | |||||
</div> | |||||
<div class="dishboard__bottom"> | |||||
<AirCard /> | |||||
</div> | |||||
</div> | |||||
</template> | |||||
<script> | |||||
import { useRouter } from 'vue-router' | |||||
import TaskCard from './components/TaskCard.vue' | |||||
import VideoCard from './components/VideoCard.vue' | |||||
import AirCard from './components/AirCard.vue' | |||||
export default { | |||||
name: 'HomePage', | |||||
components: { TaskCard, VideoCard, AirCard }, | |||||
setup(props) { | |||||
const router = useRouter() | |||||
function toSystem() { | |||||
router.push({ path: '/login' }) | |||||
} | |||||
return { | |||||
toSystem | |||||
} | |||||
} | |||||
} | |||||
</script> | |||||
<style lang="scss" scoped> | |||||
.dashboard__main{ | |||||
height: calc(100vh - 80px); | |||||
.dashboard__top{ | |||||
display: flex; | |||||
height: 50%; | |||||
.n-card{ | |||||
overflow: hidden; | |||||
&:first-child{ | |||||
width: 50%; | |||||
margin-right: 20px; | |||||
} | |||||
} | |||||
} | |||||
.dishboard__bottom{ | |||||
display: flex; | |||||
height: calc(50% - 20px); | |||||
margin-top: 20px; | |||||
} | |||||
.n-card{ | |||||
border-radius: 10px; | |||||
} | |||||
} | |||||
</style> | |||||
<template> | <template> | ||||
<div class="dashboard__main"> | |||||
<div class="dashboard__top"> | |||||
<TaskCard /> | |||||
<VideoCard /> | |||||
</div> | |||||
<div class="dishboard__bottom"> | |||||
<AirCard /> | |||||
</div> | |||||
<div> | |||||
<OneMap /> | |||||
</div> | </div> | ||||
</template> | </template> | ||||
<script> | <script> | ||||
import { useRouter } from 'vue-router' | import { useRouter } from 'vue-router' | ||||
import TaskCard from './components/TaskCard.vue' | |||||
import VideoCard from './components/VideoCard.vue' | |||||
import AirCard from './components/AirCard.vue' | |||||
import OneMap from './components/OneMap.vue' | |||||
export default { | export default { | ||||
name: 'HomePage', | name: 'HomePage', | ||||
components: { TaskCard, VideoCard, AirCard }, | |||||
components: { OneMap }, | |||||
setup(props) { | setup(props) { | ||||
const router = useRouter() | const router = useRouter() | ||||
function toSystem() { | function toSystem() { |
status: 1, | status: 1, | ||||
...res | ...res | ||||
} | } | ||||
console.log(_params) | |||||
return await getQuestionList(_params) | return await getQuestionList(_params) | ||||
} | } | ||||
<template> | <template> | ||||
<div> | <div> | ||||
<n-card> | <n-card> | ||||
<HeadSearch ref="searchRef" :info="search" @search="handleSearch" @reset="handleSearch" @change="handleChange" /> | |||||
<HeadSearch | |||||
ref="searchRef" | |||||
:info="search" | |||||
@search="handleSearch" | |||||
@reset="handleSearch" | |||||
@change="handleChange" | |||||
/> | |||||
<DataTable | <DataTable | ||||
ref="tableRef" | ref="tableRef" | ||||
:columns="columns" | :columns="columns" | ||||
size="large" | size="large" | ||||
> | > | ||||
<template #tableTitle> | <template #tableTitle> | ||||
<n-button type="primary" @click="handleModal"> 新建 </n-button> | |||||
<n-button | |||||
type="primary" | |||||
@click="handleModal" | |||||
> 新建 </n-button> | |||||
<!-- <n-popconfirm | <!-- <n-popconfirm | ||||
negative-text="取消" | negative-text="取消" | ||||
positive-text="确认" | positive-text="确认" | ||||
</div> | </div> | ||||
<!-- 新增、编辑弹窗 --> | <!-- 新增、编辑弹窗 --> | ||||
<TaskModal v-if="modalShow" v-model:visible="modalShow" :type="modalType" :data="rowData" @reload="handleSearch" /> | |||||
<TaskModal | |||||
v-if="modalShow" | |||||
v-model:visible="modalShow" | |||||
:type="modalType" | |||||
:data="rowData" | |||||
@reload="handleSearch" | |||||
/> | |||||
<!-- 直播抽屉 --> | <!-- 直播抽屉 --> | ||||
<LiveDrawer v-model:visible="liveDrawer" :data="rowData" /> | |||||
<LiveDrawer | |||||
v-model:visible="liveDrawer" | |||||
:data="rowData" | |||||
/> | |||||
<!-- 轨迹回放 --> | <!-- 轨迹回放 --> | ||||
<DemandDrawer v-model:visible="demandDrawer" :data="rowData" /> | |||||
<DemandDrawer | |||||
v-model:visible="demandDrawer" | |||||
:data="rowData" | |||||
/> | |||||
<!-- 问题核实 --> | <!-- 问题核实 --> | ||||
<VerifyDrawer v-model:visible="verifyDrawer" :data="rowData" /> | |||||
<VerifyDrawer | |||||
v-model:visible="verifyDrawer" | |||||
:data="rowData" | |||||
/> | |||||
</template> | </template> | ||||
import LiveDrawer from './components/LiveDrawer.vue' | import LiveDrawer from './components/LiveDrawer.vue' | ||||
import DemandDrawer from './components/DemandDrawer.vue' | import DemandDrawer from './components/DemandDrawer.vue' | ||||
import VerifyDrawer from './components/VerifyDrawer.vue' | import VerifyDrawer from './components/VerifyDrawer.vue' | ||||
import { reactive, ref, unref, toRefs, onUnmounted } from 'vue' | |||||
import { reactive, ref, unref, toRefs, onUnmounted, onMounted } from 'vue' | |||||
import { getTaskList } from '@/api/task/index.js' | import { getTaskList } from '@/api/task/index.js' | ||||
import { useRoute } from 'vue-router' | |||||
export default { | export default { | ||||
name: 'TaskAll', | name: 'TaskAll', | ||||
components: { HeadSearch, DataTable, TaskModal, LiveDrawer, DemandDrawer, VerifyDrawer }, | components: { HeadSearch, DataTable, TaskModal, LiveDrawer, DemandDrawer, VerifyDrawer }, | ||||
setup() { | setup() { | ||||
const route = useRoute() | |||||
const rowInfo = route.query.rowInfo | |||||
getAirOptions() | getAirOptions() | ||||
const searchRef = ref() | const searchRef = ref() | ||||
const data = reactive({ | const data = reactive({ | ||||
searchRef.value.setFormValue({ inspectionLine: null }) | searchRef.value.setFormValue({ inspectionLine: null }) | ||||
} | } | ||||
} | } | ||||
onMounted(() => { | |||||
if (rowInfo) { | |||||
data.rowData = rowInfo | |||||
data.liveDrawer = true | |||||
} | |||||
}) | |||||
onUnmounted(() => { | onUnmounted(() => { | ||||
data.searchParams = null | data.searchParams = null | ||||
}) | }) |
const tableRef = ref() | const tableRef = ref() | ||||
const searchParams = ref() | const searchParams = ref() | ||||
function handleSearch(params) { | |||||
function handleSearch (params) { | |||||
searchParams.value = { ...params } | searchParams.value = { ...params } | ||||
tableRef.value.reFetch({ searchParams }) | tableRef.value.reFetch({ searchParams }) | ||||
} | } | ||||
* @param {*} type 操作类型 create:创建,preview:预览,edit:编辑 | * @param {*} type 操作类型 create:创建,preview:预览,edit:编辑 | ||||
* @return {*} | * @return {*} | ||||
*/ | */ | ||||
function getRowData(row, type) { | |||||
function getRowData (row, type) { | |||||
data.rowData = row | data.rowData = row | ||||
data.modalType = type | data.modalType = type | ||||
data.modalShow = true | data.modalShow = true | ||||
} | } | ||||
function handleRowDelete(row) { | |||||
function handleRowDelete (row) { | |||||
taskDelete(row.id) | taskDelete(row.id) | ||||
.then(res => { | .then(res => { | ||||
if (res.code === 0) { | if (res.code === 0) { | ||||
}) | }) | ||||
} | } | ||||
function handleImplement(row) { | |||||
function handleImplement (row) { | |||||
$message.info('机场设备开始自检,请稍等') | $message.info('机场设备开始自检,请稍等') | ||||
implement(row.id) | implement(row.id) | ||||
.then(res => { | .then(res => { | ||||
if (res.code === 0) { | if (res.code === 0) { | ||||
} | } | ||||
/* 直播 */ | /* 直播 */ | ||||
function handleTaskLive(row) { | |||||
function handleTaskLive (row) { | |||||
data.rowData = row | data.rowData = row | ||||
data.liveDrawer = true | data.liveDrawer = true | ||||
} | } | ||||
/* 回放 */ | /* 回放 */ | ||||
function handleTaskDemand(row) { | |||||
function handleTaskDemand (row) { | |||||
data.rowData = row | data.rowData = row | ||||
data.demandDrawer = true | data.demandDrawer = true | ||||
} | } | ||||
/* 问题核实 */ | /* 问题核实 */ | ||||
function handleTaskVerify(row) { | |||||
function handleTaskVerify (row) { | |||||
data.rowData = row | data.rowData = row | ||||
data.verifyDrawer = true | data.verifyDrawer = true | ||||
} | } | ||||
title: '巡检方式', | title: '巡检方式', | ||||
key: 'inspectionType', | key: 'inspectionType', | ||||
align: 'center', | align: 'center', | ||||
render(row) { | |||||
render (row) { | |||||
return h(TableTags, { | return h(TableTags, { | ||||
data: row.inspectionType, | data: row.inspectionType, | ||||
filters: TASK_MODE | filters: TASK_MODE | ||||
title: '任务类型', | title: '任务类型', | ||||
key: 'type', | key: 'type', | ||||
align: 'center', | align: 'center', | ||||
render(row) { | |||||
render (row) { | |||||
return h(TableTags, { | return h(TableTags, { | ||||
data: row.type, | data: row.type, | ||||
filters: TASK_TYPE | filters: TASK_TYPE | ||||
title: '状态', | title: '状态', | ||||
key: 'status', | key: 'status', | ||||
align: 'center', | align: 'center', | ||||
render(row) { | |||||
render (row) { | |||||
return h(TableTags, { | return h(TableTags, { | ||||
data: row.status, | data: row.status, | ||||
filters: TASK_STATUS | filters: TASK_STATUS | ||||
align: 'center', | align: 'center', | ||||
width: 150, | width: 150, | ||||
fixed: 'right', | fixed: 'right', | ||||
render(row) { | |||||
render (row) { | |||||
return h(TableAction, { | return h(TableAction, { | ||||
actions: [ | actions: [ | ||||
{ | { |