} | } | ||||
/** | /** | ||||
* @description: 获取任务详情 | |||||
* @description: 获取问题列表 | |||||
* @param {*} id 任务id | * @param {*} id 任务id | ||||
* @return {*} | * @return {*} | ||||
*/ | */ | ||||
params | params | ||||
}) | }) | ||||
} | } | ||||
/** | |||||
* @description: 获取问题列表 | |||||
* @param {*} params | |||||
* @return {*} | |||||
*/ | |||||
export function getDistributed(params) { | |||||
return request({ | |||||
url: '/question/distributed', | |||||
method: 'GET', | |||||
params | |||||
}) | |||||
} | |||||
/** | /** | ||||
* @description: 获取问题类型 | * @description: 获取问题类型 | ||||
* @return {*} | * @return {*} |
}, | }, | ||||
type: { | type: { | ||||
type: String, | type: String, | ||||
default: '' | |||||
default: 'look' | |||||
} | } | ||||
}, | }, | ||||
emits: {}, | emits: {}, | ||||
watch(() => props.data, (value) => { | watch(() => props.data, (value) => { | ||||
if (value) { | if (value) { | ||||
if (mapdata.value) { | if (mapdata.value) { | ||||
console.log('数据变化===============================') | |||||
removeVector(problemLayer.value) | |||||
if (problemLayer.value) { | |||||
removeVector(problemLayer.value) | |||||
} | |||||
getLayer(props.data) | getLayer(props.data) | ||||
} | } | ||||
} | } |
<template> | <template> | ||||
<n-card> | <n-card> | ||||
<div class="card__title"> | <div class="card__title"> | ||||
<p> | |||||
<p class="card__title--left">机场状态</p> | |||||
<p class="card__title--right"> | |||||
<n-form | <n-form | ||||
inline | inline | ||||
:label-width="80" | :label-width="80" | ||||
const getVideoOptions = computed(() => { | const getVideoOptions = computed(() => { | ||||
const row = data.airOptionsAll.find((item) => { return item.id === data.videoForm.airportId }) | const row = data.airOptionsAll.find((item) => { return item.id === data.videoForm.airportId }) | ||||
const live1 = 'https://live.play.t-aaron.com/live/THSBa_hd.m3u8' | |||||
const video1 = 'https://vod.play.t-aaron.com/af2f261d45fe4468bee5d4e501097405/53f0276aadc741909fd06c94484cd217-7184ea23b102c31c4a5e31d65206f539-fd.mp4' | |||||
const video2 = 'https://vod.play.t-aaron.com/408a38ee77ad4672b2b607e20a4e11d1/6d0d2ac3044a4992b4f2fe8563f75f20-0e1dfeb4f87ab08b10522d261f973f0d-fd.mp4' | |||||
return { | return { | ||||
inner: { | inner: { | ||||
id: 'video-inner', | id: 'video-inner', | ||||
width: '100%', | width: '100%', | ||||
height: '100%', | height: '100%', | ||||
// source: row?.internalMonitorUrl, | |||||
source: row?.id === 2 ? live1 : video2, | |||||
// source: row?.externalMonitorUrl, | |||||
source: 'http://101.43.84.72:8080/live/34020000001320000001@34020000001320000001.flv', | |||||
// source: row?.id === 2 ? live1 : video2, | |||||
isLive: true | isLive: true | ||||
} | } | ||||
// outer: { | // outer: { | ||||
line-height: 20px; | line-height: 20px; | ||||
display: flex; | display: flex; | ||||
align-items: center; | align-items: center; | ||||
justify-content: space-between; | |||||
margin-bottom: 15px; | margin-bottom: 15px; | ||||
flex-direction: row-reverse; | |||||
.n-select{ | |||||
width: 160px; | |||||
.card__title--left{ | |||||
font-size: 18px; | |||||
padding-left: 8px; | |||||
border-left: 4px solid rgba(24, 144, 255, 1); | |||||
} | |||||
.card__title--right{ | |||||
.n-select{ | |||||
width: 160px; | |||||
} | |||||
} | } | ||||
} | } | ||||
.card__video{ | .card__video{ |
} | } | ||||
function handleVideoChange(value) { | function handleVideoChange(value) { | ||||
// 1 | |||||
} | } | ||||
const getVideoOptions = computed(() => { | const getVideoOptions = computed(() => { |
<template> | <template> | ||||
<div class="question-container"> | |||||
<HeadSearch :info="search" @search="handleSearch" @reset="handleSearch" /> | |||||
<position-msg :data="dataList" :type="positionType" /> | |||||
<div> | |||||
<n-card> | |||||
<div class="question__container"> | |||||
<HeadSearch :info="search" @search="handleSearch" @reset="handleSearch" /> | |||||
<div class="question__position"> | |||||
<PositionMsg :data="questionList" /> | |||||
</div> | |||||
</div> | |||||
</n-card> | |||||
</div> | </div> | ||||
</template> | </template> | ||||
<script> | <script> | ||||
import { reactive, toRefs } from '@vue/reactivity' | |||||
import { reactive, toRefs, onMounted } from 'vue' | |||||
import search from './tools/search.js' | import search from './tools/search.js' | ||||
import HeadSearch from '@/components/Search/index.vue' | import HeadSearch from '@/components/Search/index.vue' | ||||
import PositionMsg from '@/components/PositionMsg/index.vue' | import PositionMsg from '@/components/PositionMsg/index.vue' | ||||
import { getDistributed } from '@/api/task/index.js' | |||||
export default { | export default { | ||||
name: 'QuestionDistribution', | name: 'QuestionDistribution', | ||||
components: { PositionMsg, HeadSearch }, | components: { PositionMsg, HeadSearch }, | ||||
setup() { | setup() { | ||||
const data = reactive({ | const data = reactive({ | ||||
search, | search, | ||||
dataList: [ | |||||
{ lng: '118.32002', lat: '32.345623' } | |||||
], | |||||
positionType: 'look' | |||||
questionList: [] | |||||
}) | |||||
async function handleSearch(searchs) { | |||||
let params = { ...searchs } | |||||
if (searchs?.time?.length) { | |||||
params = { | |||||
...searchs, | |||||
startTime: searchs.time[0], | |||||
endTime: searchs.time[1] | |||||
} | |||||
} | |||||
delete params.time | |||||
const res = await getDistributed(params) | |||||
if (res.code === 0) { | |||||
data.questionList = res.data | |||||
} | |||||
} | |||||
onMounted(() => { | |||||
handleSearch() | |||||
}) | }) | ||||
return { | return { | ||||
...toRefs(data) | |||||
...toRefs(data), | |||||
handleSearch | |||||
} | } | ||||
} | } | ||||
} | } | ||||
</script> | </script> | ||||
<style scoped lang='scss'> | <style scoped lang='scss'> | ||||
.question-container { | |||||
width: 100%; | |||||
height: 100%; | |||||
.n-card{ | |||||
height: calc(100vh - 80px); | |||||
.question__container { | |||||
height: 100%; | |||||
display: flex; | |||||
flex-direction: column; | |||||
.question__position{ | |||||
flex: 1; | |||||
} | |||||
} | |||||
} | } | ||||
</style> | </style> |
}, | }, | ||||
{ | { | ||||
label: '搜索任务', | label: '搜索任务', | ||||
key: 'name', | |||||
key: 'missionName', | |||||
props: { | props: { | ||||
placeholder: '请输入任务名称' | placeholder: '请输入任务名称' | ||||
} | } |
import { QUESTION_TYPE } from '@/utils/dictionary.js' | |||||
import TableImage from '@/components/DataTable/tools/Image.vue' | |||||
import TableTags from '@/components/DataTable/tools/Tags.vue' | |||||
import TableAction from '@/components/DataTable/tools/Action.vue' | |||||
import { h, ref, reactive } from 'vue' | |||||
/* 注册table */ | |||||
const tableRef = ref() | |||||
const searchParams = ref() | |||||
function handleSearch(params) { | |||||
searchParams.value = { ...params } | |||||
if (params?.time?.length) { | |||||
searchParams.value = { | |||||
startTime: params.time[0], | |||||
endTime: params.time[1] | |||||
} | |||||
} | |||||
delete searchParams.value.time | |||||
tableRef.value.reFetch({ searchParams }) | |||||
} | |||||
/* 位置 */ | |||||
function handlePositionDrawer(row) { | |||||
data.rowData = row | |||||
data.positionDrawer = true | |||||
} | |||||
const data = reactive({ | |||||
tableRef, | |||||
searchParams, | |||||
rowData: {}, | |||||
positionDrawer: false, | |||||
handleSearch, | |||||
columns: [ | |||||
{ | |||||
title: '序号', | |||||
key: 'key', | |||||
render: (_, index) => { | |||||
return `${index + 1}` | |||||
}, | |||||
align: 'center' | |||||
}, | |||||
{ | |||||
title: '问题类型', | |||||
key: 'type', | |||||
align: 'center', | |||||
render(row) { | |||||
return h(TableTags, { | |||||
data: row.type, | |||||
filters: QUESTION_TYPE | |||||
}) | |||||
} | |||||
}, | |||||
{ | |||||
title: '问题图片', | |||||
key: 'fileMarkerUrl', | |||||
align: 'center', | |||||
render(row) { | |||||
return h(TableImage, { | |||||
images: { | |||||
width: 36, | |||||
height: 36, | |||||
src: row.fileMarkerUrl | |||||
// previewDisabled: true | |||||
// onClick: handleImgPreview.bind(null, row) | |||||
} | |||||
}) | |||||
} | |||||
}, | |||||
{ | |||||
title: '经纬度', | |||||
key: 'name', | |||||
align: 'center', | |||||
render(row) { | |||||
return h(TableTags, { | |||||
data: [{ name: row.lng }, { name: row.lat }] | |||||
}) | |||||
} | |||||
}, | |||||
{ | |||||
title: '位置', | |||||
key: 'position', | |||||
align: 'center', | |||||
render(row) { | |||||
return h(TableAction, { | |||||
actions: [ | |||||
{ | |||||
label: '图片位置', | |||||
type: 'button', | |||||
props: { | |||||
type: 'primary', | |||||
text: true, | |||||
onClick: handlePositionDrawer.bind(null, row) | |||||
}, | |||||
auth: 'basic_list' | |||||
} | |||||
], | |||||
align: 'center' | |||||
}) | |||||
} | |||||
}, | |||||
{ | |||||
title: '备注', | |||||
key: 'note', | |||||
align: 'center' | |||||
}, | |||||
{ | |||||
title: '所属任务', | |||||
key: 'note', | |||||
align: 'center' | |||||
} | |||||
] | |||||
}) | |||||
export default data |
<template> | |||||
<n-drawer v-bind="getDrawerOptions" @update:show="handleDrawerColse"> | |||||
<n-drawer-content closable title="轨迹回放"> | |||||
<PositionMsg :data="getPostionOptions" /> | |||||
</n-drawer-content> | |||||
</n-drawer> | |||||
</template> | |||||
<script> | |||||
import PositionMsg from '@/components/PositionMsg/index.vue' | |||||
import { defineComponent, computed, reactive, toRefs } from 'vue' | |||||
export default defineComponent({ | |||||
name: 'LiveDrawer', | |||||
components: { PositionMsg }, | |||||
props: { | |||||
/* 可见 */ | |||||
visible: { | |||||
type: Boolean, | |||||
default: false | |||||
}, | |||||
/* 选中的数据 */ | |||||
data: { | |||||
type: Object, | |||||
default: () => {} | |||||
} | |||||
}, | |||||
emits: { | |||||
'update:visible': null | |||||
}, | |||||
setup(props, { emit }) { | |||||
const data = reactive({ | |||||
}) | |||||
/* 获取抽屉的信息 */ | |||||
const getDrawerOptions = computed(() => { | |||||
return { | |||||
show: props.visible, | |||||
width: '100%', | |||||
placement: 'right' | |||||
} | |||||
}) | |||||
const getPostionOptions = computed(() => { | |||||
return [props.data] | |||||
}) | |||||
function handleDrawerColse() { | |||||
emit('update:visible', false) | |||||
} | |||||
return { | |||||
...toRefs(data), | |||||
getDrawerOptions, | |||||
getPostionOptions, | |||||
handleDrawerColse | |||||
} | |||||
} | |||||
}) | |||||
</script> | |||||
<style scoped lang='scss'> | |||||
.n-button+.n-button{ | |||||
margin-left: 30px; | |||||
} | |||||
</style> |
</n-card> | </n-card> | ||||
</div> | </div> | ||||
<MapDrawer v-model:visible="mapDrawer" :data="rowData" /> | |||||
</template> | </template> | ||||
<script> | <script> | ||||
import search from './tools/search.js' | import search from './tools/search.js' | ||||
import HeadSearch from '@/components/Search/index.vue' | import HeadSearch from '@/components/Search/index.vue' | ||||
import DataTable from '@/components/DataTable/index.vue' | import DataTable from '@/components/DataTable/index.vue' | ||||
import MapDrawer from './components/MapDrawer.vue' | |||||
import { reactive, unref, toRefs } from 'vue' | import { reactive, unref, toRefs } from 'vue' | ||||
import { getQuestionList } from '@/api/task/index.js' | import { getQuestionList } from '@/api/task/index.js' | ||||
export default { | export default { | ||||
name: 'QuestionList', | name: 'QuestionList', | ||||
components: { HeadSearch, DataTable }, | |||||
components: { HeadSearch, DataTable, MapDrawer }, | |||||
setup() { | setup() { | ||||
const data = reactive({ | const data = reactive({ | ||||
search, | search, | ||||
...toRefs(table) | ...toRefs(table) | ||||
}) | }) | ||||
/** | /** | ||||
* @description: 加载表格数据 | * @description: 加载表格数据 | ||||
* @param {*} res | * @param {*} res |
searchParams.value = { ...params } | searchParams.value = { ...params } | ||||
if (params?.time?.length) { | if (params?.time?.length) { | ||||
searchParams.value = { | searchParams.value = { | ||||
...params, | |||||
startTime: params.time[0], | startTime: params.time[0], | ||||
endTime: params.time[1] | endTime: params.time[1] | ||||
} | } | ||||
/* 位置 */ | /* 位置 */ | ||||
function handlePositionDrawer(row) { | function handlePositionDrawer(row) { | ||||
data.rowData = row | data.rowData = row | ||||
data.positionDrawer = true | |||||
data.mapDrawer = true | |||||
} | } | ||||
const data = reactive({ | const data = reactive({ | ||||
tableRef, | tableRef, | ||||
searchParams, | searchParams, | ||||
rowData: {}, | rowData: {}, | ||||
positionDrawer: false, | |||||
mapDrawer: false, | |||||
handleSearch, | handleSearch, | ||||
columns: [ | columns: [ | ||||
}) | }) | ||||
} | } | ||||
}, | }, | ||||
{ | |||||
title: '所属任务', | |||||
key: 'missionName', | |||||
align: 'center' | |||||
}, | |||||
{ | { | ||||
title: '经纬度', | title: '经纬度', | ||||
key: 'name', | key: 'name', | ||||
title: '备注', | title: '备注', | ||||
key: 'note', | key: 'note', | ||||
align: 'center' | align: 'center' | ||||
}, | |||||
{ | |||||
title: '所属任务', | |||||
key: 'note', | |||||
align: 'center' | |||||
} | } | ||||
] | ] |
<script> | <script> | ||||
import BaseMap from './BaseMap.vue' | import BaseMap from './BaseMap.vue' | ||||
import { h, defineComponent, computed, reactive, toRefs } from 'vue' | |||||
import { defineComponent, computed, reactive, toRefs } from 'vue' | |||||
export default defineComponent({ | export default defineComponent({ | ||||
name: 'LiveDrawer', | name: 'LiveDrawer', |
}, | }, | ||||
setup(props, { emit }) { | setup(props, { emit }) { | ||||
getAirOptions() | getAirOptions() | ||||
if (props?.data?.id) { | |||||
getLineOptions(props.data.droneId) | |||||
} | |||||
const MODAL_TYPE = { | const MODAL_TYPE = { | ||||
'create': '新建任务', | 'create': '新建任务', | ||||
'preview': '任务详情', | 'preview': '任务详情', | ||||
show: props.visible, | show: props.visible, | ||||
title: MODAL_TYPE[props.type], | title: MODAL_TYPE[props.type], | ||||
width: 700, | width: 700, | ||||
negativeText: '取消', | |||||
positiveText: '确认' | |||||
negativeText: props.type !== 'preview' ? '取消' : '', | |||||
positiveText: props.type !== 'preview' ? '确认' : '' | |||||
} | } | ||||
}) | }) | ||||
watch(() => data.taskForm.airportId, | watch(() => data.taskForm.airportId, | ||||
(val) => { | (val) => { | ||||
const { airOptions } = getOptions() | |||||
const item = airOptions.value.find((item) => { return item.id === val }) | |||||
data.taskForm.inspectionLine = '' | data.taskForm.inspectionLine = '' | ||||
getLineOptions(val) | |||||
getLineOptions(item.droneId) | |||||
}) | }) | ||||
/** | /** | ||||
.n-date-picker{ | .n-date-picker{ | ||||
width: 100%; | width: 100%; | ||||
} | } | ||||
::v-deep(.n-date-picker--disabled){ | |||||
.n-input .n-input-wrapper .n-input__input { | |||||
.n-input__input-el{ | |||||
text-decoration-color: transparent !important; | |||||
} | |||||
} | |||||
} | |||||
</style> | </style> |
export const form = reactive({ | export const form = reactive({ | ||||
taskForm: { | taskForm: { | ||||
name: '', | |||||
inspectionType: '', | |||||
airportId: '', | |||||
inspectionLine: '', | |||||
type: '', | |||||
name: null, | |||||
inspectionType: null, | |||||
airportId: null, | |||||
inspectionLine: null, | |||||
type: null, | |||||
executionStartTime: null, | executionStartTime: null, | ||||
note: '' | |||||
note: null | |||||
}, | }, | ||||
taskRules: { | taskRules: { | ||||
name: [{ required: true, message: '请输入任务名称', trigger: 'blur' }], | name: [{ required: true, message: '请输入任务名称', trigger: 'blur' }], | ||||
export const getAirOptions = async function() { | export const getAirOptions = async function() { | ||||
const res = await airportList() | const res = await airportList() | ||||
airOptions.value = dataToSelect(res.data, { label: 'name', value: 'droneId' }) | |||||
airOptions.value = dataToSelect(res.data, { label: 'name', value: 'id' }) | |||||
} | } | ||||
// 获取角色列表 | // 获取角色列表 |
export const getAirOptions = async function() { | export const getAirOptions = async function() { | ||||
const res = await airportList() | const res = await airportList() | ||||
airOptions.value = dataToSelect(res.data, { label: 'name', value: 'droneId' }) | |||||
airOptions.value = dataToSelect(res.data, { label: 'name', value: 'id' }) | |||||
} | } | ||||
// 获取角色列表 | // 获取角色列表 | ||||
export const getLineOptions = async function(id) { | export const getLineOptions = async function(id) { | ||||
const res = await airportLine(id) | |||||
const item = airOptions.value.find((item) => { return item.id === id }) | |||||
const res = await airportLine(item.droneId) | |||||
lineOptions.value = dataToSelect(res.data, { label: 'name', value: 'id' }) | lineOptions.value = dataToSelect(res.data, { label: 'name', value: 'id' }) | ||||
} | } | ||||
<template> | <template> | ||||
<HeadSearch :info="search" /> | |||||
<HeadSearch :info="search" @search="handleSearch" @reset="handleSearch" /> | |||||
<DataTable | <DataTable | ||||
ref="tableRef" | ref="tableRef" | ||||
:columns="columns" | :columns="columns" | ||||
</template> | </template> | ||||
<template #toolbar> | <template #toolbar> | ||||
<n-button @click="handleReported"> | <n-button @click="handleReported"> | ||||
{{ isReported ? '修改并生成报告': '提交并生成报告' }} | |||||
{{ reportStatus ? '修改并生成报告': '提交并生成报告' }} | |||||
</n-button> | </n-button> | ||||
</template> | </template> | ||||
</DataTable> | </DataTable> | ||||
search, | search, | ||||
...toRefs(table), | ...toRefs(table), | ||||
pageData: [], | pageData: [], | ||||
isReported: props.data?.isReported || false | |||||
isReported: props.data?.reportStatus === 1 || false | |||||
}) | }) | ||||
/** | /** |