| | |
| | | <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> |
| | | <div>{{ formatTaskTime(record.begin_time) }}</div> |
| | | <div>{{ formatTaskTime(record.end_time) }}</div> |
| | | </div> |
| | | <div class="ml10"> |
| | | <div>{{ formatTaskTime(record.execute_time) }}</div> |
| | | <div>{{ formatTaskTime(record.completed_time) }}</div> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | <!-- 状态 --> |
| | |
| | | </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> |
| | |
| | | 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' |
| | |
| | | |
| | | 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', |
| | | title: '计划名称', |
| | | dataIndex: 'job_name', |
| | | width: 100, |
| | | }, |
| | | { |
| | | title: 'Type', |
| | | dataIndex: 'taskType', |
| | | width: 100, |
| | | slots: { customRender: 'taskType' }, |
| | | }, |
| | | { |
| | | title: 'Flight Route Name', |
| | | dataIndex: 'file_name', |
| | | width: 100, |
| | | }, |
| | | { |
| | | title: 'Dock Name', |
| | | title: '设备名称', |
| | | dataIndex: 'dock_name', |
| | | width: 100, |
| | | ellipsis: true |
| | | }, |
| | | { |
| | | title: 'RTH Altitude Relative to Dock (m)', |
| | | title: '相对机场返航高度', |
| | | dataIndex: 'rth_altitude', |
| | | width: 120, |
| | | width: 140, |
| | | }, |
| | | { |
| | | title: 'Lost Action', |
| | | title: '航线飞行中失联', |
| | | dataIndex: 'out_of_control_action', |
| | | width: 120, |
| | | width: 140, |
| | | slots: { customRender: 'lostAction' }, |
| | | }, |
| | | { |
| | | title: 'Creator', |
| | | dataIndex: 'username', |
| | | width: 120, |
| | | }, |
| | | { |
| | | title: 'Media File Upload', |
| | | key: 'media_upload', |
| | | width: 160, |
| | | slots: { customRender: 'media_upload' } |
| | | }, |
| | | { |
| | | title: 'Action', |
| | | title: '操作', |
| | | width: 120, |
| | | slots: { customRender: 'action' } |
| | | } |
| | |
| | | } |
| | | } |
| | | |
| | | // 挂起任务 |
| | | 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() |
| | | } |
| | | } |
| | | |
| | | // 立即上传媒体 |
| | | async function onUploadMediaFileNow (jobId: string) { |
| | | const { code } = await uploadMediaFileNow(workspaceId, jobId) |
| | |
| | | margin-top: 10px; |
| | | } |
| | | .action-area { |
| | | color: $primary; |
| | | cursor: pointer; |
| | | |
| | | &::v-deep { |
| | | .ant-btn { |
| | | margin-right: 10px; |
| | | margin-bottom: 10px; |
| | | } |
| | | } |
| | | } |
| | | |
| | | .circle-icon { |