xieb
2023-09-13 3667807a7b7418efc090ee3fa6a6b734bc3080bf
src/components/task/TaskPanel.vue
@@ -1,13 +1,22 @@
<template>
  <div class="header">Task Plan Library</div>
  <div class="header">计划库</div>
  <div class="plan-panel-wrapper">
    <a-table class="plan-table" :columns="columns" :data-source="plansData.data" row-key="job_id"
      :pagination="paginationProp" :scroll="{ x: '100%', y: 600 }" @change="refreshData">
      <!-- 执行时间 -->
      <template #duration="{ record }">
        <div>
          <div>{{ formatTaskTime(record.execute_time) }}</div>
          <div>{{ formatTaskTime(record.end_time) }}</div>
        <div class="flex-row" style="white-space: pre-wrap">
          <div v-if="record.taskType >2">
            <div>{{ formatTaskTime(record.executeStartTime) }}</div>
            <div>{{ formatTaskTime(record.executeEndTime) }}</div>
          </div>
          <div v-else>
            <div>{{formatTaskTime(record.executeSingleTime)}}</div>
          </div>
          <div class="ml10">
            <div>{{ formatTaskTime(record.execute_time) }}</div>
            <div>{{ formatTaskTime(record.completed_time) }}</div>
          </div>
        </div>
      </template>
      <!-- 状态 -->
@@ -56,17 +65,35 @@
      </template>
      <!-- 操作 -->
      <template #action="{ record }">
        <span class="action-area">
        <div class="action-area">
          <a-popconfirm
            v-if="record.status === TaskStatus.Wait"
            title="Are you sure you want to delete flight task?"
            ok-text="Yes"
            cancel-text="No"
            title="是否删除飞行计划?"
            ok-text="是"
            cancel-text="否"
            @confirm="onDeleteTask(record.job_id)"
          >
            <a-button type="primary" size="small">Delete</a-button>
            <a-button type="primary" size="small">删除</a-button>
          </a-popconfirm>
        </span>
          <a-popconfirm
            v-if="record.status === TaskStatus.Carrying"
            title="是否暂停?"
            ok-text="是"
            cancel-text="否"
            @confirm="onSuspendTask(record.job_id)"
          >
            <a-button type="primary" size="small">暂停</a-button>
          </a-popconfirm>
          <a-popconfirm
            v-if="record.status === TaskStatus.Paused"
            title="是否重新开始?"
            ok-text="是"
            cancel-text="否"
            @confirm="onResumeTask(record.job_id)"
          >
            <a-button type="primary" size="small">重启</a-button>
          </a-popconfirm>
        </div>
      </template>
    </a-table>
  </div>
@@ -78,7 +105,7 @@
import { TableState } from 'ant-design-vue/lib/table/interface'
import { onMounted } from 'vue'
import { IPage } from '/@/api/http/type'
import { deleteTask, getWaylineJobs, Task, uploadMediaFileNow } from '/@/api/wayline'
import { deleteTask, updateTaskStatus, UpdateTaskStatus, getWaylineJobs, Task, uploadMediaFileNow } from '/@/api/wayline'
import { useMyStore } from '/@/store'
import { ELocalStorageKey } from '/@/types/enums'
import { useFormatTask } from './use-format-task'
@@ -89,7 +116,7 @@
import { ExclamationCircleOutlined, UploadOutlined } from '@ant-design/icons-vue'
const store = useMyStore()
const workspaceId = localStorage.getItem(ELocalStorageKey.WorkspaceId)!
const workspaceId = store.state.common.projectId
const body: IPage = {
  page: 1,
@@ -107,63 +134,52 @@
const columns = [
  {
    title: 'Planned/Actual Time',
    title: '计划|实际时间',
    dataIndex: 'duration',
    width: 160,
    width: 200,
    slots: { customRender: 'duration' },
  },
  {
    title: 'Status',
    title: '执行状态',
    key: 'status',
    width: 150,
    slots: { customRender: 'status' }
  },
  {
    title: 'Plan Name',
    dataIndex: 'job_name',
    width: 100,
  },
  {
    title: 'Type',
    title: '类型',
    dataIndex: 'taskType',
    width: 100,
    slots: { customRender: 'taskType' },
  },
  {
    title: 'Flight Route Name',
    dataIndex: 'file_name',
    title: '计划名称',
    dataIndex: 'name',
    width: 100,
  },
  {
    title: 'Dock Name',
    dataIndex: 'dock_name',
    title: '航线名称',
    dataIndex: 'fileName',
    width: 100,
  },
  {
    title: '设备名称',
    dataIndex: 'dockName',
    width: 100,
    ellipsis: true
  },
  {
    title: 'RTH Altitude Relative to Dock (m)',
    dataIndex: 'rth_altitude',
    width: 120,
  },
  {
    title: 'Lost Action',
    dataIndex: 'out_of_control_action',
    width: 120,
    slots: { customRender: 'lostAction' },
  },
  {
    title: 'Creator',
    title: '创建人',
    dataIndex: 'username',
    width: 120,
  },
  {
    title: 'Media File Upload',
    title: '媒体上传',
    key: 'media_upload',
    width: 160,
    slots: { customRender: 'media_upload' }
  },
  {
    title: 'Action',
    title: '操作',
    width: 120,
    slots: { customRender: 'action' }
  }
@@ -240,12 +256,15 @@
function getPlans () {
  getWaylineJobs(workspaceId, body).then(res => {
    if (res.code !== 0) {
    console.log('计划数据', res)
    const data = res.data
    if (res.code !== 5000) {
      return
    }
    plansData.data = res.data.list
    paginationProp.total = res.data.pagination.total
    paginationProp.current = res.data.pagination.page
    plansData.data = data.records
    paginationProp.total = data.records.total
    paginationProp.current = data.records.current
  })
}
@@ -262,6 +281,30 @@
  })
  if (code === 0) {
    message.success('Deleted successfully')
    getPlans()
  }
}
// 挂起任务
async function onSuspendTask (jobId: string) {
  const { code } = await updateTaskStatus(workspaceId, {
    job_id: jobId,
    status: UpdateTaskStatus.Suspend
  })
  if (code === 0) {
    message.success('Suspended successfully')
    getPlans()
  }
}
// 解除挂起任务
async function onResumeTask (jobId: string) {
  const { code } = await updateTaskStatus(workspaceId, {
    job_id: jobId,
    status: UpdateTaskStatus.Resume
  })
  if (code === 0) {
    message.success('Resumed successfully')
    getPlans()
  }
}
@@ -285,8 +328,13 @@
    margin-top: 10px;
  }
  .action-area {
    color: $primary;
    cursor: pointer;
    &::v-deep {
      .ant-btn {
        margin-right: 10px;
        margin-bottom: 10px;
      }
    }
  }
  .circle-icon {