@@ -5,7 +5,7 @@ VITE_PUBLIC_PATH = '/' | |||
VITE_APP_USE_MOCK = false | |||
# proxy | |||
VITE_PROXY = [["/api","http://192.168.11.11:9011/api"]] | |||
VITE_PROXY = [["/api","http://192.168.11.11:9099/api"]] | |||
# base api | |||
VITE_APP_GLOB_BASE_API = '/api' |
@@ -3,6 +3,9 @@ import vue from '@vitejs/plugin-vue' | |||
import Components from 'unplugin-vue-components/vite' | |||
import { NaiveUiResolver } from 'unplugin-vue-components/resolvers' | |||
import { createSvgIconsPlugin } from 'vite-plugin-svg-icons' | |||
import { resolve } from 'path' | |||
import VueSetupExtend from 'vite-plugin-vue-setup-extend' | |||
import { unocss } from './unocss' | |||
@@ -15,6 +18,10 @@ export function createVitePlugins(viteEnv, isBuild) { | |||
Components({ | |||
resolvers: [NaiveUiResolver()] | |||
}), | |||
createSvgIconsPlugin({ | |||
iconDirs: [resolve(process.cwd(), 'src/assets/icon')], | |||
symbolId: 'icon-[dir]-[name]' | |||
}), | |||
VueSetupExtend(), | |||
unocss(), | |||
configHtmlPlugin(viteEnv, isBuild) |
@@ -9,6 +9,10 @@ | |||
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> | |||
<link rel="icon" href="/favicon.ico" /> | |||
<title><%= title %></title> | |||
<link rel="stylesheet" href="https://g.alicdn.com/de/prismplayer/2.9.21/skins/default/aliplayer-min.css" /> | |||
<script charset="utf-8" type="text/javascript" src="https://g.alicdn.com/de/prismplayer/2.9.21/aliplayer-h5-min.js"></script> | |||
</head> | |||
<body> | |||
<div id="app"></div> |
@@ -44,6 +44,7 @@ | |||
"vite": "^2.6.4", | |||
"vite-plugin-html": "^2.1.2", | |||
"vite-plugin-mock": "^2.9.6", | |||
"vite-plugin-svg-icons": "^2.0.1", | |||
"vite-plugin-vue-setup-extend": "^0.4.0" | |||
} | |||
} |
@@ -0,0 +1,49 @@ | |||
import { defAxios as request } from '@/utils/http' | |||
/** | |||
* @description: 获取巡检机场 | |||
* @return {*} | |||
*/ | |||
export function airportList(params) { | |||
return request({ | |||
url: '/inspection/airport', | |||
method: 'GET', | |||
params | |||
}) | |||
} | |||
/** | |||
* @description: 获取航线 | |||
* @return {*} | |||
*/ | |||
export function airportLine(id) { | |||
return request({ | |||
url: `/inspection/airport/line/${id}`, | |||
method: 'GET' | |||
}) | |||
} | |||
/** | |||
* @description: 获取机场天气 | |||
* @param {*} id 机场id | |||
* @return {*} | |||
*/ | |||
export function airportWeather(id) { | |||
return request({ | |||
url: `/inspection/airport/weather/${id}`, | |||
method: 'GET' | |||
}) | |||
} | |||
/** | |||
* @description: 获取飞行轨迹 | |||
* @param {*} id 机场id | |||
* @return {*} | |||
*/ | |||
export function airportTrack(id) { | |||
return request({ | |||
url: `/inspection/track/${id}`, | |||
method: 'GET' | |||
}) | |||
} | |||
@@ -1,14 +1,61 @@ | |||
import { defAxios as request } from '@/utils/http' | |||
/** | |||
* @description: 创建任务 | |||
* @param {*} id 任务id | |||
* @return {*} | |||
*/ | |||
export function createTask(data) { | |||
return request({ | |||
url: '/mission', | |||
method: 'POST', | |||
data | |||
}) | |||
} | |||
/** | |||
* @description: 获取任务列表 | |||
* @param {*} data | |||
* @param {*} params | |||
* @return {*} | |||
*/ | |||
export function getTaskList(data = {}) { | |||
export function getTaskList(params) { | |||
return request({ | |||
url: '/mission/page', | |||
method: 'get', | |||
data | |||
method: 'GET', | |||
params | |||
}) | |||
} | |||
/** | |||
* @description: 获取任务详情 | |||
* @param {*} id 任务id | |||
* @return {*} | |||
*/ | |||
export function getTaskDetail(id) { | |||
return request({ | |||
url: `/mission/${id}`, | |||
method: 'GET' | |||
}) | |||
} | |||
/** | |||
* @description: 删除任务 | |||
* @param {*} id 任务id | |||
* @return {*} | |||
*/ | |||
export function taskDelete(id) { | |||
return request({ | |||
url: `/mission/${id}`, | |||
method: 'DELETE' | |||
}) | |||
} | |||
/** | |||
* @description: 立即执行 | |||
* @param {*} id 任务id | |||
* @return {*} | |||
*/ | |||
export function implement(id) { | |||
return request({ | |||
url: `/inspection/mission/${id}`, | |||
method: 'PUT' | |||
}) | |||
} |
@@ -0,0 +1 @@ | |||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><defs><style>.b{fill:none;}</style></defs><g transform="translate(-72.592 -80.272)"><path class="a" d="M80.21,96.931a.434.434,0,0,1-.307-.741l3.836-3.837L79.9,88.517a.434.434,0,0,1,.614-.614l4.143,4.143a.433.433,0,0,1,0,.614L80.517,96.8A.433.433,0,0,1,80.21,96.931Z" transform="translate(0 0)"/><path class="a" d="M480.21,96.931a.434.434,0,0,1-.307-.741l3.836-3.837L479.9,88.517a.434.434,0,0,1,.614-.614l4.143,4.143a.434.434,0,0,1,0,.614L480.517,96.8A.433.433,0,0,1,480.21,96.931Z" transform="translate(-395.684 0)"/></g><rect class="b" width="24" height="24"/></svg> |
@@ -28,7 +28,11 @@ | |||
:pagination="pagination" | |||
@update:page="updatePage" | |||
@update:page-size="updatePageSize" | |||
/> | |||
> | |||
<template #empty> | |||
<slot name="empty" /> | |||
</template> | |||
</n-data-table> | |||
</div> | |||
</template> | |||
@@ -50,7 +50,10 @@ export default defineComponent({ | |||
const getActions = computed(() => { | |||
return (toRaw(props.actions) || []) | |||
.filter((action) => { | |||
return data.permissionList.includes(action.auth) || action.auth === '' | |||
if (!Object.keys(action).includes('show')) { | |||
action.show = Object.keys(action).includes('hidden') ? !action.hidden : true | |||
} | |||
return (data.permissionList.includes(action.auth) || action.auth === '') && action.show | |||
}) | |||
}) | |||
@@ -58,10 +58,10 @@ export default defineComponent({ | |||
const { filters } = unref(props) | |||
function getFilter(value) { | |||
const data = filters.find(item => { | |||
return item.key === value | |||
return item.value === value | |||
}) | |||
return data || { | |||
key: value, | |||
value: value, | |||
label: value | |||
} | |||
} |
@@ -0,0 +1,73 @@ | |||
<template> | |||
<div v-if="external" :style="styleExternalIcon" class="svg-external-icon svg-icon" v-bind="$attrs" /> | |||
<svg v-else :class="svgClass" aria-hidden="true" v-bind="$attrs"> | |||
<use :xlink:href="iconName" /> | |||
</svg> | |||
</template> | |||
<script> | |||
import { isExternal } from '@/utils/is.js' | |||
import { defineComponent, computed } from 'vue' | |||
export default defineComponent({ | |||
name: 'SvgIcon', | |||
props: { | |||
prefix: { | |||
type: String, | |||
default: 'icon' | |||
}, | |||
iconClass: { | |||
type: String, | |||
required: true | |||
}, | |||
className: { | |||
type: String, | |||
default: '' | |||
} | |||
}, | |||
setup(props, { emit }) { | |||
const external = computed(() => { | |||
return isExternal(props.iconClass) | |||
}) | |||
const iconName = computed(() => { | |||
return `#icon-${props.iconClass}` | |||
}) | |||
const svgClass = computed(() => { | |||
if (props.className) { | |||
return 'svg-icon ' + props.className | |||
} else { | |||
return 'svg-icon' | |||
} | |||
}) | |||
const styleExternalIcon = computed(() => { | |||
return { | |||
mask: `url(${props.iconClass}) no-repeat 50% 50%`, | |||
'-webkit-mask': `url(${props.iconClass}) no-repeat 50% 50%` | |||
} | |||
}) | |||
return { | |||
external, | |||
iconName, | |||
svgClass, | |||
styleExternalIcon | |||
} | |||
} | |||
}) | |||
</script> | |||
<style scoped> | |||
.svg-icon { | |||
width: 1em; | |||
height: 1em; | |||
vertical-align: -0.15em; | |||
fill: currentColor; | |||
overflow: hidden; | |||
} | |||
.svg-external-icon { | |||
background-color: currentColor; | |||
mask-size: cover!important; | |||
display: inline-block; | |||
} | |||
</style> |
@@ -0,0 +1,123 @@ | |||
<template> | |||
<div :id="getPlayerId" /> | |||
</template> | |||
<script> | |||
import { ref, computed, watch, onMounted, defineComponent } from 'vue' | |||
export default defineComponent({ | |||
name: 'VideoPlayer', | |||
props: { | |||
options: { | |||
type: Object, | |||
default: () => {} | |||
} | |||
}, | |||
emits: ['timeUpdate', 'video-status'], | |||
setup(props, { emit }) { | |||
const videoPlayer = ref() | |||
const hasInit = ref(false) | |||
const isSeek = ref(false) | |||
const toolComponent = Aliplayer.Component({ | |||
timeupdate(player, e) { | |||
const currentTime = player.getCurrentTime() | |||
const duration = player.getDuration() | |||
emit('timeUpdate', { | |||
status: isSeek.value || Number.isInteger(currentTime) ? 'skip' : 'palying', | |||
currentTime, | |||
duration | |||
}) | |||
}, | |||
ready(player, e) { | |||
const currentTime = player.getCurrentTime() | |||
const duration = player.getDuration() | |||
emit('video-status', { | |||
status: 'ready', | |||
currentTime, | |||
duration | |||
}) | |||
} | |||
}) | |||
const getPlayerId = computed(() => { | |||
return props.options?.id || 'player' | |||
}) | |||
function init() { | |||
const player = new Aliplayer({ | |||
id: 'player', | |||
width: '500px', | |||
height: '260px', | |||
autoplay: true, | |||
...props.options, | |||
components: [ | |||
toolComponent | |||
] | |||
}, function(player) { | |||
if (player.getOptions().autoplay) { | |||
player.mute() | |||
} | |||
}) | |||
videoPlayer.value = player | |||
player.on('startSeek', () => { | |||
isSeek.value = true | |||
}) | |||
player.on('completeSeek', () => { | |||
isSeek.value = false | |||
}) | |||
hasInit.value = true | |||
} | |||
function getTime() { | |||
return videoPlayer.value.getCurrentTime() | |||
} | |||
function seekTime(time) { | |||
videoPlayer.value.seek(time) | |||
} | |||
function playVideo() { | |||
videoPlayer.value.play() | |||
} | |||
function pauseVideo() { | |||
videoPlayer.value.pause() | |||
} | |||
function disposeVideo() { | |||
hasInit.value = false | |||
videoPlayer.value.dispose() | |||
} | |||
watch( | |||
() => props.options, | |||
(val) => { | |||
if (props.options.source && !hasInit.value) { | |||
init() | |||
} | |||
if (hasInit.value) { | |||
disposeVideo() | |||
init() | |||
} | |||
} | |||
) | |||
onMounted(() => { | |||
if (props.options.source && !hasInit.value) { | |||
init() | |||
} | |||
}) | |||
return { | |||
getPlayerId, | |||
getTime, | |||
seekTime, | |||
playVideo, | |||
pauseVideo, | |||
disposeVideo | |||
} | |||
} | |||
}) | |||
</script> | |||
<style> | |||
.prism-player .prism-ErrorMessage .prism-error-operation{ | |||
border-bottom: none; | |||
} | |||
.prism-player .prism-ErrorMessage .prism-error-operation a.prism-button.prism-button-refresh{ | |||
display: none; | |||
} | |||
.prism-player .prism-ErrorMessage .prism-detect-info.prism-center{ | |||
display: none; | |||
} | |||
</style> |
@@ -10,7 +10,7 @@ | |||
</n-layout> | |||
</n-layout> | |||
</n-layout> | |||
<div class="right_img">copyright©2022拓恒技术有限公司</div> | |||
<!-- <div class="right_img">copyright©2022拓恒技术有限公司</div> --> | |||
</n-space> | |||
</template> | |||
@@ -1,5 +1,6 @@ | |||
import '@/styles/index.scss' | |||
import 'uno.css' | |||
import 'virtual:svg-icons-register' | |||
import { createApp } from 'vue' | |||
import { setupRouter } from '@/router' |
@@ -14,7 +14,7 @@ export const basicRoutes = [ | |||
{ | |||
path: '/', | |||
component: Layout, | |||
redirect: '/home', | |||
redirect: '/dashboard', | |||
name: 'dashBoard', | |||
title: '工作台', | |||
meta: { | |||
@@ -22,7 +22,7 @@ export const basicRoutes = [ | |||
}, | |||
children: [ | |||
{ | |||
path: 'home', | |||
path: 'dashboard', | |||
title: '首页', | |||
component: Home, | |||
meta: { |
@@ -33,7 +33,7 @@ export default [ | |||
children: [ | |||
{ | |||
path: 'user', | |||
component: () => import('@/views/system/user/index.vue'), | |||
component: () => import('@/views/system-manage/user-manage/index.vue'), | |||
name: 'SystemUser', | |||
title: '用户管理', | |||
meta: { | |||
@@ -42,7 +42,7 @@ export default [ | |||
}, | |||
{ | |||
path: 'role', | |||
component: () => import('@/views/system/role/index.vue'), | |||
component: () => import('@/views/system-manage/role-manage/index.vue'), | |||
name: 'SystemRole', | |||
title: '角色管理', | |||
meta: { | |||
@@ -51,7 +51,7 @@ export default [ | |||
}, | |||
{ | |||
path: 'dept', | |||
component: () => import('@/views/system/dept/index.vue'), | |||
component: () => import('@/views/system-manage/department-manage/index.vue'), | |||
name: 'SystemDept', | |||
title: '部门管理', | |||
meta: { | |||
@@ -60,7 +60,7 @@ export default [ | |||
}, | |||
{ | |||
path: 'menu', | |||
component: () => import('@/views/system/menu/index.vue'), | |||
component: () => import('@/views/system-manage/menu-manage/index.vue'), | |||
name: 'SystemMenu', | |||
title: '菜单管理', | |||
meta: { |
@@ -1,17 +1,18 @@ | |||
export const TASK_STATUS = [ | |||
{ label: '待飞行', value: 0 }, | |||
{ label: '飞行中', value: 1 }, | |||
{ label: '飞行完成', value: 2 }, | |||
{ label: '飞行失败', value: 3 } | |||
{ label: '待飞行', value: 1 }, | |||
{ label: '飞行中', value: 2 }, | |||
{ label: '飞行失败', value: 3 }, | |||
{ label: '飞行完成', value: 4 } | |||
] | |||
export const TASK_MODE = [ | |||
{ label: '机场服务', value: 0 } | |||
{ label: '机场服务', value: 1 }, | |||
{ label: '人工巡检', value: 2 } | |||
] | |||
export const TASK_TYPE = [ | |||
{ label: '日常巡检', value: 0 }, | |||
{ label: '应急巡检', value: 1 } | |||
{ label: '日常巡检', value: 1 }, | |||
{ label: '应急巡检', value: 2 } | |||
] | |||
export const QUESTION_TYPE = [ |
@@ -46,6 +46,12 @@ export function setupInterceptor(service) { | |||
case -1: | |||
$message.error(response.data.msg) | |||
break | |||
case 10009: | |||
$message.error(response.data.msg) | |||
break | |||
case 500: | |||
$message.error(response.data.msg) | |||
break | |||
case 401: | |||
// 未登录(可能是token过期或者无效了) | |||
removeToken() |
@@ -0,0 +1,129 @@ | |||
<template> | |||
<n-card> | |||
<div class="card__title"> | |||
<p> | |||
<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" @change="getAirportInfo" /> | |||
</n-form-item> | |||
</n-form> | |||
</p> | |||
</div> | |||
<div class="card__video"> | |||
<div class="video__item"> | |||
<!-- <VideoPlayer :options="getVideoOptions.inner" /> --> | |||
</div> | |||
<div class="video__item"> | |||
<!-- <VideoPlayer :options="getVideoOptions.outer" /> --> | |||
</div> | |||
</div> | |||
</n-card> | |||
</template> | |||
<script> | |||
import { dataToSelect } from '@/utils/handleData.js' | |||
import { airportList, airportWeather, airportTrack } from '@/api/dashboard/index.js' | |||
import VideoPlayer from '@/components/VideoPlayer/index.vue' | |||
import { reactive, computed, toRefs } from 'vue' | |||
export default { | |||
name: 'TaskCard', | |||
components: { VideoPlayer }, | |||
setup() { | |||
const data = reactive({ | |||
videoForm: { | |||
airportId: null | |||
}, | |||
airOptions: [], | |||
airOptionsAll: [] | |||
}) | |||
/** | |||
* @description: 加载表格数据 | |||
* @param {*} res | |||
* @return {*} | |||
*/ | |||
const loadAirport = (async function() { | |||
const res = await airportList({ page: 1, limit: 60 }) | |||
if (res.code === 0) { | |||
data.airOptionsAll = res.data | |||
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 res = await airportWeather(id) | |||
if (res.code === 0) { | |||
// 1 | |||
} | |||
const res2 = await airportTrack(id) | |||
if (res2.code === 0) { | |||
// 1 | |||
} | |||
} | |||
const getVideoOptions = computed(() => { | |||
const row = data.airOptionsAll.find((item) => { return item.id === data.videoForm.airportId }) | |||
return { | |||
inner: { | |||
id: 'video-inner', | |||
width: '100%', | |||
height: '100%', | |||
source: row?.internalMonitorUrl, | |||
isLive: true | |||
}, | |||
outer: { | |||
id: 'video-outer', | |||
width: '100%', | |||
height: '100%', | |||
source: row?.externalMonitorUrl, | |||
isLive: true | |||
} | |||
} | |||
}) | |||
return { | |||
...toRefs(data), | |||
loadAirport, | |||
getAirportInfo, | |||
getVideoOptions | |||
} | |||
} | |||
} | |||
</script> | |||
<style scoped lang='scss'> | |||
.card__title{ | |||
line-height: 20px; | |||
display: flex; | |||
align-items: center; | |||
margin-bottom: 15px; | |||
flex-direction: row-reverse; | |||
.n-select{ | |||
width: 160px; | |||
} | |||
} | |||
.card__video{ | |||
display: flex; | |||
height: calc(100% - 55px); | |||
.video__item{ | |||
width: calc(50% - 10px); | |||
&:first-child{ | |||
margin-right: 20px | |||
} | |||
} | |||
} | |||
::v-deep(.n-form){ | |||
.n-form-item-feedback-wrapper{ | |||
display: none; | |||
} | |||
} | |||
</style> |
@@ -0,0 +1,117 @@ | |||
<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> | |||
<n-data-table | |||
:bordered="false" | |||
:single-column="true" | |||
:columns="columns" | |||
:data="tableData" | |||
:pagination="false" | |||
> | |||
<template #empty> | |||
无数据 | |||
</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: 'inspectionType', | |||
align: 'center' | |||
} | |||
] | |||
}) | |||
/** | |||
* @description: 加载表格数据 | |||
* @param {*} res | |||
* @return {*} | |||
*/ | |||
const loadDataTable = (async function() { | |||
const res = await getTaskList({ page: 1, limit: 6 }) | |||
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); | |||
} | |||
} | |||
} | |||
::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> |
@@ -0,0 +1,128 @@ | |||
<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" /> | |||
</n-form-item> | |||
<n-form-item label="回放选择:" path="taskId"> | |||
<n-select v-model:value="videoForm.taskId" :options="taskOptions" /> | |||
</n-form-item> | |||
</n-form> | |||
</p> | |||
</div> | |||
<div class="card__video"> | |||
<div class="video__item"> | |||
<!-- <VideoPlayer :options="getVideoOptions.origin" /> --> | |||
</div> | |||
<div class="video__item"> | |||
<!-- <VideoPlayer :options="getVideoOptions.analyse" /> --> | |||
</div> | |||
</div> | |||
</n-card> | |||
</template> | |||
<script> | |||
import { dataToSelect } from '@/utils/handleData.js' | |||
import { airportList } from '@/api/dashboard/index.js' | |||
import VideoPlayer from '@/components/VideoPlayer/index.vue' | |||
import { reactive, computed, toRefs } from 'vue' | |||
export default { | |||
name: 'TaskCard', | |||
components: { VideoPlayer }, | |||
setup() { | |||
const data = reactive({ | |||
videoForm: { | |||
airportId: 2, | |||
taskId: '' | |||
}, | |||
airOptionsAll: [], | |||
airOptions: [], | |||
taskOptions: [] | |||
}) | |||
/** | |||
* @description: 加载表格数据 | |||
* @param {*} res | |||
* @return {*} | |||
*/ | |||
const loadAirport = (async function() { | |||
const res = await airportList({ page: 1, limit: 60 }) | |||
if (res.code === 0) { | |||
data.airOptionsAll = res.data | |||
data.airOptions = dataToSelect(res.data, { label: 'name', value: 'id' }) | |||
data.videoForm.airportId = res.data[0].id | |||
} | |||
})() | |||
const getVideoOptions = computed(() => { | |||
const row = data.airOptionsAll.find((item) => { return item.id === data.videoForm.airportId }) | |||
return { | |||
origin: { | |||
id: 'video-origin', | |||
width: '100%', | |||
height: '100%', | |||
source: row?.internalMonitorUrl, | |||
isLive: true | |||
}, | |||
analyse: { | |||
id: 'video-analyse', | |||
width: '100%', | |||
height: '100%', | |||
source: row?.externalMonitorUrl, | |||
isLive: true | |||
} | |||
} | |||
}) | |||
return { | |||
...toRefs(data), | |||
loadAirport, | |||
getVideoOptions | |||
} | |||
} | |||
} | |||
</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: 160px; | |||
} | |||
} | |||
} | |||
.card__video{ | |||
display: flex; | |||
height: calc(100% - 55px); | |||
.video__item{ | |||
width: calc(50% - 10px); | |||
&:first-child{ | |||
margin-right: 20px | |||
} | |||
} | |||
} | |||
::v-deep(.n-form){ | |||
.n-form-item-feedback-wrapper{ | |||
display: none; | |||
} | |||
} | |||
</style> |
@@ -1,13 +1,23 @@ | |||
<template> | |||
<div> | |||
工作台 | |||
<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() { | |||
@@ -20,6 +30,27 @@ export default { | |||
} | |||
</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> | |||
@@ -1,14 +1,60 @@ | |||
<template> | |||
<div> | |||
问题列表 | |||
<n-card> | |||
<HeadSearch :info="search" @search="handleSearch" @reset="handleSearch" /> | |||
<DataTable | |||
ref="tableRef" | |||
:columns="columns" | |||
:request="loadDataTable" | |||
:row-key="(row) => row.id" | |||
size="large" | |||
/> | |||
</n-card> | |||
</div> | |||
</template> | |||
<script> | |||
import table from './tools/table.js' | |||
import search from './tools/search.js' | |||
import HeadSearch from '@/components/Search/index.vue' | |||
import DataTable from '@/components/DataTable/index.vue' | |||
import { reactive, unref, toRefs } from 'vue' | |||
import { getTaskList } from '@/api/task/index.js' | |||
export default { | |||
name: 'QuestionList', | |||
name: 'TaskAll', | |||
components: { HeadSearch, DataTable }, | |||
setup() { | |||
const data = reactive({ | |||
search, | |||
...toRefs(table) | |||
}) | |||
/** | |||
* @description: 加载表格数据 | |||
* @param {*} res | |||
* @return {*} | |||
*/ | |||
const loadDataTable = async(res) => { | |||
const _params = { | |||
...unref(data.searchParams), | |||
...res | |||
} | |||
return await getTaskList(_params) | |||
} | |||
function handleModal() { | |||
data.rowData = null | |||
data.modalType = 'create' | |||
data.modalShow = true | |||
} | |||
return { | |||
...toRefs(data), | |||
loadDataTable, | |||
handleModal | |||
} | |||
} | |||
} | |||
@@ -0,0 +1,22 @@ | |||
import { reactive } from 'vue' | |||
const data = reactive([ | |||
{ | |||
label: '选择时间', | |||
key: 'code', | |||
type: 'date', | |||
props: { | |||
type: 'daterange' | |||
} | |||
}, | |||
{ | |||
label: '搜索任务', | |||
key: 'name', | |||
props: { | |||
placeholder: '请输入任务名称' | |||
} | |||
} | |||
]) | |||
export default data | |||
@@ -0,0 +1,217 @@ | |||
import { TASK_MODE, TASK_TYPE, TASK_STATUS } from '@/utils/dictionary.js' | |||
import TableTags from '@/components/DataTable/tools/Tags.vue' | |||
import TableAction from '@/components/DataTable/tools/Action.vue' | |||
import { h, ref, reactive } from 'vue' | |||
import { taskDelete } from '@/api/task/index.js' | |||
/* 注册table */ | |||
const tableRef = ref() | |||
const searchParams = ref() | |||
function handleSearch(params) { | |||
searchParams.value = { ...params } | |||
tableRef.value.reFetch({ searchParams }) | |||
} | |||
/** | |||
* @description: 获取数据及操作 | |||
* @param {*} row 单行数据 | |||
* @param {*} type 操作类型 create:创建,preview:预览,edit:编辑 | |||
* @return {*} | |||
*/ | |||
function getRowData(row, type) { | |||
data.rowData = row | |||
data.modalType = type | |||
data.modalShow = true | |||
} | |||
function handleRowDelete(row) { | |||
taskDelete(row.id) | |||
.then(res => { | |||
if (res.code === 0) { | |||
handleSearch() | |||
} | |||
}) | |||
} | |||
function handleImplement(row) { | |||
data.rowData = row | |||
} | |||
/* 直播 */ | |||
function handleTaskLive(row) { | |||
data.rowData = row | |||
data.liveDrawer = true | |||
} | |||
/* 回放 */ | |||
function handleTaskDemand(row) { | |||
data.rowData = row | |||
data.demandDrawer = true | |||
} | |||
/* 问题核实 */ | |||
function handleTaskVerify(row) { | |||
data.rowData = row | |||
data.verifyDrawer = true | |||
} | |||
const data = reactive({ | |||
tableRef, | |||
searchParams, | |||
rowData: {}, | |||
modalType: 'create', | |||
modalShow: false, | |||
liveDrawer: false, | |||
demandDrawer: false, | |||
verifyDrawer: false, | |||
handleSearch, | |||
columns: [ | |||
{ | |||
title: '任务标号', | |||
key: 'code', | |||
align: 'center' | |||
}, | |||
{ | |||
title: '任务名称', | |||
key: 'name', | |||
align: 'center' | |||
}, | |||
{ | |||
title: '巡检方式', | |||
key: 'inspectionType', | |||
align: 'center', | |||
render(row) { | |||
return h(TableTags, { | |||
data: row.inspectionType, | |||
filters: TASK_MODE | |||
}) | |||
} | |||
}, | |||
{ | |||
title: '巡检机场', | |||
key: 'airportName', | |||
align: 'center' | |||
}, | |||
{ | |||
title: '巡检路线', | |||
key: 'inspectionLineName', | |||
align: 'center' | |||
}, | |||
{ | |||
title: '任务类型', | |||
key: 'type', | |||
align: 'center', | |||
render(row) { | |||
return h(TableTags, { | |||
data: row.type, | |||
filters: TASK_TYPE | |||
}) | |||
} | |||
}, | |||
{ | |||
title: '巡检时间', | |||
key: 'executionStartTime', | |||
align: 'center' | |||
}, | |||
{ | |||
title: '状态', | |||
key: 'status', | |||
align: 'center', | |||
render(row) { | |||
return h(TableTags, { | |||
data: row.status, | |||
filters: TASK_STATUS | |||
}) | |||
} | |||
}, | |||
{ | |||
title: '操作', | |||
align: 'center', | |||
width: 150, | |||
fixed: 'right', | |||
render(row) { | |||
return h(TableAction, { | |||
actions: [ | |||
{ | |||
label: '详情', | |||
type: 'button', | |||
props: { | |||
type: 'primary', | |||
text: true, | |||
onClick: getRowData.bind(null, row, 'preview') | |||
}, | |||
auth: 'basic_list' | |||
}, | |||
{ | |||
label: '删除', | |||
type: 'popconfirm', | |||
tip: '是否删除该数据?', | |||
props: { | |||
onClick: handleRowDelete.bind(null, row) | |||
}, | |||
ButtonProps: { | |||
text: true, | |||
type: 'primary' | |||
}, | |||
auth: 'basic_list' | |||
}, | |||
{ | |||
label: '立即执行', | |||
type: 'popconfirm', | |||
tip: '是否立即开始执行任务?', | |||
props: { | |||
onClick: handleImplement.bind(null, row) | |||
}, | |||
ButtonProps: { | |||
text: true, | |||
type: 'primary' | |||
}, | |||
auth: 'basic_list', | |||
show: row.status === 1 | |||
}, | |||
{ | |||
label: '直播', | |||
type: 'button', | |||
props: { | |||
type: 'primary', | |||
text: true, | |||
onClick: handleTaskLive.bind(null, row) | |||
}, | |||
auth: 'basic_list', | |||
show: row.status === 2 | |||
}, | |||
{ | |||
label: '轨迹', | |||
type: 'button', | |||
props: { | |||
type: 'primary', | |||
text: true, | |||
onClick: handleTaskDemand.bind(null, row) | |||
}, | |||
auth: 'basic_list', | |||
show: row.status === 4 | |||
}, | |||
{ | |||
label: '问题核实', | |||
type: 'button', | |||
props: { | |||
type: 'primary', | |||
text: true, | |||
onClick: handleTaskVerify.bind(null, row) | |||
}, | |||
auth: 'basic_list', | |||
show: row.status !== 1 | |||
} | |||
], | |||
align: 'center' | |||
}) | |||
} | |||
} | |||
] | |||
}) | |||
export default data |
@@ -97,8 +97,8 @@ export default defineComponent({ | |||
if (params.id) { | |||
editDept(params).then(res => { | |||
if (res.code === 0) { | |||
handleClose() | |||
emit('reload') | |||
handleClose() | |||
} | |||
}).catch(e => { | |||
console.log(e) | |||
@@ -106,8 +106,8 @@ export default defineComponent({ | |||
} else { | |||
addDept(params).then(res => { | |||
if (res.code === 0) { | |||
handleClose() | |||
emit('reload') | |||
handleClose() | |||
} | |||
}) | |||
} |
@@ -122,6 +122,7 @@ export default defineComponent({ | |||
editMenu(params).then(res => { | |||
if (res.code === 0) { | |||
emit('reload') | |||
handleClose() | |||
} | |||
}).catch(e => { | |||
console.log(e) | |||
@@ -129,8 +130,8 @@ export default defineComponent({ | |||
} else { | |||
addMenu(params).then(res => { | |||
if (res.code === 0) { | |||
handleClose() | |||
emit('reload') | |||
handleClose() | |||
} | |||
}) | |||
} |
@@ -1,3 +1,4 @@ | |||
import { MENU_TYPE, MENU_STATUS, MENU_VISIBLE } from '@/utils/dictionary.js' | |||
import { h, ref, reactive } from 'vue' | |||
import TableTags from '@/components/DataTable/tools/Tags.vue' | |||
import TableAction from '@/components/DataTable/tools/Action.vue' | |||
@@ -60,16 +61,7 @@ const data = reactive({ | |||
render(row) { | |||
return h(TableTags, { | |||
data: row.type, | |||
filters: [ | |||
{ | |||
key: 0, | |||
label: '菜单' | |||
}, | |||
{ | |||
key: 1, | |||
label: '节点' | |||
} | |||
] | |||
filters: MENU_TYPE | |||
}) | |||
} | |||
}, | |||
@@ -93,16 +85,7 @@ const data = reactive({ | |||
render(row) { | |||
return h(TableTags, { | |||
data: row.status, | |||
filters: [ | |||
{ | |||
key: 1, | |||
label: '在用' | |||
}, | |||
{ | |||
key: 2, | |||
label: '停用' | |||
} | |||
] | |||
filters: MENU_STATUS | |||
}) | |||
} | |||
}, | |||
@@ -120,16 +103,7 @@ const data = reactive({ | |||
render(row) { | |||
return h(TableTags, { | |||
data: row.hide, | |||
filters: [ | |||
{ | |||
key: 1, | |||
label: '可见' | |||
}, | |||
{ | |||
key: 2, | |||
label: '不可见' | |||
} | |||
] | |||
filters: MENU_VISIBLE | |||
}) | |||
} | |||
}, |
@@ -83,8 +83,8 @@ export default defineComponent({ | |||
function handleConfirm() { | |||
savePermission({ roleId: props.data.id, menuIds: data.menuIds }).then(res => { | |||
if (res.code === 0) { | |||
handleClose() | |||
emit('reload') | |||
handleClose() | |||
} | |||
}).catch(e => { | |||
console.log(e) |
@@ -19,7 +19,7 @@ | |||
<n-form-item :label="item.label" :path="item.key"> | |||
<n-input v-if="item.type === 'input'" v-model:value="taskForm[item.key]" v-bind="item.props" /> | |||
<n-select v-if="item.type === 'select'" v-model:value="taskForm[item.key]" v-bind="item.props" /> | |||
<n-date-picker v-if="item.type === 'date'" v-model:value="taskForm[item.key]" v-bind="item.props" /> | |||
<n-date-picker v-if="item.type === 'date'" v-model:formatted-value="taskForm[item.key]" v-bind="item.props" /> | |||
</n-form-item> | |||
</template> | |||
</n-form> | |||
@@ -28,9 +28,10 @@ | |||
</template> | |||
<script> | |||
import { defineComponent, computed, ref, reactive, toRefs } from 'vue' | |||
import { form, getAirOptions, getLineOptions, getOptions } from '../tools/form.js' | |||
import { defineComponent, computed, watch, ref, reactive, toRefs } from 'vue' | |||
import Modal from '@/components/Modal/index.vue' | |||
import form from '../tools/form.js' | |||
import { createTask } from '@/api/task/index.js' | |||
export default defineComponent({ | |||
name: 'UserModal', | |||
components: { Modal }, | |||
@@ -50,18 +51,25 @@ export default defineComponent({ | |||
}, | |||
emits: { | |||
'update:visible': null, | |||
'done': null | |||
'reload': null | |||
}, | |||
setup(props, { emit }) { | |||
getAirOptions() | |||
const MODAL_TYPE = { | |||
'create': '新建任务', | |||
'preview': '任务详情', | |||
'update': '编辑任务' | |||
} | |||
const formRef = ref() | |||
const { taskForm, taskRules } = form | |||
const data = reactive({ | |||
...toRefs(form), | |||
...props.data, | |||
taskForm: { | |||
...taskForm, | |||
...props.data | |||
}, | |||
taskRules: { | |||
...taskRules | |||
}, | |||
disabled: props.type === 'preview' | |||
}) | |||
/* 获取弹窗的属性 */ | |||
@@ -81,6 +89,12 @@ export default defineComponent({ | |||
} | |||
}) | |||
watch(() => data.taskForm.airportId, | |||
(val) => { | |||
data.taskForm.inspectionLine = '' | |||
getLineOptions(val) | |||
}) | |||
/** | |||
* @description: 保存&编辑 | |||
* @return {*} | |||
@@ -88,14 +102,25 @@ export default defineComponent({ | |||
const handleConfirm = () => { | |||
formRef.value?.validate((errors) => { | |||
if (!errors) { | |||
const { airOptions, lineOptions } = getOptions() | |||
const airportInfo = airOptions.value.find((item) => { return (item.value === data.taskForm.airportId) }) | |||
const airLineInfo = lineOptions.value.find((item) => { return (item.value === data.taskForm.inspectionLine) }) | |||
const params = { | |||
...data.taskForm | |||
...data.taskForm, | |||
airportName: airportInfo.label, | |||
inspectionLineName: airLineInfo.label | |||
} | |||
if (params.id) { | |||
// 1 | |||
} else { | |||
/* 新增 */ | |||
// 1 | |||
createTask(params) | |||
.then(res => { | |||
if (res.code === 0) { | |||
emit('reload') | |||
handleClose() | |||
} | |||
}) | |||
} | |||
} else { | |||
$message.error('请先完成校验') |
@@ -1,7 +1,7 @@ | |||
<template> | |||
<div> | |||
<n-card> | |||
<HeadSearch :info="search" /> | |||
<HeadSearch :info="search" @search="handleSearch" @reset="handleSearch" /> | |||
<DataTable | |||
ref="tableRef" | |||
:columns="columns" | |||
@@ -27,7 +27,7 @@ | |||
</div> | |||
<!-- 新增、编辑弹窗 --> | |||
<TaskModal v-if="modalShow" v-model:visible="modalShow" :type="modalType" :data="rowData" /> | |||
<TaskModal v-if="modalShow" v-model:visible="modalShow" :type="modalType" :data="rowData" @reload="handleSearch" /> | |||
<!-- 直播抽屉 --> | |||
<LiveDrawer v-model:visible="liveDrawer" :data="rowData" /> | |||
<!-- 轨迹回放 --> | |||
@@ -46,7 +46,7 @@ import TaskModal from './components/TaskModal.vue' | |||
import LiveDrawer from './components/LiveDrawer.vue' | |||
import DemandDrawer from './components/DemandDrawer.vue' | |||
import VerifyDrawer from './components/VerifyDrawer.vue' | |||
import { h, unref, ref, toRefs, reactive } from 'vue' | |||
import { reactive, unref, toRefs } from 'vue' | |||
import { getTaskList } from '@/api/task/index.js' | |||
export default { | |||
@@ -65,8 +65,10 @@ export default { | |||
*/ | |||
const loadDataTable = async(res) => { | |||
const _params = { | |||
...unref(data.searchParams), | |||
...res | |||
} | |||
if (_params.status === 'all') _params.status = '' | |||
return await getTaskList(_params) | |||
} | |||
@@ -1,33 +1,94 @@ | |||
import { reactive } from 'vue' | |||
import { ref, reactive } from 'vue' | |||
import { TASK_MODE, TASK_TYPE } from '@/utils/dictionary.js' | |||
import { airportList, airportLine } from '@/api/dashboard/index.js' | |||
import { dataToSelect } from '@/utils/handleData.js' | |||
const data = reactive({ | |||
const airOptions = ref([]) | |||
const lineOptions = ref([]) | |||
function disableTime(ts) { | |||
const DATE = new Date().getDate() | |||
const HOURS = new Date().getHours() | |||
const MINUTES = new Date().getMinutes() | |||
const SECONDS = new Date().getSeconds() | |||
const tDate = new Date(ts).getDate() | |||
const tHours = new Date(ts).getHours() | |||
const tMinutes = new Date(ts).getMinutes() | |||
return { | |||
isHourDisabled: (hour) => { | |||
return tDate === DATE && hour < HOURS | |||
}, | |||
isMinuteDisabled: (minute) => { | |||
if (tDate === DATE) { | |||
if (tHours < HOURS) { | |||
return true | |||
} else { | |||
return minute < MINUTES | |||
} | |||
} else { | |||
return false | |||
} | |||
}, | |||
isSecondDisabled: (second) => { | |||
if (tDate === DATE) { | |||
if (tHours < HOURS) { | |||
return true | |||
} else if (tMinutes < MINUTES) { | |||
return true | |||
} else { | |||
return second < SECONDS | |||
} | |||
} else { | |||
return false | |||
} | |||
// return tDate === DATE && tHours <= HOURS && tMinutes <= MINUTES && second < SECONDS | |||
} | |||
} | |||
} | |||
export const form = reactive({ | |||
taskForm: { | |||
name: '', | |||
name2: '', | |||
name3: '', | |||
name4: '', | |||
name5: '', | |||
name6: null, | |||
name7: '' | |||
inspectionType: '', | |||
airportId: '', | |||
inspectionLine: '', | |||
type: '', | |||
executionStartTime: null, | |||
note: '' | |||
}, | |||
taskRules: { | |||
name: [{ required: true, message: '请输入任务名称', trigger: 'blur' }], | |||
name2: [{ required: true, type: 'number', message: '请选择巡检方式', trigger: 'blur' }], | |||
name3: [{ required: true, type: 'number', message: '请选择巡检机场', trigger: 'blur' }], | |||
name4: [{ required: true, type: 'number', message: '请选择巡检路线', trigger: 'blur' }], | |||
name5: [{ required: true, type: 'number', message: '请选择任务类型', trigger: 'blur' }], | |||
name6: [{ required: true, type: 'date', message: '请选择巡检时间', trigger: ['blur', 'change'] }] | |||
inspectionType: [{ required: true, type: 'number', message: '请选择巡检方式', trigger: 'blur' }], | |||
airportId: [{ required: true, type: 'number', message: '请选择巡检机场', trigger: 'blur' }], | |||
inspectionLine: [{ required: true, type: 'number', message: '请选择巡检路线', trigger: 'blur' }], | |||
type: [{ required: true, type: 'number', message: '请选择任务类型', trigger: 'blur' }], | |||
executionStartTime: [{ required: true, type: 'date', message: '请选择巡检时间', trigger: ['blur', 'change'] }] | |||
}, | |||
formItem: [ | |||
{ type: 'input', key: 'name', label: '任务名称' }, | |||
{ type: 'select', key: 'name2', label: '巡检方式', props: { options: TASK_MODE }}, | |||
{ type: 'select', key: 'name3', label: '巡检机场', props: { options: [] }}, | |||
{ type: 'select', key: 'name4', label: '巡检路线', props: { options: [] }}, | |||
{ type: 'select', key: 'name5', label: '任务类型', props: { options: TASK_TYPE }}, | |||
{ type: 'date', key: 'name6', label: '巡检时间', props: { type: 'datetime' }}, | |||
{ type: 'input', key: 'name7', label: '备注', props: { type: 'textarea', autosize: { minRows: 3, maxRows: 3 }}} | |||
{ type: 'select', key: 'inspectionType', label: '巡检方式', props: { options: TASK_MODE }}, | |||
{ type: 'select', key: 'airportId', label: '巡检机场', props: { options: airOptions }}, | |||
{ type: 'select', key: 'inspectionLine', label: '巡检路线', props: { options: lineOptions }}, | |||
{ type: 'select', key: 'type', label: '任务类型', props: { options: TASK_TYPE }}, | |||
{ type: 'date', key: 'executionStartTime', label: '巡检时间', props: { type: 'datetime', valueFormat: 'yyyy-MM-dd HH:mm:ss', format: 'yyyy-MM-dd HH:mm:ss', isDateDisabled: (ts) => { return ts < (Date.now() - 24 * 60 * 60 * 1000) }, isTimeDisabled: disableTime }}, | |||
{ type: 'input', key: 'note', label: '备注', props: { type: 'textarea', autosize: { minRows: 3, maxRows: 3 }}} | |||
] | |||
}) | |||
export default data | |||
export const getAirOptions = async function() { | |||
const res = await airportList() | |||
airOptions.value = dataToSelect(res.data, { label: 'name', value: 'droneId' }) | |||
} | |||
// 获取角色列表 | |||
export const getLineOptions = async function(id) { | |||
const res = await airportLine(id) | |||
lineOptions.value = dataToSelect(res.data, { label: 'name', value: 'id' }) | |||
} | |||
export const getOptions = function() { | |||
return { | |||
airOptions, | |||
lineOptions | |||
} | |||
} |
@@ -31,7 +31,7 @@ const data = reactive([ | |||
}, | |||
{ | |||
label: '巡检机场', | |||
key: 'plain', | |||
key: 'airportId', | |||
type: 'select', | |||
props: { | |||
placeholder: '请选择任务状态', | |||
@@ -44,7 +44,7 @@ const data = reactive([ | |||
}, | |||
{ | |||
label: '巡检路线', | |||
key: 'route', | |||
key: 'inspectionLine', | |||
type: 'select', | |||
props: { | |||
placeholder: '请选择任务状态', | |||
@@ -60,9 +60,7 @@ const data = reactive([ | |||
value: 0, | |||
props: { | |||
placeholder: '请选择任务状态', | |||
options: TASK_TYPE, | |||
onUpdateValue: () => { | |||
} | |||
options: TASK_TYPE | |||
} | |||
} | |||
]) |
@@ -1,6 +1,17 @@ | |||
// import TableTags from '@/components/DataTable/tools/Tags.vue' | |||
import { TASK_MODE, TASK_TYPE, TASK_STATUS } from '@/utils/dictionary.js' | |||
import TableTags from '@/components/DataTable/tools/Tags.vue' | |||
import TableAction from '@/components/DataTable/tools/Action.vue' | |||
import { h, reactive } from 'vue' | |||
import { h, ref, reactive } from 'vue' | |||
import { taskDelete, implement } from '@/api/task/index.js' | |||
/* 注册table */ | |||
const tableRef = ref() | |||
const searchParams = ref() | |||
function handleSearch(params) { | |||
searchParams.value = { ...params } | |||
tableRef.value.reFetch({ searchParams }) | |||
} | |||
/** | |||
* @description: 获取数据及操作 | |||
@@ -15,11 +26,21 @@ function getRowData(row, type) { | |||
} | |||
function handleRowDelete(row) { | |||
taskDelete(row.id) | |||
.then(res => { | |||
if (res.code === 0) { | |||
handleSearch() | |||
} | |||
}) | |||
} | |||
function handleImplement(row) { | |||
data.rowData = row | |||
implement(row.id) | |||
.then(res => { | |||
if (res.code === 0) { | |||
handleSearch() | |||
} | |||
}) | |||
} | |||
/* 直播 */ | |||
@@ -41,20 +62,20 @@ function handleTaskVerify(row) { | |||
} | |||
const data = reactive({ | |||
tableRef, | |||
searchParams, | |||
rowData: {}, | |||
modalType: 'create', | |||
modalShow: false, | |||
liveDrawer: false, | |||
demandDrawer: false, | |||
verifyDrawer: false, | |||
handleSearch, | |||
columns: [ | |||
{ | |||
title: '任务标号', | |||
key: 'name', | |||
key: 'code', | |||
align: 'center' | |||
}, | |||
{ | |||
@@ -64,33 +85,51 @@ const data = reactive({ | |||
}, | |||
{ | |||
title: '巡检方式', | |||
key: 'name', | |||
align: 'center' | |||
key: 'inspectionType', | |||
align: 'center', | |||
render(row) { | |||
return h(TableTags, { | |||
data: row.inspectionType, | |||
filters: TASK_MODE | |||
}) | |||
} | |||
}, | |||
{ | |||
title: '巡检机场', | |||
key: 'name', | |||
key: 'airportName', | |||
align: 'center' | |||
}, | |||
{ | |||
title: '巡检路线', | |||
key: 'name', | |||
key: 'inspectionLineName', | |||
align: 'center' | |||
}, | |||
{ | |||
title: '任务类型', | |||
key: 'name', | |||
align: 'center' | |||
key: 'type', | |||
align: 'center', | |||
render(row) { | |||
return h(TableTags, { | |||
data: row.type, | |||
filters: TASK_TYPE | |||
}) | |||
} | |||
}, | |||
{ | |||
title: '巡检时间', | |||
key: 'name', | |||
key: 'executionStartTime', | |||
align: 'center' | |||
}, | |||
{ | |||
title: '状态', | |||
key: 'name', | |||
align: 'center' | |||
key: 'status', | |||
align: 'center', | |||
render(row) { | |||
return h(TableTags, { | |||
data: row.status, | |||
filters: TASK_STATUS | |||
}) | |||
} | |||
}, | |||
{ | |||
@@ -135,7 +174,8 @@ const data = reactive({ | |||
text: true, | |||
type: 'primary' | |||
}, | |||
auth: 'basic_list' | |||
auth: 'basic_list', | |||
show: row.status === 1 | |||
}, | |||
{ | |||
label: '直播', | |||
@@ -145,7 +185,8 @@ const data = reactive({ | |||
text: true, | |||
onClick: handleTaskLive.bind(null, row) | |||
}, | |||
auth: 'basic_list' | |||
auth: 'basic_list', | |||
show: row.status === 2 | |||
}, | |||
{ | |||
label: '轨迹', | |||
@@ -155,7 +196,8 @@ const data = reactive({ | |||
text: true, | |||
onClick: handleTaskDemand.bind(null, row) | |||
}, | |||
auth: 'basic_list' | |||
auth: 'basic_list', | |||
show: row.status === 4 | |||
}, | |||
{ | |||
label: '问题核实', | |||
@@ -165,7 +207,8 @@ const data = reactive({ | |||
text: true, | |||
onClick: handleTaskVerify.bind(null, row) | |||
}, | |||
auth: 'basic_list' | |||
auth: 'basic_list', | |||
show: row.status !== 1 | |||
} | |||
], | |||
align: 'center' |