* @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:获取机场详细信息 | * @description:获取机场详细信息 | ||||
* @param id 机场id | * @param id 机场id | ||||
*/ | */ | ||||
export function getAirportInfo (data) { | |||||
export function getAirportInfo(data) { | |||||
return request({ | return request({ | ||||
url: `/index/getAirportDetail`, | url: `/index/getAirportDetail`, | ||||
method: 'POST', | method: 'POST', | ||||
* @param page 页数 | * @param page 页数 | ||||
* @param limit 每页显示数 | * @param limit 每页显示数 | ||||
*/ | */ | ||||
export function getMissionList (data) { | |||||
export function getMissionList(data) { | |||||
return request({ | return request({ | ||||
url: `/index/getMissionList`, | url: `/index/getMissionList`, | ||||
method: 'POST', | method: 'POST', | ||||
data | |||||
data, | |||||
hideMessage: true | |||||
}) | }) | ||||
} | } | ||||
/** | /** | ||||
* @description:获取问题多选类型 | * @description:获取问题多选类型 | ||||
* | * | ||||
*/ | */ | ||||
export function getQuestionType () { | |||||
export function getQuestionType() { | |||||
return request({ | return request({ | ||||
url: `/question/type`, | url: `/question/type`, | ||||
method: 'GET' | method: 'GET' | ||||
/** | /** | ||||
* @description:获取问题列表数据 | * @description:获取问题列表数据 | ||||
*/ | */ | ||||
export function getQuestionList (data) { | |||||
export function getQuestionList(data) { | |||||
return request({ | return request({ | ||||
url: `/index/getQuestionList`, | url: `/index/getQuestionList`, | ||||
method: 'POST', | method: 'POST', |
}, | }, | ||||
{ | { | ||||
title: '编辑人', | title: '编辑人', | ||||
key: 'updateUser', | |||||
key: 'updateUserName', | |||||
align: 'center' | align: 'center' | ||||
}, | }, | ||||
{ | { |
}, | }, | ||||
{ | { | ||||
title: '编辑人', | title: '编辑人', | ||||
key: 'updateUser', | |||||
key: 'updateUserName', | |||||
align: 'center' | align: 'center' | ||||
}, | }, | ||||
{ | { |
cameraName: [{ required: true, message: '请输入设备名称', trigger: 'blur' }], | cameraName: [{ required: true, message: '请输入设备名称', trigger: 'blur' }], | ||||
cameraType: [{ required: true, message: '请选择设备机型', type: 'number', trigger: 'blur' }], | cameraType: [{ required: true, message: '请选择设备机型', type: 'number', trigger: 'blur' }], | ||||
customPos: [{ key: 'custom', required: true, message: '请输入经纬度', trigger: ['blur', 'change'] }], | customPos: [{ key: 'custom', required: true, message: '请输入经纬度', trigger: ['blur', 'change'] }], | ||||
flvUrl: [{ required: true, message: '请输入摄像头地址', trigger: 'blur', pattern: /^https:\/\/(([a-zA-Z0-9_-])+(\.)?)*(:\d+)?(\/((\.)?(\?)?=?&?[a-zA-Z0-9_-](\?)?)*)*$/i }] | |||||
flvUrl: [{ required: true, message: '请输入摄像头地址', trigger: 'blur' }] | |||||
// pattern: /^https:\/\/(([a-zA-Z0-9_-])+(\.)?)*(:\d+)?(\/((\.)?(\?)?=?&?[a-zA-Z0-9_-](\?)?)*)*$/i | |||||
}, | }, | ||||
formItem: [ | formItem: [ | ||||
{ type: 'input', key: 'cameraName', label: '设备名称', props: { maxlength: '20', placeholder: '请输入设备名称', clearable: true }}, | { type: 'input', key: 'cameraName', label: '设备名称', props: { maxlength: '20', placeholder: '请输入设备名称', clearable: true }}, | ||||
{ type: 'select', key: 'cameraType', label: '设备机型', props: { options: MONITOR_OPTIONS, placeholder: '请选择设备机型' }}, | { type: 'select', key: 'cameraType', label: '设备机型', props: { options: MONITOR_OPTIONS, placeholder: '请选择设备机型' }}, | ||||
{ type: 'customPos', key: 'customPos', label: '安装位置' }, | { type: 'customPos', key: 'customPos', label: '安装位置' }, | ||||
{ type: 'input', key: 'flvUrl', label: '摄像头地址', props: { maxlength: '20', placeholder: '请输入https://', clearable: true }}, | |||||
{ type: 'input', key: 'flvUrl', label: '摄像头地址', props: { placeholder: '请输入摄像头地址', clearable: true }}, | |||||
{ type: 'input', key: 'remark', label: '备注', props: { type: 'textarea', autosize: { maxlength: '200', minRows: 3, maxRows: 3 }}} | { type: 'input', key: 'remark', label: '备注', props: { type: 'textarea', autosize: { maxlength: '200', minRows: 3, maxRows: 3 }}} | ||||
] | ] | ||||
}) | }) |
}, | }, | ||||
{ | { | ||||
title: '编辑人', | title: '编辑人', | ||||
key: 'updateUser', | |||||
key: 'updateUserName', | |||||
align: 'center', | align: 'center', | ||||
width: 160 | width: 160 | ||||
}, | }, |
<template> | |||||
<div class="map__entend"> | |||||
<div v-for="(item,index) in extendList" :key="index" class="extend__container" @click="handleClick(index)"> | |||||
<img :src="selectedTab === index ? `/src/assets/images/${item.selected.path}.png` : `/src/assets/images/${item.path}.png`" alt=""> | |||||
<p :style="{color: selectedTab === index ? item.selected.color : '#eee'}">{{ item.name }}</p> | |||||
</div> | |||||
<div v-if="showPatrol" class="portal__modal"> | |||||
<p class="portal__title"> | |||||
<span :class="{'selected': portalTab ==='task'}" @click="handleTabChage('task')">任务</span> | |||||
<span :class="{'selected': portalTab ==='ques'}" @click="handleTabChage('ques')">问题</span> | |||||
</p> | |||||
<div v-show="portalTab ==='task'" class="portal__container"> | |||||
<div class="container__table"> | |||||
<ul> | |||||
<li v-for="(item,index) in taskList" :key="index"> | |||||
<span>{{ formatDate(item.executionStartTime) }}</span> | |||||
<span class="table__name">{{ item.name }}</span> | |||||
<span>{{ statusList[item.status] }}</span> | |||||
<n-popconfirm | |||||
v-if="item.status == 1" | |||||
> | |||||
<template #trigger> | |||||
<span class="table__operate">执行</span> | |||||
</template> | |||||
是否立即开始执行任务? | |||||
</n-popconfirm> | |||||
<span v-else class="table__operate live">直播</span> | |||||
</li> | |||||
</ul> | |||||
</div> | |||||
<div v-show="pageTotal>taskParams.limit" class="container__page"> | |||||
<n-pagination | |||||
v-model:page="taskParams.page" | |||||
v-model:page-size="taskParams.limit" | |||||
v-model:item-count="pageTotal" | |||||
:page-slot="8" | |||||
@update:page="handlePageChange" | |||||
/> | |||||
</div> | |||||
</div> | |||||
<div v-show="portalTab ==='ques'" class="portal__container"> | |||||
<div> | |||||
<n-date-picker | |||||
v-model:value="times" | |||||
format="yyyy-MM-dd" | |||||
value-format="yyyy-MM-dd" | |||||
type="daterange" | |||||
:is-date-disabled="disablePreviousDate" | |||||
@update:formatted-value="handleDateChange" | |||||
/> | |||||
</div> | |||||
<div class="container__checkbox"> | |||||
<n-checkbox-group | |||||
v-model:value="checkedType" | |||||
@update:value="handleRadioChange" | |||||
> | |||||
<div v-for="(item, index) in QUESTION_TYPE" :key="index"> | |||||
<n-checkbox | |||||
:value="item.content" | |||||
:label="item.content" | |||||
style="color: #ffffff" | |||||
/> | |||||
</div> | |||||
</n-checkbox-group> | |||||
</div> | |||||
</div> | |||||
</div> | |||||
</div> | |||||
</template> | |||||
<script> | |||||
import { reactive, toRefs } from 'vue' | |||||
import { startOfDay } from 'date-fns/esm' | |||||
import { getMissionList, getQuestionList } from '@/api/dashboard/index.js' | |||||
import { formatDate } from '@/utils/index.js' | |||||
import { QUESTION_TYPE } from '@/utils/dictionary.js' | |||||
export default { | |||||
name: 'MapExtend', | |||||
setup() { | |||||
const data = reactive({ | |||||
selectedTab: 0, | |||||
extendList: [ | |||||
{ 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' }} | |||||
], | |||||
showPatrol: false, | |||||
portalTab: 'task' | |||||
}) | |||||
const task = reactive({ | |||||
taskList: [], | |||||
taskParams: { | |||||
page: 1, | |||||
limit: 10 | |||||
}, | |||||
pageTotal: 1, | |||||
statusList: { | |||||
1: '待执行', | |||||
2: '执行中' | |||||
} | |||||
}) | |||||
const ques = reactive({ | |||||
times: [Date.now() - 7 * 24 * 3600000, Date.now()], | |||||
disablePreviousDate(ts, type, range) { | |||||
const d = 864e5 | |||||
if (type === 'start' && range !== null) { | |||||
return startOfDay(range[1]).valueOf() - startOfDay(ts).valueOf() >= d * 8 || ts > Date.now() | |||||
} | |||||
if (type === 'end' && range !== null) { | |||||
return startOfDay(ts).valueOf() - startOfDay(range[0]).valueOf() >= d * 8 || ts > Date.now() | |||||
} | |||||
return ts > Date.now() | |||||
}, | |||||
checkedType: QUESTION_TYPE.value?.map((item) => item.content) || null, | |||||
QUESTION_TYPE | |||||
}) | |||||
const handleClick = (index) => { | |||||
data.selectedTab = index | |||||
if (index === 1) { | |||||
if (!data.showPatrol) { | |||||
queryTaskList() | |||||
} | |||||
data.showPatrol = true | |||||
} | |||||
} | |||||
const queryTaskList = async() => { | |||||
const res = await getMissionList(task.taskParams) | |||||
if (res.code === 0) { | |||||
task.taskList = res.data.records | |||||
task.pageTotal = res.data.total | |||||
} | |||||
} | |||||
/** | |||||
* @description: | |||||
* @return {*} | |||||
*/ | |||||
const handleTabChage = (type) => { | |||||
data.portalTab = type | |||||
} | |||||
/** | |||||
* @description: | |||||
* @return {*} | |||||
*/ | |||||
const handlePageChange = () => { | |||||
queryTaskList() | |||||
} | |||||
const handleDateChange = (value) => { | |||||
console.log(ques.times) | |||||
} | |||||
const handleRadioChange = async() => { | |||||
const params = { | |||||
startTime: ques.times[0], | |||||
endTime: ques.times[1] | |||||
} | |||||
const res = await getQuestionList(params) | |||||
} | |||||
return { | |||||
...toRefs(data), | |||||
...toRefs(task), | |||||
...toRefs(ques), | |||||
handleClick, | |||||
queryTaskList, | |||||
formatDate, | |||||
handleTabChage, | |||||
handlePageChange, | |||||
handleDateChange, | |||||
handleRadioChange | |||||
} | |||||
} | |||||
} | |||||
</script> | |||||
<style scoped lang='scss'> | |||||
.map__entend{ | |||||
display: flex; | |||||
position: relative; | |||||
} | |||||
.extend__container{ | |||||
display: flex; | |||||
flex-direction: column; | |||||
justify-content: space-around; | |||||
align-items: center; | |||||
width: 66px; | |||||
height: 66px; | |||||
opacity: 1; | |||||
border-radius: 3px; | |||||
background: rgba(0, 0, 0, 0.7); | |||||
margin-right: 15px; | |||||
cursor: pointer; | |||||
img{ | |||||
width: 30px; | |||||
height: 30px; | |||||
} | |||||
p{ | |||||
font-size: 14px; | |||||
text-align: center; | |||||
color: #eee; | |||||
} | |||||
} | |||||
.portal__modal { | |||||
position: absolute; | |||||
width: 400px; | |||||
height: 428px; | |||||
top: 100px; | |||||
border-radius: 1px; | |||||
background: rgba(0, 0, 0, 1); | |||||
padding: 0 5px 5px; | |||||
animation: scale-up-tr 0.4s cubic-bezier(0.390, 0.575, 0.565, 1.000) both; | |||||
.portal__title{ | |||||
display: flex; | |||||
align-items: center; | |||||
line-height: 35px; | |||||
span{ | |||||
flex: 1; | |||||
text-align: center; | |||||
font-size: 16px; | |||||
color: #eee; | |||||
cursor: pointer; | |||||
&.selected{ | |||||
color: #63acff, | |||||
} | |||||
} | |||||
} | |||||
.portal__container{ | |||||
width: 100%; | |||||
height: calc(100% - 35px); | |||||
padding: 10px; | |||||
background: #2c2c2c; | |||||
.container__table{ | |||||
height: 330px; | |||||
color: #eeeeee; | |||||
li{ | |||||
line-height: 32px; | |||||
font-size: 14px; | |||||
display: flex; | |||||
align-items: center; | |||||
justify-content: space-between; | |||||
.table__name{ | |||||
width: 140px; | |||||
white-space: nowrap; | |||||
overflow: hidden; | |||||
text-overflow: ellipsis; | |||||
} | |||||
.table__operate{ | |||||
cursor: pointer; | |||||
color: #27e024; | |||||
&.live{ | |||||
color: #4f92ff; | |||||
} | |||||
} | |||||
} | |||||
} | |||||
} | |||||
} | |||||
::v-deep(.container__page){ | |||||
.n-pagination{ | |||||
.n-pagination-item { | |||||
color: #ffffff; | |||||
} | |||||
.n-checkbox__label { | |||||
color: #ffffff; | |||||
} | |||||
.n-pagination-item--button{ | |||||
background: transparent; | |||||
&:hover{ | |||||
color: #ffffff; | |||||
} | |||||
} | |||||
} | |||||
} | |||||
::v-deep(.container__checkbox){ | |||||
margin: 15px 0 0 5px; | |||||
.n-checkbox__label{ | |||||
color: #ffffff; | |||||
} | |||||
} | |||||
@keyframes scale-up-tr { | |||||
0% { | |||||
transform: scale(0.5); | |||||
transform-origin: 100% 0%; | |||||
} | |||||
100% { | |||||
transform: scale(1); | |||||
transform-origin: 100% 0%; | |||||
} | |||||
} | |||||
</style> |
nar[n].fraction.push(arr[i]) | nar[n].fraction.push(arr[i]) | ||||
} | } | ||||
} | } | ||||
console.log(nar) | |||||
// 添加问题图层 | // 添加问题图层 | ||||
initProblemType() | initProblemType() | ||||
addproblemLayer(nar) | addproblemLayer(nar) |
<template> | <template> | ||||
<div> | |||||
<div class="basic"> | |||||
<OneMap /> | <OneMap /> | ||||
<!-- <Extend class="extend" /> --> | |||||
</div> | </div> | ||||
</template> | </template> | ||||
<script> | <script> | ||||
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' | |||||
export default { | export default { | ||||
name: 'HomePage', | name: 'HomePage', | ||||
components: { OneMap }, | |||||
components: { OneMap, Extend }, | |||||
setup(props) { | setup(props) { | ||||
const router = useRouter() | const router = useRouter() | ||||
function toSystem() { | function toSystem() { | ||||
border-radius: 10px; | border-radius: 10px; | ||||
} | } | ||||
} | } | ||||
.extend{ | |||||
position: relative; | |||||
z-index: 999; | |||||
width:fit-content; | |||||
} | |||||
</style> | </style> | ||||