Browse Source

task

tags/v1.0.0^2
zhangtao 2 years ago
parent
commit
d28442dfa2
12 changed files with 702 additions and 37 deletions
  1. +48
    -2
      src/components/Modal/index.vue
  2. +21
    -17
      src/components/Search/index.vue
  3. +15
    -0
      src/utils/dictionary.js
  4. +1
    -1
      src/views/login/index.vue
  5. +59
    -0
      src/views/task-manage/all-task/components/DemandDrawer.vue
  6. +59
    -0
      src/views/task-manage/all-task/components/LiveDrawer.vue
  7. +128
    -0
      src/views/task-manage/all-task/components/TaskModal.vue
  8. +59
    -0
      src/views/task-manage/all-task/components/VerifyDrawer.vue
  9. +52
    -15
      src/views/task-manage/all-task/index.vue
  10. +33
    -0
      src/views/task-manage/all-task/tools/form.js
  11. +54
    -2
      src/views/task-manage/all-task/tools/search.js
  12. +173
    -0
      src/views/task-manage/all-task/tools/table.js

+ 48
- 2
src/components/Modal/index.vue View File

@@ -1,5 +1,6 @@
<template>
<n-modal
ref="modalRef"
v-bind="getModalOptions"
:style="`width:${getModalOptions.width}px`"
:title="options.title"
@@ -12,7 +13,7 @@

<script>

import { defineComponent, computed } from 'vue'
import { defineComponent, computed, ref } from 'vue'
export default defineComponent({
name: 'CardDialogModal',
props: {
@@ -28,11 +29,12 @@ export default defineComponent({
}
},
setup(props, { emit }) {
const modalRef = ref(null)
const getModalOptions = computed(() => {
return {
...props.options,
width: props.options.width || 600,
preset: props.options.preset || 'dialog',
preset: props.options.preset || 'card',
showIcon: !!props.options.showIcon
}
})
@@ -43,7 +45,46 @@ export default defineComponent({
const handleClose = function() {
emit('onClose', true)
}

// setTimeout(() => {
// const dialogHeaderEl = document.querySelector('.n-card-header')
// const dragDom = document.querySelector('.n-modal')
// dragDom.style.overflow = 'auto'
// dialogHeaderEl.style.cursor = 'move'
// const sty = dragDom.currentStyle || window.getComputedStyle(dragDom, null)
// const moveDown = (e) => {
// // 鼠标按下,计算当前元素距离可视区的距离
// const disX = e.clientX - dialogHeaderEl.offsetLeft
// const disY = e.clientY - dialogHeaderEl.offsetTop
// // 获取到的值带px 正则匹配替换
// let styL, styT
// // 注意在ie中 第一次获取到的值为组件自带50% 移动之后赋值为px
// if (sty.left.includes('%')) {
// styL = +document.body.clientWidth * (+sty.left.replace(/\%/g, '') / 100)
// styT = +document.body.clientHeight * (+sty.top.replace(/\%/g, '') / 100)
// } else {
// styL = +sty.left.replace(/\px/g, '')
// styT = +sty.top.replace(/\px/g, '')
// }

// document.onmousemove = function(e) {
// // 计算移动的距离
// const l = e.clientX - disX
// const t = e.clientY - disY
// // 移动当前元素
// dragDom.style.left = `${l + styL}px`
// dragDom.style.top = `${t + styT}px`
// }
// document.onmouseup = function(e) {
// document.onmousemove = null
// document.onmouseup = null
// }
// }
// dialogHeaderEl.onmousedown = moveDown
// })

return {
modalRef,
getModalOptions,
handleConfirm,
handleClose
@@ -53,4 +94,9 @@ export default defineComponent({
</script>

<style scoped lang='scss'>
::v-deep(.n-scrollbar-content){
&:first-child{
display: none;
}
}
</style>

+ 21
- 17
src/components/Search/index.vue View File

@@ -2,22 +2,15 @@
<div>
<n-form ref="formRef" v-bind="getFormOptions">
<template v-for="(item, index) in getFormOptions.info" :key="`${index}-${item.label}`">
<n-form-item v-if="['input'].includes(item.type) || !item.type" :label="item.label">
<n-input v-model:value="getFormOptions.form[item.key]" v-bind="item.props" />
</n-form-item>
<n-form-item v-if="['select'].includes(item.type) " :label="item.label">
<n-select v-model:value="getFormOptions.form[item.key]" v-bind="item.props" />
</n-form-item>
<n-form-item v-if="['area'].includes(item.type) " :label="item.label">
<AreaCascader :ref="el=>{itemRefs[item.refIndex] = el}" v-model:value="getFormOptions.form[item.key]" v-bind="item.props" @selectd="handleSelect" />
</n-form-item>
<n-form-item v-if="['date'].includes(item.type) " :label="item.label">
<n-date-picker v-model="getFormOptions.form[item.key]" v-bind="item.props" />
<n-form-item :class="{'hidden-item': index > showItemNum}" :label="item.label">
<n-input v-if="['input'].includes(item.type) || !item.type" v-model:value="getFormOptions.form[item.key]" v-bind="item.props" />
<n-select v-if="['select'].includes(item.type)" v-model:value="getFormOptions.form[item.key]" v-bind="item.props" />
<AreaCascader v-if="['area'].includes(item.type)" :ref="el=>{itemRefs[item.refIndex] = el}" v-model:value="getFormOptions.form[item.key]" v-bind="item.props" @selectd="handleSelect" />
<n-date-picker v-if="['date'].includes(item.type)" v-model="getFormOptions.form[item.key]" v-bind="item.props" />
</n-form-item>
</template>
<slot name="expand" />
<n-form-item class="form__button">
<n-button @click="handleSearch">查询</n-button>
<n-button type="primary" @click="handleSearch">查询</n-button>
<n-button @click="handleReset">重置</n-button>
<n-button
v-if="showButton"
@@ -30,7 +23,7 @@
</template>

<script>
import { computed, ref, unref } from 'vue'
import { computed, ref, unref, watch } from 'vue'
import { NForm } from 'naive-ui'
import AreaCascader from '@/components/AreaCascader/index.vue'
export default {
@@ -45,7 +38,7 @@ export default {
},
emits: ['search', 'reset'],
setup(props, { emit }) {
const showItemNum = ref(3)
const showItemNum = ref(30)
const len = ref(props.info.length - 1)
const itemRefs = ref([])
const showButton = ref(!!(showItemNum.value < len.value))
@@ -53,7 +46,8 @@ export default {
/* 初始化搜索表单信息 */
function initForm() {
Object.keys(form.value).forEach((key) => {
form.value[key] = null
const index = unref(props).info.findIndex((item) => item.key === key)
form.value[key] = (props).info[index].value || null
})
itemRefs.value.forEach((item) => {
item.clearValue()
@@ -66,14 +60,21 @@ export default {
}
}
const getFormOptions = computed(() => {
props.info.forEach((item) => {
form.value[item.key] = item.value || null
})
return {
form: unref(form),
labelWidth: 'auto',
labelPlacement: 'left',
inline: true,
info: [...unref(props).info]
info: [...props.info]
}
})
watch(() => props.info, (value) => {
console.log(value)
})

function handleSearch() {
emit('search', getFormOptions.value.form)
}
@@ -112,6 +113,9 @@ export default {
.n-cascader{
width: 200px;
}
&.hidden-item{
display: none;
}
transition: all 10s;
}
.form__button{

+ 15
- 0
src/utils/dictionary.js View File

@@ -0,0 +1,15 @@
export const TASK_STATUS = [
{ label: '待飞行', value: 0 },
{ label: '飞行中', value: 1 },
{ label: '飞行完成', value: 2 },
{ label: '飞行失败', value: 3 }
]

export const TASK_MODE = [
{ label: '机场服务', value: 0 }
]

export const TASK_TYPE = [
{ label: '日常巡检', value: 0 },
{ label: '应急巡检', value: 1 }
]

+ 1
- 1
src/views/login/index.vue View File

@@ -104,7 +104,7 @@ export default {
}

/* 调用store中的方法,登录以及存储token和用户信息 */
const res = await userStore.getLoginToken(this.loginForm)
const res = await userStore.getLoginToken(data.loginForm)
if (res.code === 0) {
const toPath = decodeURIComponent((route.query?.redirect || '/'))
route.path === '/login' ? router.replace('/') : router.replace(toPath)

+ 59
- 0
src/views/task-manage/all-task/components/DemandDrawer.vue View File

@@ -0,0 +1,59 @@
<template>
<n-drawer v-bind="getDrawerOptions" @update:show="handleDrawerColse">
<n-drawer-content closable title="轨迹回放">
轨迹回放
</n-drawer-content>
</n-drawer>
</template>

<script>
import { h, defineComponent, computed, reactive, toRefs } from 'vue'

export default defineComponent({
name: 'LiveDrawer',
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'
}
})
function handleDrawerColse() {
emit('update:visible', false)
}

return {
...toRefs(data),
getDrawerOptions,
handleDrawerColse
}
}
})
</script>

<style scoped lang='scss'>
.n-button+.n-button{
margin-left: 30px;
}
</style>

+ 59
- 0
src/views/task-manage/all-task/components/LiveDrawer.vue View File

@@ -0,0 +1,59 @@
<template>
<n-drawer v-bind="getDrawerOptions" @update:show="handleDrawerColse">
<n-drawer-content closable title="飞行直播">
飞行直播
</n-drawer-content>
</n-drawer>
</template>

<script>
import { h, defineComponent, computed, reactive, toRefs } from 'vue'

export default defineComponent({
name: 'LiveDrawer',
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'
}
})
function handleDrawerColse() {
emit('update:visible', false)
}

return {
...toRefs(data),
getDrawerOptions,
handleDrawerColse
}
}
})
</script>

<style scoped lang='scss'>
.n-button+.n-button{
margin-left: 30px;
}
</style>

+ 128
- 0
src/views/task-manage/all-task/components/TaskModal.vue View File

@@ -0,0 +1,128 @@
<template>
<Modal
:options="getModalOptions"
:on-positive-click="handleConfirm"
:on-negative-click="handleClose"
:on-close="handleClose"
>
<template #Context>
<n-form
ref="formRef"
:model="taskForm"
:rules="taskRules"
:label-width="80"
label-placement="left"
require-mark-placement="left"
:disabled="disabled"
>
<template v-for="(item,index) in getFormOptions" :key="index">
<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-form-item>
</template>
</n-form>
</template>
</Modal>
</template>

<script>
import { defineComponent, computed, ref, unref, reactive, toRefs } from 'vue'
import Modal from '@/components/Modal/index.vue'
import form from '../tools/form.js'
export default defineComponent({
name: 'UserModal',
components: { Modal },
props: {
visible: {
type: Boolean,
default: false
},
type: {
type: String,
default: 'create'
},
data: {
type: Object,
default: () => null
}
},
emits: {
'update:visible': null,
'done': null
},
setup(props, { emit }) {
const MODAL_TYPE = {
'create': '新建任务',
'preview': '任务详情',
'update': '编辑任务'
}
const formRef = ref()
const data = reactive({
...toRefs(form),
...props.data,
disabled: props.type === 'preview'
})
/* 获取弹窗的属性 */
const getModalOptions = computed(() => {
return {
show: props.visible,
title: MODAL_TYPE[props.type],
width: 700,
negativeText: '取消',
positiveText: '确认'
}
})

const getFormOptions = computed(() => {
return {
...form.formItem
}
})

/**
* @description: 保存&编辑
* @return {*}
*/
const handleConfirm = () => {
formRef.value?.validate((errors) => {
if (!errors) {
const params = {
...data.taskForm
}
if (params.id) {
// 1
} else {
/* 新增 */
// 1
}
} else {
$message.error('请先完成校验')
}
})
return false
}

/* 关闭弹窗 */
const handleClose = () => {
emit('update:visible', false)
}

return {
...toRefs(data),
formRef,
getModalOptions,
getFormOptions,
handleConfirm,
handleClose
}
}

})
</script>
<style scoped lang='scss'>
.n-date-picker{
width: 100%;
}
</style>

+ 59
- 0
src/views/task-manage/all-task/components/VerifyDrawer.vue View File

@@ -0,0 +1,59 @@
<template>
<n-drawer v-bind="getDrawerOptions" @update:show="handleDrawerColse">
<n-drawer-content closable title="问题核实">
问题核实
</n-drawer-content>
</n-drawer>
</template>

<script>
import { h, defineComponent, computed, reactive, toRefs } from 'vue'

export default defineComponent({
name: 'LiveDrawer',
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'
}
})
function handleDrawerColse() {
emit('update:visible', false)
}

return {
...toRefs(data),
getDrawerOptions,
handleDrawerColse
}
}
})
</script>

<style scoped lang='scss'>
.n-button+.n-button{
margin-left: 30px;
}
</style>

+ 52
- 15
src/views/task-manage/all-task/index.vue View File

@@ -1,24 +1,18 @@
<template>
<div>
<n-card>
<headSearch :info="search">
<template #expand>
<n-form-item label="巡检机场">
<n-date-picker />
</n-form-item>
</template>
</headSearch>
<!-- <data-table
<headSearch :info="search" />
<data-table
ref="tableRef"
:columns="columns"
:data="data"
:row-key="(row) => row.id"
:request="loadDataTable"
size="large"
@update:checked-row-keys="handleCheck"
>
<!-- :request="loadDataTable" -->
<template #tableTitle>
<n-button type="primary" @click="handleModal"> 新建 </n-button>
<n-popconfirm
<!-- <n-popconfirm
negative-text="取消"
positive-text="确认"
@positive-click="deleteComplex"
@@ -27,23 +21,66 @@
<n-button type="primary"> 删除 </n-button>
</template>
确认要删除选中数据吗?
</n-popconfirm>
</n-popconfirm> -->
</template>
</data-table> -->
</data-table>
</n-card>
</div>

<!-- 新增、编辑弹窗 -->
<TaskModal v-if="modalShow" v-model:visible="modalShow" :type="modalType" :data="rowData" />
<!-- 直播抽屉 -->
<LiveDrawer v-model:visible="liveDrawer" :data="rowData" />
<!-- 轨迹回放 -->
<DemandDrawer v-model:visible="demandDrawer" :data="rowData" />
<!-- 问题核实 -->
<VerifyDrawer v-model:visible="verifyDrawer" :data="rowData" />

</template>

<script>
import headSearch from '@/components/Search/index.vue'
import table from './tools/table.js'
import search from './tools/search.js'
import dataTable from '@/components/DataTable/index.vue'
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'

export default {
name: 'TaskAll',
components: { headSearch, dataTable },
components: { headSearch, dataTable, TaskModal, LiveDrawer, DemandDrawer, VerifyDrawer },
setup() {
return {
const data = reactive({
...toRefs(table),
data: [{}],
search
})

/**
* @description: 加载表格数据
* @param {*} res
* @return {*}
*/
const loadDataTable = async(res) => {
const _params = {
...res
}
// return await getUserList(_params)
}

function handleModal() {
data.rowData = null
data.modalType = 'create'
data.modalShow = true
}

return {
...toRefs(data),
loadDataTable,
handleModal
}
}
}

+ 33
- 0
src/views/task-manage/all-task/tools/form.js View File

@@ -0,0 +1,33 @@
import { reactive } from 'vue'
import { TASK_MODE, TASK_TYPE } from '@/utils/dictionary.js'

const data = reactive({
taskForm: {
name: '',
name2: '',
name3: '',
name4: '',
name5: '',
name6: null,
name7: ''
},
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'] }]
},
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 }}}
]
})

export default data

+ 54
- 2
src/views/task-manage/all-task/tools/search.js View File

@@ -1,4 +1,7 @@
const data = [
import { reactive } from 'vue'
import { TASK_STATUS, TASK_TYPE } from '@/utils/dictionary.js'

const data = reactive([
{
label: '任务编号',
key: 'code',
@@ -12,8 +15,57 @@ const data = [
props: {
placeholder: '请输入任务名称'
}
},
{
label: '任务状态',
key: 'status',
type: 'select',
value: 'all',
props: {
placeholder: '请选择任务状态',
options: [
{ label: '全部', value: 'all' },
...TASK_STATUS
]
}
},
{
label: '巡检机场',
key: 'plain',
type: 'select',
props: {
placeholder: '请选择任务状态',
options: [],
onUpdateValue: () => {
const index = data.findIndex((item) => item.key === 'route')
data[index].value = ''
}
}
},
{
label: '巡检路线',
key: 'route',
type: 'select',
props: {
placeholder: '请选择任务状态',
options: [],
onUpdateValue: () => {
}
}
},
{
label: '任务类型',
key: 'type',
type: 'select',
value: 0,
props: {
placeholder: '请选择任务状态',
options: TASK_TYPE,
onUpdateValue: () => {
}
}
}
]
])

export default data


+ 173
- 0
src/views/task-manage/all-task/tools/table.js View File

@@ -0,0 +1,173 @@
// import TableTags from '@/components/DataTable/tools/Tags.vue'
import TableAction from '@/components/DataTable/tools/Action.vue'
import { h, reactive } from 'vue'

function getRowData(row, type) {
data.rowData = row
data.modalType = type
data.modalShow = true
}

function handleRowDelete(row) {

}

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({
rowData: {},
modalType: 'create',
modalShow: false,

liveDrawer: false,

demandDrawer: false,

verifyDrawer: false,

columns: [
{
title: '任务标号',
key: 'name',
align: 'center'
},
{
title: '任务名称',
key: 'name',
align: 'center'
},
{
title: '巡检方式',
key: 'name',
align: 'center'
},
{
title: '巡检机场',
key: 'name',
align: 'center'
},
{
title: '巡检路线',
key: 'name',
align: 'center'
},
{
title: '任务类型',
key: 'name',
align: 'center'
},
{
title: '巡检时间',
key: 'name',
align: 'center'
},
{
title: '状态',
key: 'name',
align: 'center'
},

{
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'
},
{
label: '直播',
type: 'button',
props: {
type: 'primary',
text: true,
onClick: handleTaskLive.bind(null, row)
},
auth: 'basic_list'
},
{
label: '轨迹',
type: 'button',
props: {
type: 'primary',
text: true,
onClick: handleTaskDemand.bind(null, row)
},
auth: 'basic_list'
},
{
label: '问题核实',
type: 'button',
props: {
type: 'primary',
text: true,
onClick: handleTaskVerify.bind(null, row)
},
auth: 'basic_list'
}
],
align: 'center'
})
}
}

]
})

export default data

Loading…
Cancel
Save