VITE_APP_USE_MOCK = false | VITE_APP_USE_MOCK = false | ||||
# proxy | # 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 | # base api | ||||
VITE_APP_GLOB_BASE_API = '/api-local' | VITE_APP_GLOB_BASE_API = '/api-local' | ||||
# mock base api | # mock base api | ||||
VITE_APP_GLOB_BASE_API_MOCK = '/api-mock' | |||||
VITE_APP_GLOB_BASE_API_MOCK = '/api-mock' |
* @description:获取机场详细信息 | * @description:获取机场详细信息 | ||||
* @param id 机场id | * @param id 机场id | ||||
*/ | */ | ||||
export function getAirportInfo(data) { | |||||
export function getAirportInfo(id) { | |||||
return request({ | return request({ | ||||
url: `/index/getAirportDetail`, | |||||
method: 'POST', | |||||
data | |||||
url: `/index/getAirportDetail/${id}`, | |||||
method: 'GET' | |||||
}) | }) | ||||
} | } | ||||
/** | /** | ||||
hideMessage: true | hideMessage: true | ||||
}) | }) | ||||
} | } | ||||
// 预警列表 | |||||
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 | |||||
}) | |||||
} | |||||
*/ | */ | ||||
export function updateWarning(id, status) { | export function updateWarning(id, status) { | ||||
return request({ | return request({ | ||||
url: `/warning/status/${id}/${status}`, | |||||
// url: `/warning/status/${id}/${status}`, | |||||
url: `/warning/messageRead/status/${id}`, | |||||
method: 'put', | method: 'put', | ||||
hideMessage: true | hideMessage: true | ||||
}) | }) |
// 可切换每页数量集合 | // 可切换每页数量集合 | ||||
pageSizes: [10, 20, 30, 40, 50], | pageSizes: [10, 20, 30, 40, 50], | ||||
// 是否显示每页条数的选择器 | // 是否显示每页条数的选择器 | ||||
showSizePicker: false, | |||||
showSizePicker: true, | |||||
// 是否显示快速跳转 | // 是否显示快速跳转 | ||||
showQuickJumper: false | |||||
showQuickJumper: true | |||||
} | } | ||||
} | } | ||||
} | } |
<script setup> | <script setup> | ||||
import { isNullOrUndef } from '@/utils/is' | import { isNullOrUndef } from '@/utils/is' | ||||
import { useDialog } from 'naive-ui' | |||||
import { useDialog, useDialogReactiveList } from 'naive-ui' | |||||
const NDialog = useDialog() | const NDialog = useDialog() | ||||
const dialogReactiveList = useDialogReactiveList() | |||||
class Dialog { | class Dialog { | ||||
success(title, option) { | success(title, option) { | ||||
...option | ...option | ||||
}) | }) | ||||
} | } | ||||
colseDialog() { | |||||
dialogReactiveList.value[0]?.cancel() | |||||
} | |||||
} | } | ||||
window['$dialog'] = new Dialog() | window['$dialog'] = new Dialog() | ||||
configurable: false, | configurable: false, | ||||
writable: false | writable: false | ||||
}) | }) | ||||
</script> | </script> | ||||
] | ] | ||||
export const TASK_TYPE = [ | export const TASK_TYPE = [ | ||||
{ label: '日常巡检', value: 1 }, | |||||
{ label: '应急巡检', value: 2 } | |||||
{ label: '日常巡检', value: 1 } | |||||
// { label: '应急巡检', value: 2 } | |||||
] | ] | ||||
export const QUESTION_STATUS = [ | export const QUESTION_STATUS = [ |
export const timerHeart = async function() { | export const timerHeart = async function() { | ||||
if (getToken()) { | if (getToken()) { | ||||
setTimeout(() => { timerHeart() }, 5000) | |||||
hasTimer.value = true | hasTimer.value = true | ||||
const res = await fireHeart() | const res = await fireHeart() | ||||
if (res.code === 0) { | if (res.code === 0) { | ||||
} | } | ||||
} | } | ||||
) | ) | ||||
// } else { | |||||
// $dialog.colseDialog() | |||||
} | } | ||||
setTimeout(() => { | |||||
timerHeart() | |||||
}, 5000) | |||||
} | } | ||||
} else { | } else { | ||||
hasModal.value = false | hasModal.value = false |
<template> | |||||
<n-card> | |||||
<div class="card__title"> | |||||
<p class="card__title--left">机场状态</p> | |||||
<p class="card__title--right"> | |||||
<n-form | |||||
inline | |||||
:label-width="80" | |||||
:model="videoForm" | |||||
label-placement="left" | |||||
> | |||||
<n-form-item label="机场选择:" path="airportId"> | |||||
<n-select v-model:value="videoForm.airportId" :options="airOptions" @update:value="getAirportInfo" /> | |||||
</n-form-item> | |||||
</n-form> | |||||
</p> | |||||
</div> | |||||
<div class="card__video"> | |||||
<div class="video__item"> | |||||
<VideoPlayer id="video-inner" ref="videoRef" :use-empty="true"> | |||||
<template #empty> | |||||
<div class="video__item--empty"> | |||||
<img src="@/assets/images/lose-control.png"> | |||||
<p>暂无信号</p> | |||||
</div> | |||||
</template> | |||||
</VideoPlayer> | |||||
</div> | |||||
<div class="video__item"> | |||||
<div class="item__weather"> | |||||
<ul> | |||||
<li v-for="(item,index) in weatherList" :key="index"> {{ item.label }}: {{ item.value }} </li> | |||||
</ul> | |||||
</div> | |||||
<BaseMap ref="mapRef" :coordinate="coordinate" /> | |||||
</div> | |||||
</div> | |||||
</n-card> | |||||
</template> | |||||
<script> | |||||
import { dataToSelect } from '@/utils/handleData.js' | |||||
import { airportList, airportWeather } from '@/api/dashboard/index.js' | |||||
import VideoPlayer from '@/components/VideoPlayer/index.vue' | |||||
import BaseMap from '@/components/BaseMap/BaseMap.vue' | |||||
import { ref, reactive, toRefs, nextTick } from 'vue' | |||||
import { gcj02towgs84 } from '@/utils/coordinate-util.js' | |||||
export default { | |||||
name: 'TaskCard', | |||||
components: { VideoPlayer, BaseMap }, | |||||
setup() { | |||||
const mapRef = ref() | |||||
const videoRef = ref() | |||||
const data = reactive({ | |||||
videoForm: { | |||||
airportId: null | |||||
}, | |||||
airOptions: [], | |||||
airOptionsAll: [], | |||||
weatherList: [], | |||||
coordinate: [108.94043, 31.008173] | |||||
}) | |||||
/** | |||||
* @description: 获取机场数据 | |||||
* @param {*} res | |||||
* @return {*} | |||||
*/ | |||||
const loadAirport = (async function() { | |||||
const res = await airportList({ page: 1, limit: 60 }) | |||||
if (res.code === 0) { | |||||
data.airOptionsAll = res.data | |||||
// console.log(data.airOptionsAll) | |||||
data.airOptions = dataToSelect(res.data, { label: 'name', value: 'id' }) | |||||
data.videoForm.airportId = res.data[0].id | |||||
getAirportInfo(res.data[0].id) | |||||
} | |||||
})() | |||||
async function getAirportInfo(id) { | |||||
const airItem = data.airOptionsAll.find((item) => { return item.id === id }) | |||||
const coordinate = gcj02towgs84(parseFloat(airItem?.longitude), parseFloat(airItem?.latitude)) | |||||
markPoint(coordinate) | |||||
const res = await airportWeather(id) | |||||
if (res.code === 0) { | |||||
const parm = res.data.wth?.parm || [] | |||||
data.weatherList = parm.length !== 0 ? [ | |||||
// { label: '天气', value: '' }, | |||||
{ label: '气温', value: (parm.tmp / 10).toFixed(1) + ' ℃' }, | |||||
{ label: '湿度', value: (parm.hum / 10).toFixed(1) + ' RH' }, | |||||
{ label: '风度', value: (parm.wspd / 10).toFixed(1) + ' m/s' }, | |||||
{ label: '风向', value: (parm.wdir).toFixed(1) + ' °' } | |||||
] : [] | |||||
videoRef.value.disposeVideo() | |||||
nextTick(() => { | |||||
initPlayer() | |||||
}) | |||||
} | |||||
} | |||||
/* 地图标点 */ | |||||
const markPoint = function(coordinate) { | |||||
try { | |||||
mapRef.value.getLayer(coordinate) | |||||
} catch (e) { | |||||
markPoint(coordinate) | |||||
} | |||||
} | |||||
function initPlayer() { | |||||
const row = data.airOptionsAll.find((item) => { return item.id === data.videoForm.airportId }) | |||||
const options = { | |||||
width: '100%', | |||||
height: '100%', | |||||
source: row?.flvExternalMonitorUrl, | |||||
isLive: true | |||||
} | |||||
videoRef.value?.init(options) | |||||
} | |||||
return { | |||||
...toRefs(data), | |||||
mapRef, | |||||
videoRef, | |||||
loadAirport, | |||||
getAirportInfo | |||||
} | |||||
} | |||||
} | |||||
</script> | |||||
<style scoped lang='scss'> | |||||
.card__title{ | |||||
line-height: 20px; | |||||
display: flex; | |||||
align-items: center; | |||||
justify-content: space-between; | |||||
margin-bottom: 15px; | |||||
.card__title--left{ | |||||
font-size: 18px; | |||||
padding-left: 8px; | |||||
border-left: 4px solid rgba(24, 144, 255, 1); | |||||
} | |||||
.card__title--right{ | |||||
.n-select{ | |||||
width: 180px; | |||||
} | |||||
} | |||||
} | |||||
.card__video{ | |||||
display: flex; | |||||
height: calc(100% - 55px); | |||||
.video__item{ | |||||
width: calc(50% - 10px); | |||||
position: relative; | |||||
&:first-child{ | |||||
margin-right: 20px | |||||
} | |||||
.video__item--empty{ | |||||
position: absolute; | |||||
width: 100%; | |||||
height: 100%; | |||||
background: rgba(3, 3, 3, 1); | |||||
img{ | |||||
position: absolute; | |||||
left: 50%; | |||||
top: 45%; | |||||
transform: translate(-50%,-50%); | |||||
} | |||||
p{ | |||||
position: absolute; | |||||
left: 50%; | |||||
top: 60%; | |||||
transform: translate(-50%,-50%); | |||||
font-size: 12px; | |||||
color: rgba(255, 255, 255, 1); | |||||
} | |||||
} | |||||
.item__weather{ | |||||
position: absolute; | |||||
z-index: 100; | |||||
padding: 5px 6px; | |||||
font-size: 12px; | |||||
right: 0; | |||||
color: rgba(255, 255, 255, 1); | |||||
background: rgba(0, 0, 0, 0.4); | |||||
} | |||||
} | |||||
} | |||||
::v-deep(.n-form){ | |||||
.n-form-item-feedback-wrapper{ | |||||
display: none; | |||||
} | |||||
} | |||||
</style> |
{ icon: new URL('../../../assets/images/north.png', import.meta.url).href, indicatorValue: null, indicatorName: '风向' }, | { 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/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/airHumidity.png', import.meta.url).href, indicatorValue: null, indicatorName: '空气湿度' }, | ||||
{ icon: new URL('../../../assets/images/airTemperature.png', import.meta.url).href, indicatorValue: null, indicatorName: '空气温度' }], | { icon: new URL('../../../assets/images/airTemperature.png', import.meta.url).href, indicatorValue: null, indicatorName: '空气温度' }], | ||||
innerMonitorOptions: { | innerMonitorOptions: { | ||||
// width: '256px', | // width: '256px', | ||||
height: '198px', | height: '198px', | ||||
control: true, // 是否显示控制 | control: true, // 是否显示控制 | ||||
controlBtns: [ | controlBtns: [ | ||||
'fullScreen' | 'fullScreen' | ||||
], // 显示所有按钮, | ], // 显示所有按钮, | ||||
src: '' | src: '' | ||||
watch(() => props.data, (value) => { | watch(() => props.data, (value) => { | ||||
if (JSON.stringify(value) !== '{}') { | if (JSON.stringify(value) !== '{}') { | ||||
// console.log(props.data) | |||||
data.detail = props.data | |||||
data.detail = value | |||||
innerVideoRef.value?.disposeVideo() | innerVideoRef.value?.disposeVideo() | ||||
outVideoRef.value?.disposeVideo() | outVideoRef.value?.disposeVideo() | ||||
initPlayer(data.detail.internalMonitorUrl, data.detail.externalMonitorUrl) | initPlayer(data.detail.internalMonitorUrl, data.detail.externalMonitorUrl) | ||||
getAirportInfo({ | |||||
airportId: data.detail.id | |||||
}) | |||||
getAirportInfo(data.detail.id) | |||||
.then(res => { | .then(res => { | ||||
if (res.code === 0) { | if (res.code === 0) { | ||||
// console.log(res, '机场详情') | // console.log(res, '机场详情') |
</template> | </template> | ||||
<script> | <script> | ||||
import { reactive, toRefs } from 'vue' | |||||
import { onMounted, reactive, toRefs } from 'vue' | |||||
import { startOfDay } from 'date-fns/esm' | import { startOfDay } from 'date-fns/esm' | ||||
import { getMissionList, getQuestionList } from '@/api/dashboard/index.js' | import { getMissionList, getQuestionList } from '@/api/dashboard/index.js' | ||||
import { cameraList } from '@/api/basic/monitor.js' | import { cameraList } from '@/api/basic/monitor.js' | ||||
{ name: '火灾预警', path: 'warning', selected: { color: 'rgba(51, 133, 255, 1)', path: 'warning_select' }}, | { name: '火灾预警', path: 'warning', selected: { color: 'rgba(51, 133, 255, 1)', path: 'warning_select' }}, | ||||
{ name: '森林巡查', path: 'patrol', selected: { color: 'rgba(51, 133, 255, 1)', path: 'patrol_select' }} | { name: '森林巡查', path: 'patrol', selected: { color: 'rgba(51, 133, 255, 1)', path: 'patrol_select' }} | ||||
], | ], | ||||
showWarning: false, | |||||
showWarning: true, | |||||
showPatrol: false, | showPatrol: false, | ||||
portalTab: 'task' | portalTab: 'task' | ||||
}) | }) | ||||
const warn = reactive({ | const warn = reactive({ | ||||
warnList: [ | warnList: [ | ||||
{ icon: camera, label: '监控分布', value: 1, num: 0, list: [] }, | |||||
{ icon: materials, label: '消防物资', value: 2, num: 0, list: [] }, | |||||
{ icon: personnel, label: '防护人员', value: 3, num: 0, list: [] } | |||||
{ icon: camera, label: '监控分布', value: 'camera', num: 0, list: [] }, | |||||
{ icon: materials, label: '消防物资', value: 'materials', num: 0, list: [] } | |||||
// { icon: personnel, label: '防护人员', value: 'personnel', num: 0, list: [] } | |||||
], | ], | ||||
checkedWarn: [1, 2, 3] | |||||
checkedWarn: ['camera', 'materials'] | |||||
}) | }) | ||||
const task = reactive({ | const task = reactive({ | ||||
taskList: [], | taskList: [], | ||||
const handleClick = (index) => { | const handleClick = (index) => { | ||||
data.selectedTab = index | data.selectedTab = index | ||||
if (index === 1) { | if (index === 1) { | ||||
data.portalTab = 'task' | |||||
ques.checkedQues = QUESTION_TYPE.value?.map((item) => item.value) || null | |||||
if (!data.showPatrol) { | if (!data.showPatrol) { | ||||
queryTaskList() | queryTaskList() | ||||
const times = [formatDate(ques.times[0]), formatDate(ques.times[1])] | const times = [formatDate(ques.times[0]), formatDate(ques.times[1])] | ||||
data.showWarning = false | data.showWarning = false | ||||
} else { | } else { | ||||
getWarnList() | getWarnList() | ||||
warn.checkedWarn = ['camera', 'materials'] | |||||
data.showWarning = true | data.showWarning = true | ||||
data.showPatrol = false | data.showPatrol = false | ||||
} | } | ||||
} | } | ||||
const res = await getQuestionList(params) | const res = await getQuestionList(params) | ||||
if (res.code === 0) { | if (res.code === 0) { | ||||
ques.checkedQues = QUESTION_TYPE.value?.map((item) => item.value) || null | |||||
ques.message = res.data?.map((item) => { | ques.message = res.data?.map((item) => { | ||||
item.icon = ICON_LIST[item.type] | item.icon = ICON_LIST[item.type] | ||||
return item | return item | ||||
}) | }) | ||||
emit('send', { tabs: data.selectedTab, data: ques.message, type: ques.checkedQues }) | |||||
emit('send', { tabs: data.selectedTab, data: ques.message, type: ques.checkedQues, ops: 'query' }) | |||||
} else { | } else { | ||||
ques.message = null | ques.message = null | ||||
} | } | ||||
warn.warnList[0].list = camera?.data || [] | warn.warnList[0].list = camera?.data || [] | ||||
warn.warnList[1].num = maertral?.data?.length || 0 | warn.warnList[1].num = maertral?.data?.length || 0 | ||||
warn.warnList[1].list = maertral?.data || [] | warn.warnList[1].list = maertral?.data || [] | ||||
emit('send', { tabs: data.selectedTab, data: warn.warnList, type: warn.checkedWarn }) | |||||
emit('send', { tabs: data.selectedTab, data: warn.warnList, type: warn.checkedWarn, ops: 'query' }) | |||||
}) | }) | ||||
.catch(err => { | .catch(err => { | ||||
console.log(err) | console.log(err) | ||||
* @return {*} | * @return {*} | ||||
*/ | */ | ||||
const handleWarnChange = async(value) => { | const handleWarnChange = async(value) => { | ||||
emit('send', { tabs: data.selectedTab, data: warn.warnList, type: value }) | |||||
emit('send', { tabs: data.selectedTab, data: warn.warnList, type: value, ops: 'select' }) | |||||
} | } | ||||
/** | /** | ||||
* @description: 变更僧林巡查问题选择 | * @description: 变更僧林巡查问题选择 | ||||
* @return {*} | * @return {*} | ||||
*/ | */ | ||||
const handleQuesChange = async(value) => { | const handleQuesChange = async(value) => { | ||||
emit('send', { tabs: data.selectedTab, data: ques.message, type: value }) | |||||
emit('send', { tabs: data.selectedTab, data: ques.message, type: value, ops: 'select' }) | |||||
} | } | ||||
return { | return { |
<template> | |||||
<div class="fire-alarm"> | |||||
<div class="fire-details"> | |||||
<p class="alarm-title">火灾详情</p> | |||||
<div style="width: 100%; height: 210px"> | |||||
视频位置 | |||||
</div> | |||||
<p class="alarm-detail"> | |||||
<span>火灾位置:</span> | |||||
<span>{{ fireDetail.location }}</span> | |||||
</p> | |||||
<p class="alarm-detail"> | |||||
<span>发现方式:</span> | |||||
<span>{{ fireDetail.discoveryWay }}</span> | |||||
</p> | |||||
<p class="alarm-detail"> | |||||
<span>上报时间:</span> | |||||
<span>{{ fireDetail.time }}</span> | |||||
</p> | |||||
</div> | |||||
<p class="dividing-line" /> | |||||
<div class="airport-dispatch"> | |||||
<p class="alarm-title">机场调度</p> | |||||
<p class="dispatch-detail"> | |||||
<span>选择机场:</span> | |||||
<n-select v-model:value="value" :options="airpotOptions" /> | |||||
<a>可用机场列表</a> | |||||
</p> | |||||
<p class="dispatch-detail"> | |||||
<span>飞行高度:</span> | |||||
<n-slider v-model:value="value" :default-value="100" :format-tooltip="formatHeight" :max="600" :show-tooltip="true" :placement="bottom" /> | |||||
</p> | |||||
<p class="execute-btn">立即执行</p> | |||||
<p class="task-log"> | |||||
<span>任务记录</span> | |||||
<ul> | |||||
<li> 2023-01-23 10:00:00 XXXXX机场执行任务 执行中</li> | |||||
<li> 2023-01-23 10:00:00 XXXXX机场执行任务 已完成</li> | |||||
<li> 2023-01-23 10:00:00 XXXXX机场执行任务 已完成</li> | |||||
</ul> | |||||
</p> | |||||
</div> | |||||
<p class="dividing-line" /> | |||||
<div class="fire-verify"> | |||||
<p class="alarm-title">火灾核实</p> | |||||
<n-input | |||||
v-model:value="value" | |||||
type="textarea" | |||||
placeholder="请输入火灾核实描述" | |||||
/> | |||||
<p class="verify-btns"> | |||||
<span>忽略</span> | |||||
<span>已处理</span> | |||||
</p> | |||||
</div> | |||||
</div> | |||||
<div class="available-airports"> | |||||
<p class="alarm-title">可用机场列表</p> | |||||
<div class="airport-params"> | |||||
<p> | |||||
<span class="airport-name">机场1</span> | |||||
<span class="airport-find">发现隐患的机场</span> | |||||
</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> | |||||
</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> | |||||
</template> | |||||
<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: { }, | |||||
props: { | |||||
data: { | |||||
type: Object, | |||||
default: () => { } | |||||
} | |||||
}, | |||||
emits: [], | |||||
setup(props, { emit }) { | |||||
const data = reactive({ | |||||
airpotOptions: [ | |||||
{ | |||||
label: '机场1', | |||||
value: 'airport1' | |||||
}, | |||||
{ | |||||
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' | |||||
} | |||||
return { | |||||
...toRefs(data), | |||||
formatHeight | |||||
} | |||||
} | |||||
} | |||||
</script> | |||||
<style lang="scss" scoped> | |||||
.fire-alarm { | |||||
position: absolute; | |||||
left: 1345px; | |||||
top: 10px; | |||||
width: 407px; | |||||
height: 925px; | |||||
opacity: 0.85; | |||||
border-radius: 1px; | |||||
background: rgba(0, 0, 0, 1); | |||||
} | |||||
.alarm-title { | |||||
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: 85px; | |||||
height: 30px; | |||||
line-height: 30px; | |||||
display: inline-block; | |||||
color: rgba(139, 139, 139, 1); | |||||
font-size: 14px; | |||||
text-align: right; | |||||
} | |||||
span:nth-child(2){ | |||||
width: 320px; | |||||
height: 30px; | |||||
line-height: 30px; | |||||
display: inline-block; | |||||
color: rgba(255, 255, 255, 1); | |||||
font-size: 14px; | |||||
text-align: left; | |||||
padding-left: 5px; | |||||
} | |||||
} | |||||
.dividing-line{ | |||||
width: 100%; | |||||
height: 0px; | |||||
opacity: 1; | |||||
background: rgba(112, 112, 112, 1); | |||||
border: 0.2px solid rgba(107, 107, 107, 1); | |||||
margin: 15px 0 0 0; | |||||
} | |||||
::v-deep(.dispatch-detail) { | |||||
width: 100%; | |||||
height: 34px; | |||||
margin: 5px 0; | |||||
span { | |||||
width: 90px; | |||||
height: 34px; | |||||
line-height: 34px; | |||||
display: inline-block; | |||||
color: rgba(139, 139, 139, 1); | |||||
font-size: 14px; | |||||
text-align: right; | |||||
} | |||||
.n-select { | |||||
width: 225px; | |||||
height: 32px; | |||||
border-radius: 2px; | |||||
display: inline-block; | |||||
margin-left: 5px; | |||||
} | |||||
.n-slider { | |||||
width: 270px; | |||||
display: inline-block; | |||||
margin-left: 6px; | |||||
vertical-align: middle; | |||||
} | |||||
a { | |||||
color: rgba(0, 119, 255, 1); | |||||
font-size: 10px; | |||||
margin-left: 6px; | |||||
cursor: pointer; | |||||
} | |||||
} | |||||
.execute-btn { | |||||
width: 347px; | |||||
height: 32px; | |||||
margin: 10px 0; | |||||
border-radius: 17px; | |||||
background: rgba(31, 31, 31, 1); | |||||
border: 2px solid rgba(57, 146, 247, 1); | |||||
color: #fff; | |||||
line-height: 32px; | |||||
font-size: 14px; | |||||
text-align: center; | |||||
margin-left: 30px; | |||||
cursor: pointer; | |||||
} | |||||
.task-log { | |||||
width: 100%; | |||||
margin-top: 30px; | |||||
span { | |||||
width: 100%; | |||||
height: 30px; | |||||
display: inline-block; | |||||
line-height: 30px; | |||||
color: #fff; | |||||
font-size: 14px; | |||||
padding-left: 25px; | |||||
} | |||||
} | |||||
::v-deep(.fire-verify){ | |||||
width: 100%; | |||||
.n-input { | |||||
margin-left: 35px; | |||||
width: 350px; | |||||
height: 90px; | |||||
} | |||||
.verify-btns { | |||||
width: 100%; | |||||
height: 32px; | |||||
margin-top: 30px; | |||||
span { | |||||
width: 162px; | |||||
height: 32px; | |||||
display: inline-block; | |||||
border-radius: 17px; | |||||
background: rgba(31, 31, 31, 1); | |||||
border: 2px solid rgba(57, 146, 247, 1); | |||||
line-height: 32px; | |||||
color: #fff; | |||||
font-size: 14px; | |||||
text-align: center; | |||||
cursor: pointer; | |||||
} | |||||
span:nth-child(1){ | |||||
background: rgba(57, 146, 247, 1); | |||||
margin-left: 37px; | |||||
margin-right: 6px; | |||||
} | |||||
} | |||||
} | |||||
.available-airports { | |||||
position: absolute; | |||||
left: 764px; | |||||
top: 91px; | |||||
width: 285px; | |||||
height: 449px; | |||||
opacity: 0.85; | |||||
border-radius: 1px; | |||||
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> | |||||
}) | }) | ||||
watch(() => props.detail, (value) => { | watch(() => props.detail, (value) => { | ||||
console.log(value) | |||||
if (JSON.stringify(value) !== '{}') { | if (JSON.stringify(value) !== '{}') { | ||||
const fileImageList = value.fileMarkerUrl.split(',') | const fileImageList = value.fileMarkerUrl.split(',') | ||||
data.fileImageList = [] | data.fileImageList = [] |
<template> | |||||
<div v-show="suppliesShow" class="supplies-content"> | |||||
<div class="supplies-title"> | |||||
<p>消防物资</p> | |||||
<span class="close-supplies" @click="closeSupplies" /> | |||||
</div> | |||||
<p class="supplies-type"> | |||||
<img :src="`/src/assets/gis/images/toLeft.png`" @click="deSuppliesIndex"> | |||||
<span v-for="(item ,index) in MATERIAL_TYPE" v-show="item.value === suppliesType" :key="index"> | |||||
{{ item.label }} | |||||
</span> | |||||
<img :src="`/src/assets/gis/images/toRight.png`" @click="inSuppliesIndex"> | |||||
</p> | |||||
<div class="supplies-table"> | |||||
<ul class="table-title"> | |||||
<li> | |||||
<span>序号</span> | |||||
<span>物资名称</span> | |||||
<span>作用</span> | |||||
</li> | |||||
</ul> | |||||
<ul class="table-content"> | |||||
<li v-for="(item, index) in goodsFeaturesByType" :key="index"> | |||||
<span>{{ index + 1 }}</span> | |||||
<span>{{ item.goodsName }}</span> | |||||
<span>{{ item.goodsAction }}</span> | |||||
</li> | |||||
</ul> | |||||
</div> | |||||
</div> | |||||
</template> | |||||
<script> | |||||
import { reactive, toRefs, watch } from 'vue' | |||||
import { MATERIAL_TYPE } from '@/utils/dictionary.js' | |||||
import { goodsList } from '@/api/basic/material.js' | |||||
export default { | |||||
name: 'SuppliesInfo', | |||||
components: { }, | |||||
props: { | |||||
data: { | |||||
type: Object, | |||||
default: () => { } | |||||
} | |||||
}, | |||||
emits: ['close'], | |||||
setup(props, { emit }) { | |||||
const data = reactive({ | |||||
detail: props.data, | |||||
suppliesShow: true, | |||||
MATERIAL_TYPE, | |||||
suppliesType: 1, | |||||
goodsFeatures: [], | |||||
goodsFeaturesByType: [] | |||||
}) | |||||
watch(() => props.data, (value) => { | |||||
if (JSON.stringify(value) !== '{}') { | |||||
showGoodsTable(value) | |||||
} | |||||
}) | |||||
const deSuppliesIndex = () => { | |||||
// type索引自减一 | |||||
data.suppliesType = data.suppliesType === 1 ? MATERIAL_TYPE.length : --data.suppliesType | |||||
filterGoods() | |||||
} | |||||
const inSuppliesIndex = () => { | |||||
// type索引自增一 | |||||
data.suppliesType = data.suppliesType < MATERIAL_TYPE.length ? ++data.suppliesType : 1 | |||||
filterGoods() | |||||
} | |||||
// 筛选数据 | |||||
const filterGoods = () => { | |||||
data.goodsFeaturesByType.length = 0 | |||||
data.goodsFeatures.forEach((feature) => { | |||||
if (feature.goodsType === data.suppliesType) { | |||||
data.goodsFeaturesByType.push(feature) | |||||
} | |||||
}) | |||||
} | |||||
const showGoodsTable = async(value) => { | |||||
data.suppliesShow = true | |||||
const res = await goodsList({ | |||||
warehouseId: value.id | |||||
}) | |||||
if (res.code === 0) { | |||||
data.goodsFeatures = res.data | |||||
filterGoods() | |||||
} | |||||
} | |||||
const closeSupplies = () => { | |||||
emit('close') | |||||
} | |||||
return { | |||||
...toRefs(data), | |||||
deSuppliesIndex, | |||||
inSuppliesIndex, | |||||
closeSupplies | |||||
} | |||||
} | |||||
} | |||||
</script> | |||||
<style lang="scss" scoped> | |||||
.supplies-content { | |||||
width: 282px; | |||||
height: 409px; | |||||
background-color: rgba(0, 0, 0, 0.8); | |||||
} | |||||
.supplies-title { | |||||
width: 282px; | |||||
height: 30px; | |||||
p { | |||||
width: 250px; | |||||
height: 30px; | |||||
color: white; | |||||
font-size: 12px; | |||||
line-height: 30px; | |||||
padding-left: 15px; | |||||
float: left; | |||||
} | |||||
span { | |||||
width: 30px; | |||||
height: 30px; | |||||
display: inline-block; | |||||
background: url('@/assets/gis/images/close-icon.png') no-repeat; | |||||
background-size: 100% 100%; | |||||
cursor: pointer; | |||||
} | |||||
} | |||||
.supplies-type { | |||||
width: 270px; | |||||
height: 32px; | |||||
background: rgba(61, 61, 61, 1); | |||||
display: flex; | |||||
align-items: center; | |||||
cursor: pointer; | |||||
margin-left: 6px; | |||||
img { | |||||
margin: 0 8px; | |||||
} | |||||
span { | |||||
width: 210px; | |||||
height: 30px; | |||||
display: inline-block; | |||||
line-height: 30px; | |||||
font-size: 14px; | |||||
color: #fff; | |||||
text-align: center; | |||||
} | |||||
} | |||||
.supplies-table { | |||||
width: 270px; | |||||
height: 335px; | |||||
background: rgba(61, 61, 61, 1); | |||||
margin-left: 6px; | |||||
margin-top: 2px; | |||||
} | |||||
.supplies-table li { | |||||
width: 100%; | |||||
height: 30px; | |||||
line-height: 30px; | |||||
span { | |||||
width: 90px; | |||||
height: 30px; | |||||
line-height: 30px; | |||||
display: inline-block; | |||||
color: #fff; | |||||
font-size: 12px; | |||||
text-align: center; | |||||
} | |||||
} | |||||
::v-deep(.table-content) { | |||||
height: 300px; | |||||
overflow: auto; | |||||
scrollbar-width: none; | |||||
-ms-overflow-style: none; | |||||
&::-webkit-scrollbar { | |||||
display: none; | |||||
} | |||||
} | |||||
</style> | |||||
<template> | |||||
<n-card> | |||||
<div class="card__title"> | |||||
<p class="card__title--left">待飞行任务</p> | |||||
<p class="card__title--right" @click="handlePreviewMore">查看更多<SvgIcon icon-class="arrow" /></p> | |||||
</div> | |||||
<div class="card__table"> | |||||
<n-data-table | |||||
:bordered="false" | |||||
:single-column="true" | |||||
:columns="columns" | |||||
:data="tableData" | |||||
:pagination="false" | |||||
:max-height="340" | |||||
> | |||||
<template #empty> | |||||
<img src="@/assets/images/no-task.png" alt=""> | |||||
</template> | |||||
</n-data-table> | |||||
</div> | |||||
</n-card> | |||||
</template> | |||||
<script> | |||||
import { useRouter } from 'vue-router' | |||||
import SvgIcon from '@/components/SvgIcon/index.vue' | |||||
import { getTaskList } from '@/api/task/index.js' | |||||
import { reactive, toRefs } from 'vue' | |||||
export default { | |||||
name: 'TaskCard', | |||||
components: { SvgIcon }, | |||||
setup() { | |||||
const router = useRouter() | |||||
const data = reactive({ | |||||
tableData: [], | |||||
columns: [ | |||||
{ | |||||
title: '任务名称', | |||||
key: 'name', | |||||
align: 'center' | |||||
}, | |||||
{ | |||||
title: '待飞行时间', | |||||
key: 'executionStartTime', | |||||
align: 'center' | |||||
}, | |||||
{ | |||||
title: '创建人', | |||||
key: 'createUser', | |||||
align: 'center' | |||||
} | |||||
] | |||||
}) | |||||
/** | |||||
* @description: 加载表格数据 | |||||
* @param {*} res | |||||
* @return {*} | |||||
*/ | |||||
const loadDataTable = (async function() { | |||||
const res = await getTaskList({ page: 1, limit: 6, status: 1 }) | |||||
if (res.code === 0) { | |||||
data.tableData = res.data.records | |||||
} | |||||
})() | |||||
function handlePreviewMore() { | |||||
router.replace('/taskManage/all') | |||||
} | |||||
return { | |||||
...toRefs(data), | |||||
loadDataTable, | |||||
handlePreviewMore | |||||
} | |||||
} | |||||
} | |||||
</script> | |||||
<style scoped lang='scss'> | |||||
.card__title{ | |||||
line-height: 20px; | |||||
display: flex; | |||||
justify-content: space-between; | |||||
align-items: center; | |||||
margin-bottom: 15px; | |||||
.card__title--left{ | |||||
font-size: 18px; | |||||
padding-left: 8px; | |||||
border-left: 4px solid rgba(24, 144, 255, 1); | |||||
} | |||||
.card__title--right{ | |||||
font-size: 12px; | |||||
display: flex; | |||||
align-items: center; | |||||
cursor: pointer; | |||||
svg{ | |||||
font-size: 24px; | |||||
} | |||||
&:hover{ | |||||
color: rgba(24, 144, 255, 1); | |||||
} | |||||
} | |||||
} | |||||
.card__table{ | |||||
height: calc(100% - 40px); | |||||
} | |||||
::v-deep(.n-data-table){ | |||||
.n-data-table-tr{ | |||||
.n-data-table-th{ | |||||
padding: 8px 12px; | |||||
background: rgba(191, 223, 255, 1); | |||||
} | |||||
.n-data-table-td--last-row{ | |||||
border-bottom: none; | |||||
} | |||||
} | |||||
} | |||||
</style> |
<template> | |||||
<n-card> | |||||
<div class="card__title"> | |||||
<p class="card__title--left">飞行视频</p> | |||||
<p class="card__title--right"> | |||||
<n-form | |||||
inline | |||||
:label-width="80" | |||||
:model="videoForm" | |||||
label-placement="left" | |||||
> | |||||
<n-form-item label="机场选择:" path="airportId"> | |||||
<n-select v-model:value="videoForm.airportId" :options="airOptions" @update:value="handleAirportChange" /> | |||||
</n-form-item> | |||||
<n-form-item label="回放选择:" path="taskId"> | |||||
<n-select v-model:value="videoForm.taskId" :options="taskOptions" clearable @update:value="handleVideoChange" /> | |||||
</n-form-item> | |||||
</n-form> | |||||
</p> | |||||
</div> | |||||
<div class="card__video"> | |||||
<div class="video__item"> | |||||
<VideoPlayer id="dashboard-video" ref="originRef" :use-empty="true" @video-status="handleVideoStatus"> | |||||
<template #empty> | |||||
<div class="card__video--empty"> | |||||
<img src="@/assets/images/no-live.png"> | |||||
<p>当前暂无直播</p> | |||||
</div> | |||||
</template> | |||||
</VideoPlayer> | |||||
</div> | |||||
</div> | |||||
</n-card> | |||||
</template> | |||||
<script> | |||||
import { dataToSelect } from '@/utils/handleData.js' | |||||
import { airportList } from '@/api/dashboard/index.js' | |||||
import { getTaskList } from '@/api/task/index.js' | |||||
import { missionLive } from '@/api/dashboard/index.js' | |||||
import VideoPlayer from '@/components/VideoPlayer/index.vue' | |||||
import { ref, reactive, onUnmounted, watch, toRefs, nextTick } from 'vue' | |||||
export default { | |||||
name: 'TaskCard', | |||||
components: { VideoPlayer }, | |||||
setup() { | |||||
const originRef = ref() | |||||
const data = reactive({ | |||||
videoForm: { | |||||
airportId: null, | |||||
taskId: null | |||||
}, | |||||
airOptions: [], | |||||
taskOptions: [], | |||||
hasPlayer: false, | |||||
airportIdBack: null, | |||||
videoInfo: { | |||||
url: null, | |||||
isLive: false, | |||||
status: 'init' | |||||
} | |||||
}) | |||||
/** | |||||
* @description: 加载表格数据 | |||||
* @param {*} res | |||||
* @return {*} | |||||
*/ | |||||
const loadAirport = (async function(id) { | |||||
const res = await airportList({ page: 1, limit: 60 }) | |||||
if (res.code === 0) { | |||||
data.airOptions = dataToSelect(res.data, { label: 'name', value: 'id' }) | |||||
data.videoForm.airportId = id || res.data[0]?.id | |||||
handleAirportChange(data.videoForm.airportId) | |||||
} | |||||
})() | |||||
async function loadTaskOption(id) { | |||||
const res = await getTaskList({ page: 1, limit: 600, status: 4, airportId: id }) | |||||
if (res.code === 0) { | |||||
data.taskOptions = dataToSelect(res.data.records, { label: 'name', value: 'id' }) | |||||
} | |||||
} | |||||
function handleAirportChange(value) { | |||||
// if (value === data.airportIdBack) return | |||||
data.airportIdBack = value | |||||
data.videoForm.taskId = null | |||||
missionLive(value) | |||||
.then(res => { | |||||
if (res.code === 0) { | |||||
data.videoInfo = { | |||||
url: res.data?.aiplayUrl, | |||||
isLive: true, | |||||
status: 'init' | |||||
} | |||||
} | |||||
}) | |||||
loadTaskOption(value) | |||||
} | |||||
async function handleVideoChange(value) { | |||||
const row = data.taskOptions.find((item) => { return item.id === value }) | |||||
if (!value) { | |||||
const res = await airportList({ page: 1, limit: 60 }) | |||||
if (res.code === 0) { | |||||
data.airOptions = dataToSelect(res.data, { label: 'name', value: 'id' }) | |||||
handleAirportChange(data.videoForm.airportId) | |||||
} | |||||
} else { | |||||
data.videoInfo = { | |||||
url: row.aiVideoUrl, | |||||
isLive: false, | |||||
status: 'init' | |||||
} | |||||
} | |||||
} | |||||
watch(() => data.videoInfo.url, | |||||
(value) => { | |||||
nextTick(() => { | |||||
originRef.value?.disposeVideo() | |||||
nextTick(() => { | |||||
initVideoPlayer() | |||||
}) | |||||
}) | |||||
}) | |||||
/* 初始化播放器 */ | |||||
function initVideoPlayer() { | |||||
data.videoInfo.status = 'init' | |||||
const origin = { | |||||
width: '100%', | |||||
height: '100%', | |||||
source: data.videoInfo.url, | |||||
isLive: data.videoInfo.isLive | |||||
} | |||||
originRef.value?.init(origin) | |||||
setTimeout(() => { | |||||
if (data.videoInfo.status === 'init') { | |||||
originRef.value?.disposeVideo() | |||||
initVideoPlayer() | |||||
} | |||||
}, 30000) | |||||
} | |||||
function handleVideoStatus(status) { | |||||
data.videoInfo = { | |||||
...data.videoInfo, | |||||
status | |||||
} | |||||
} | |||||
onUnmounted(() => { | |||||
originRef.value?.disposeVideo() | |||||
}) | |||||
return { | |||||
...toRefs(data), | |||||
originRef, | |||||
loadAirport, | |||||
handleAirportChange, | |||||
handleVideoChange, | |||||
handleVideoStatus | |||||
} | |||||
} | |||||
} | |||||
</script> | |||||
<style scoped lang='scss'> | |||||
.card__title{ | |||||
line-height: 20px; | |||||
display: flex; | |||||
justify-content: space-between; | |||||
align-items: center; | |||||
margin-bottom: 15px; | |||||
.card__title--left{ | |||||
font-size: 18px; | |||||
padding-left: 8px; | |||||
border-left: 4px solid rgba(24, 144, 255, 1); | |||||
} | |||||
.card__title--right{ | |||||
.n-select{ | |||||
width: 180px; | |||||
} | |||||
} | |||||
} | |||||
.card__video{ | |||||
display: flex; | |||||
height: calc(100% - 55px); | |||||
position: relative; | |||||
.video__item{ | |||||
width: 100%; | |||||
} | |||||
.card__video--empty{ | |||||
position: absolute; | |||||
width: 100%; | |||||
height: 100%; | |||||
background: rgba(3, 3, 3, 1); | |||||
img{ | |||||
position: absolute; | |||||
left: 50%; | |||||
top: 45%; | |||||
transform: translate(-50%,-50%); | |||||
} | |||||
p{ | |||||
position: absolute; | |||||
left: 50%; | |||||
top: 60%; | |||||
transform: translate(-50%,-50%); | |||||
font-size: 12px; | |||||
color: rgba(255, 255, 255, 1); | |||||
} | |||||
} | |||||
} | |||||
::v-deep(.n-form){ | |||||
.n-form-item-feedback-wrapper{ | |||||
display: none; | |||||
} | |||||
} | |||||
</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="basic"> | <div class="basic"> | ||||
<OneMap /> | |||||
<Extend class="extend" @send="getmessage" /> | |||||
<OneMap ref="Map" /> | |||||
<Extend ref="extendRef" class="extend" @send="getmessage" /> | |||||
<remoate-sensing | <remoate-sensing | ||||
class="remoate-sensing-extrinsic" | class="remoate-sensing-extrinsic" | ||||
@command="setCommandAndLog" | @command="setCommandAndLog" | ||||
</template> | </template> | ||||
<script> | <script> | ||||
import { ref } from 'vue' | |||||
import { useRouter } from 'vue-router' | import { useRouter } from 'vue-router' | ||||
import OneMap from './components/OneMap.vue' | import OneMap from './components/OneMap.vue' | ||||
import Extend from './components/Extend.vue' | import Extend from './components/Extend.vue' | ||||
import { ref, onMounted } from 'vue' | |||||
import RemoateSensing from './components/remoateSensing.vue' | import RemoateSensing from './components/remoateSensing.vue' | ||||
export default { | export default { | ||||
name: 'HomePage', | name: 'HomePage', | ||||
components: { RemoateSensing, OneMap, Extend }, | components: { RemoateSensing, OneMap, Extend }, | ||||
setup(props) { | setup(props) { | ||||
const router = useRouter() | const router = useRouter() | ||||
const extendRef = ref() | |||||
const Map = ref() | |||||
function toSystem() { | function toSystem() { | ||||
router.push({ path: '/login' }) | router.push({ path: '/login' }) | ||||
} | } | ||||
const getmessage = (data) => { | const getmessage = (data) => { | ||||
console.log(data) | |||||
Map.value.addPonit(data) | |||||
} | } | ||||
const data = ref({ | const data = ref({ | ||||
currentDroneInfo: { | currentDroneInfo: { | ||||
$message.error(errorMsg || e.message) | $message.error(errorMsg || e.message) | ||||
}) | }) | ||||
} | } | ||||
onMounted(() => { | |||||
extendRef.value.handleClick(0) | |||||
}) | |||||
return { | return { | ||||
data, | data, | ||||
toSystem, | toSystem, | ||||
extendRef, | |||||
getmessage, | getmessage, | ||||
Map, | |||||
setCommandAndLog | setCommandAndLog | ||||
} | } | ||||
} | } |
inspectionType: null, | inspectionType: null, | ||||
airportId: null, | airportId: null, | ||||
inspectionLine: null, | inspectionLine: null, | ||||
type: null, | |||||
type: 1, | |||||
executionStartTime: null, | executionStartTime: null, | ||||
note: null | note: null | ||||
}, | }, | ||||
inspectionType: [{ required: true, type: 'number', message: '请选择巡检方式', trigger: 'blur' }], | inspectionType: [{ required: true, type: 'number', message: '请选择巡检方式', trigger: 'blur' }], | ||||
airportId: [{ required: true, type: 'number', message: '请选择巡检机场', trigger: 'blur' }], | airportId: [{ required: true, type: 'number', message: '请选择巡检机场', trigger: 'blur' }], | ||||
inspectionLine: [{ required: true, type: 'number', message: '请选择巡检路线', trigger: 'blur' }], | inspectionLine: [{ required: true, type: 'number', message: '请选择巡检路线', trigger: 'blur' }], | ||||
type: [{ required: true, type: 'number', message: '请选择任务类型', trigger: 'blur' }], | |||||
// type: [{ required: true, type: 'number', message: '请选择任务类型', trigger: 'blur' }], | |||||
executionStartTime: [{ required: true, type: 'date', message: '请选择巡检时间', trigger: ['blur', 'change'] }] | executionStartTime: [{ required: true, type: 'date', message: '请选择巡检时间', trigger: ['blur', 'change'] }] | ||||
}, | }, | ||||
formItem: [ | formItem: [ | ||||
{ type: 'select', key: 'inspectionType', label: '巡检方式', props: { options: TASK_MODE }}, | { type: 'select', key: 'inspectionType', label: '巡检方式', props: { options: TASK_MODE }}, | ||||
{ type: 'select', key: 'airportId', label: '巡检机场', props: { options: airOptions }}, | { type: 'select', key: 'airportId', label: '巡检机场', props: { options: airOptions }}, | ||||
{ type: 'select', key: 'inspectionLine', label: '巡检路线', props: { options: lineOptions }}, | { type: 'select', key: 'inspectionLine', label: '巡检路线', props: { options: lineOptions }}, | ||||
{ type: 'select', key: 'type', label: '任务类型', props: { options: TASK_TYPE }}, | |||||
// { type: 'select', key: 'type', label: '任务类型', props: { options: TASK_TYPE }}, | |||||
{ type: 'date', key: 'executionStartTime', label: '巡检时间', props: { | { type: 'date', key: 'executionStartTime', label: '巡检时间', props: { | ||||
type: 'datetime', | type: 'datetime', | ||||
valueFormat: 'yyyy-MM-dd HH:mm:ss', format: 'yyyy-MM-dd HH:mm:ss', | valueFormat: 'yyyy-MM-dd HH:mm:ss', format: 'yyyy-MM-dd HH:mm:ss', |
placeholder: '请选择任务状态', | placeholder: '请选择任务状态', | ||||
options: lineOptions | options: lineOptions | ||||
} | } | ||||
}, | |||||
{ | |||||
label: '任务类型', | |||||
key: 'type', | |||||
type: 'select', | |||||
props: { | |||||
placeholder: '请选择任务状态', | |||||
options: TASK_TYPE | |||||
} | |||||
} | } | ||||
// { | |||||
// label: '任务类型', | |||||
// key: 'type', | |||||
// type: 'select', | |||||
// props: { | |||||
// placeholder: '请选择任务状态', | |||||
// options: TASK_TYPE | |||||
// } | |||||
// } | |||||
] | ] | ||||
}) | }) | ||||
key: 'inspectionLineName', | key: 'inspectionLineName', | ||||
align: 'center' | align: 'center' | ||||
}, | }, | ||||
{ | |||||
title: '任务类型', | |||||
key: 'type', | |||||
align: 'center', | |||||
render(row) { | |||||
return h(TableTags, { | |||||
data: row.type, | |||||
filters: TASK_TYPE | |||||
}) | |||||
} | |||||
}, | |||||
// { | |||||
// title: '任务类型', | |||||
// key: 'type', | |||||
// align: 'center', | |||||
// render(row) { | |||||
// return h(TableTags, { | |||||
// data: row.type, | |||||
// filters: TASK_TYPE | |||||
// }) | |||||
// } | |||||
// }, | |||||
{ | { | ||||
title: '巡检时间', | title: '巡检时间', | ||||
key: 'executionStartTime', | key: 'executionStartTime', |