From 1810c61f5a8bae5f92b2ab56953052ff423109d6 Mon Sep 17 00:00:00 2001 From: "sean.zhou" Date: Fri, 21 Oct 2022 21:41:17 +0800 Subject: [PATCH] v1.3.0-beta1 --- src/api/manage.ts | 6 + src/api/wayline.ts | 59 +++- src/components/GMap.vue | 1 + src/components/TaskPanel.vue | 182 ---------- src/components/livestream-agora.vue | 177 ++++++---- src/components/livestream-others.vue | 174 ++++++---- .../task/CreatePlan.vue} | 81 ++++- src/components/task/TaskPanel.vue | 233 +++++++++++++ src/components/task/use-format-task.ts | 30 ++ .../task/use-task-progress-event.ts | 19 ++ src/components/wayline-panel.vue | 123 ------- src/event-bus/index.ts | 5 +- src/hooks/use-g-map-tsa.ts | 23 +- src/pages/page-pilot/pilot-home.vue | 2 +- src/pages/page-web/projects/dock.vue | 2 +- src/pages/page-web/projects/task.vue | 28 +- src/pages/page-web/projects/workspace.vue | 5 +- src/router/index.ts | 2 +- src/store/index.ts | 18 +- src/types/enums.ts | 2 +- src/types/task.ts | 78 +++++ src/types/wayline.ts | 29 +- src/utils/error-code/index.ts | 310 ++++++++++++++++++ tsconfig.json | 5 +- 24 files changed, 1048 insertions(+), 546 deletions(-) delete mode 100644 src/components/TaskPanel.vue rename src/{pages/page-web/projects/create-plan.vue => components/task/CreatePlan.vue} (76%) create mode 100644 src/components/task/TaskPanel.vue create mode 100644 src/components/task/use-format-task.ts create mode 100644 src/components/task/use-task-progress-event.ts delete mode 100644 src/components/wayline-panel.vue create mode 100644 src/types/task.ts create mode 100644 src/utils/error-code/index.ts diff --git a/src/api/manage.ts b/src/api/manage.ts index 559d12b..fbdcb48 100644 --- a/src/api/manage.ts +++ b/src/api/manage.ts @@ -159,4 +159,10 @@ export const getDeviceHms = async function (body: HmsQueryBody, workspace_id: st }) const result = await request.get(url) return result.data +} + +export const changeLivestreamLens = async function (body: {}): Promise> { + const url = `${HTTP_PREFIX}/live/streams/switch` + const result = await request.post(url, body) + return result.data } \ No newline at end of file diff --git a/src/api/wayline.ts b/src/api/wayline.ts index 2efa822..1ecbf30 100644 --- a/src/api/wayline.ts +++ b/src/api/wayline.ts @@ -1,14 +1,9 @@ import { message } from 'ant-design-vue' -import request, { IPage, IWorkspaceResponse } from '/@/api/http/request' -const HTTP_PREFIX = '/wayline/api/v1' +import request, { IPage, IWorkspaceResponse, IListWorkspaceResponse } from '/@/api/http/request' +import { TaskType, TaskStatus } from '/@/types/task' +import { WaylineType } from '/@/types/wayline' -export interface CreatePlan { - name: string, - file_id: string, - dock_sn: string, - immediate: boolean, - type: string, -} +const HTTP_PREFIX = '/wayline/api/v1' // Get Wayline Files export const getWaylineFiles = async function (wid: string, body: {}): Promise> { @@ -24,12 +19,11 @@ export const downloadWaylineFile = async function (workspaceId: string, waylineI if (result.data.type === 'application/json') { const reader = new FileReader() reader.onload = function (e) { - let text = reader.result as string + const text = reader.result as string const result = JSON.parse(text) message.error(result.message) } reader.readAsText(result.data, 'utf-8') - return } else { return result.data } @@ -42,6 +36,15 @@ export const deleteWaylineFile = async function (workspaceId: string, waylineId: return result.data } +export interface CreatePlan { + name: string, + file_id: string, + dock_sn: string, + task_type: TaskType, // 任务类型 + wayline_type: WaylineType, // 航线类型 + execute_time?: number // 执行时间(毫秒) +} + // Create Wayline Job export const createPlan = async function (workspaceId: string, plan: CreatePlan): Promise> { const url = `${HTTP_PREFIX}/workspaces/${workspaceId}/flight-tasks` @@ -49,16 +52,40 @@ export const createPlan = async function (workspaceId: string, plan: CreatePlan) return result.data } +export interface Task { + job_id: string, + job_name: string, + task_type: TaskType, // 任务类型 + file_id: string, // 航线文件id + file_name: string, // 航线名称 + wayline_type: WaylineType, // 航线类型 + dock_sn: string, + dock_name: string, + workspace_id: string, + username: string, + execute_time: string, + end_time: string, + status: TaskStatus, // 任务状态 + progress: number, // 执行进度 + code: number, // 错误码 +} + // Get Wayline Jobs -export const getWaylineJobs = async function (workspaceId: string, page: IPage): Promise> { +export const getWaylineJobs = async function (workspaceId: string, page: IPage): Promise> { const url = `${HTTP_PREFIX}/workspaces/${workspaceId}/jobs?page=${page.page}&page_size=${page.page_size}` const result = await request.get(url) return result.data } -// Execute Wayline Job -export const executeWaylineJobs = async function (workspaceId: string, plan_id: string): Promise> { - const url = `${HTTP_PREFIX}/workspaces/${workspaceId}/jobs/${plan_id}` - const result = await request.post(url) +export interface DeleteTaskParams { + job_id: string +} + +// 取消机场任务 +export async function deleteTask (workspaceId: string, params: DeleteTaskParams): Promise> { + const url = `${HTTP_PREFIX}/workspaces/${workspaceId}/jobs` + const result = await request.delete(url, { + params: params + }) return result.data } diff --git a/src/components/GMap.vue b/src/components/GMap.vue index 411b7ed..24791c7 100644 --- a/src/components/GMap.vue +++ b/src/components/GMap.vue @@ -589,6 +589,7 @@ export default defineComponent({ } } if (data.currentType === EDeviceTypeName.Dock && data.dockInfo[data.currentSn]) { + deviceTsaUpdateHook.value.initMarker(EDeviceTypeName.Dock, EDeviceTypeName.Dock, data.currentSn, data.dockInfo[data.currentSn].longitude, data.dockInfo[data.currentSn].latitude) if (osdVisible.value.visible && osdVisible.value.is_dock && osdVisible.value.gateway_sn !== '') { deviceInfo.dock = data.dockInfo[osdVisible.value.gateway_sn] deviceInfo.device = data.deviceInfo[deviceInfo.dock.sub_device?.device_sn] diff --git a/src/components/TaskPanel.vue b/src/components/TaskPanel.vue deleted file mode 100644 index 084626f..0000000 --- a/src/components/TaskPanel.vue +++ /dev/null @@ -1,182 +0,0 @@ - - - - - diff --git a/src/components/livestream-agora.vue b/src/components/livestream-agora.vue index 41463f3..1860cce 100644 --- a/src/components/livestream-agora.vue +++ b/src/components/livestream-agora.vue @@ -3,15 +3,23 @@

Live streaming source selection

+ +
+ AppId: + Token: + Channel:
- Play + Switch Lens + Play Stop Update Clarity - Refresh Live Capacity
@@ -91,8 +105,9 @@ import AgoraRTC, { IAgoraRTCClient, IAgoraRTCRemoteUser } from 'agora-rtc-sdk-ng' import { message } from 'ant-design-vue' import { onMounted, reactive } from 'vue' +import { uuidv4 } from '../utils/uuid' import { CURRENT_CONFIG as config } from '/@/api/http/config' -import { getLiveCapacity, setLivestreamQuality, startLivestream, stopLivestream } from '/@/api/manage' +import { changeLivestreamLens, getLiveCapacity, setLivestreamQuality, startLivestream, stopLivestream } from '/@/api/manage' import { getRoot } from '/@/root' const root = getRoot() @@ -120,6 +135,12 @@ const clarityList = [ } ] +interface SelectOption { + value: any, + label: string, + more?: any +} + let agoraClient = {} as IAgoraRTCClient const agoraPara = reactive({ appid: config.agoraAPPID, @@ -130,13 +151,16 @@ const agoraPara = reactive({ }) const dronePara = reactive({ livestreamSource: [], - droneList: [] as any[], - cameraList: [] as any[], - videoList: [] as any[], - droneSelected: '', - cameraSelected: '', - videoSelected: '', - claritySelected: 0 + droneList: [] as SelectOption[], + cameraList: [] as SelectOption[], + videoList: [] as SelectOption[], + droneSelected: undefined as string | undefined, + cameraSelected: undefined as string | undefined, + videoSelected: undefined as string | undefined, + claritySelected: 0, + lensList: [] as string[], + lensSelected: undefined as string | undefined, + isDockLive: false }) const livePara = reactive({ url: '', @@ -144,14 +168,15 @@ const livePara = reactive({ videoId: '', liveState: false }) +const nonSwitchable = 'normal' const onRefresh = async () => { dronePara.droneList = [] dronePara.cameraList = [] dronePara.videoList = [] - dronePara.droneSelected = '' - dronePara.cameraSelected = '' - dronePara.videoSelected = '' + dronePara.droneSelected = undefined + dronePara.cameraSelected = undefined + dronePara.videoSelected = undefined await getLiveCapacity({}) .then(res => { if (res.code === 0) { @@ -166,18 +191,20 @@ const onRefresh = async () => { if (dronePara.livestreamSource) { dronePara.livestreamSource.forEach((ele: any) => { - dronePara.droneList.push({ label: ele.name + '-' + ele.sn, value: ele.sn }) + dronePara.droneList.push({ label: ele.name + '-' + ele.sn, value: ele.sn, more: ele.cameras_list }) }) } } }) .catch(error => { + message.error(error) console.error(error) }) } onMounted(() => { onRefresh() + agoraPara.token = encodeURIComponent(agoraPara.token) agoraClient = AgoraRTC.createClient({ mode: 'live', codec: 'vp8' }) // Subscribe when a remote user publishes a stream agoraClient.on('user-joined', async (user: IAgoraRTCRemoteUser) => { @@ -191,7 +218,7 @@ onMounted(() => { const remoteVideoTrack = user.videoTrack! // Dynamically create a container in the form of a DIV element for playing the remote video track. const remotePlayerContainer: any = document.getElementById('player') - // remotePlayerContainer.id = agoraPara.uid + remotePlayerContainer.id = user.uid.toString() remoteVideoTrack.play(remotePlayerContainer) } }) @@ -199,6 +226,10 @@ onMounted(() => { console.log('unpublish live:', user) message.info('unpublish live') }) + agoraClient.on('exception', async (e: any) => { + console.error(e) + message.error(e.msg) + }) }) const handleError = (err: any) => { @@ -207,7 +238,9 @@ const handleError = (err: any) => { const handleJoinChannel = (uid: any) => { agoraPara.uid = uid } - +const encodeToken = (e: any) => { + agoraPara.token = encodeURIComponent(agoraPara.token) +} const onStart = async () => { const that = this console.log( @@ -222,13 +255,12 @@ const onStart = async () => { if ( dronePara.droneSelected == null || dronePara.cameraSelected == null || - dronePara.videoSelected == null || dronePara.claritySelected == null ) { message.warn('waring: not select live para!!!') return } - agoraClient.setClientRole('audience', { level: 1 }) + agoraClient.setClientRole('audience', { level: 2 }) if (agoraClient.connectionState === 'DISCONNECTED') { agoraClient .join(agoraPara.appid, agoraPara.channel, agoraPara.token) @@ -236,11 +268,8 @@ const onStart = async () => { livePara.videoId = dronePara.droneSelected + '/' + - dronePara.cameraSelected + - '/' + - dronePara.videoSelected + dronePara.cameraSelected + '/' + (dronePara.videoSelected || nonSwitchable + '-0') console.log(agoraPara) - agoraPara.token = encodeURIComponent(agoraPara.token) livePara.url = 'channel=' + @@ -259,6 +288,9 @@ const onStart = async () => { video_quality: dronePara.claritySelected }) .then(res => { + if (res.code !== 0) { + return + } livePara.liveState = true }) .catch(err => { @@ -266,12 +298,6 @@ const onStart = async () => { }) } const onStop = async () => { - livePara.videoId = - dronePara.droneSelected + - '/' + - dronePara.cameraSelected + - '/' + - dronePara.videoSelected stopLivestream({ video_id: livePara.videoId }).then(res => { @@ -279,52 +305,52 @@ const onStop = async () => { message.success(res.message) } livePara.liveState = false + dronePara.lensSelected = '' console.log('stop play livestream') }) } -const onDroneSelect = (val: any) => { - dronePara.droneSelected = val - if (dronePara.droneSelected) { - const droneTemp = dronePara.livestreamSource - dronePara.cameraList = [] +const onDroneSelect = (val: SelectOption) => { + dronePara.cameraList = [] + dronePara.videoList = [] + dronePara.lensList = [] - droneTemp.forEach((ele: any) => { - const drone = ele - if (drone.cameras_list && drone.sn === dronePara.droneSelected) { - const cameraListTemp = drone.cameras_list - cameraListTemp.forEach((ele: any) => { - dronePara.cameraList.push({ label: ele.name, value: ele.index }) - }) - } - }) + dronePara.cameraSelected = undefined + dronePara.videoSelected = undefined + dronePara.lensSelected = undefined + dronePara.droneSelected = val.value + if (!val.more) { + return } + val.more.forEach((ele: any) => { + dronePara.cameraList.push({ label: ele.name, value: ele.index, more: ele.videos_list }) + }) } -const onCameraSelect = (val: any) => { - dronePara.cameraSelected = val +const onCameraSelect = (val: SelectOption) => { + dronePara.cameraSelected = val.value + dronePara.videoSelected = undefined + dronePara.lensSelected = undefined + dronePara.videoList = [] + dronePara.lensList = [] + if (!val.more) { + return + } - if (dronePara.cameraSelected) { - const droneTemp = dronePara.livestreamSource - droneTemp.forEach((ele: any) => { - const drone = ele - if (drone.sn === dronePara.droneSelected) { - const cameraListTemp = drone.cameras_list - cameraListTemp.forEach((ele: any) => { - const camera = ele - if (camera.index === dronePara.cameraSelected) { - const videoListTemp = camera.videos_list - dronePara.videoList = [] - videoListTemp.forEach((ele: any) => { - dronePara.videoList.push({ label: ele.type, value: ele.index }) - }) - dronePara.videoSelected = dronePara.videoList[0]?.value - } - }) - } - }) + val.more.forEach((ele: any) => { + dronePara.videoList.push({ label: ele.type, value: ele.index, more: ele.switch_video_types }) + }) + if (dronePara.videoList.length === 0) { + return } + const firstVideo: SelectOption = dronePara.videoList[0] + dronePara.videoSelected = firstVideo.value + dronePara.lensList = firstVideo.more + dronePara.lensSelected = firstVideo.label + dronePara.isDockLive = dronePara.lensList.length > 0 } -const onVideoSelect = (val: any) => { - dronePara.videoSelected = val +const onVideoSelect = (val: SelectOption) => { + dronePara.videoSelected = val.value + dronePara.lensList = val.more + dronePara.lensSelected = val.label } const onClaritySelect = (val: any) => { dronePara.claritySelected = val @@ -343,6 +369,21 @@ const onUpdateQuality = () => { } }) } + +const onSwitch = () => { + if (dronePara.lensSelected === undefined || dronePara.lensSelected === nonSwitchable) { + message.info('The ' + nonSwitchable + ' lens cannot be switched, please select the lens to be switched.', 8) + return + } + changeLivestreamLens({ + video_id: livePara.videoId, + video_type: dronePara.lensSelected + }).then(res => { + if (res.code === 0) { + message.success('Switching live camera successfully.') + } + }) +} diff --git a/src/components/task/use-format-task.ts b/src/components/task/use-format-task.ts new file mode 100644 index 0000000..852f2ef --- /dev/null +++ b/src/components/task/use-format-task.ts @@ -0,0 +1,30 @@ +import { DEFAULT_PLACEHOLDER } from '/@/utils/constants' +import { Task } from '/@/api/wayline' +import { TaskStatusColor, TaskStatusMap, TaskTypeMap } from '/@/types/task' + +export function useFormatTask () { + function formatTaskType (task: Task) { + return TaskTypeMap[task.task_type] || DEFAULT_PLACEHOLDER + } + + function formatTaskTime (time: string) { + return time || DEFAULT_PLACEHOLDER + } + + function formatTaskStatus (task: Task) { + const statusObj = { + text: '', + color: '' + } + const { status } = task + statusObj.text = TaskStatusMap[status] + statusObj.color = TaskStatusColor[status] + return statusObj + } + + return { + formatTaskType, + formatTaskTime, + formatTaskStatus, + } +} diff --git a/src/components/task/use-task-progress-event.ts b/src/components/task/use-task-progress-event.ts new file mode 100644 index 0000000..54d4551 --- /dev/null +++ b/src/components/task/use-task-progress-event.ts @@ -0,0 +1,19 @@ +import EventBus from '/@/event-bus/' +import { onMounted, onBeforeUnmount } from 'vue' +import { TaskProgressInfo } from '/@/types/task' + +export function useTaskProgressEvent (onTaskProgressWs: (data: TaskProgressInfo) => void): void { + function handleTaskProgress (payload: any) { + onTaskProgressWs(payload.data) + // eslint-disable-next-line no-unused-expressions + // console.log('payload', payload.data) + } + + onMounted(() => { + EventBus.on('deviceTaskProgress', handleTaskProgress) + }) + + onBeforeUnmount(() => { + EventBus.off('deviceTaskProgress', handleTaskProgress) + }) +} diff --git a/src/components/wayline-panel.vue b/src/components/wayline-panel.vue deleted file mode 100644 index aad0a49..0000000 --- a/src/components/wayline-panel.vue +++ /dev/null @@ -1,123 +0,0 @@ - - - - - diff --git a/src/event-bus/index.ts b/src/event-bus/index.ts index 8024981..d4d24b3 100644 --- a/src/event-bus/index.ts +++ b/src/event-bus/index.ts @@ -1,8 +1,9 @@ import mitt, { Emitter } from 'mitt' type Events = { - deviceUpgrade: any; - deviceLogUploadProgress: any + deviceUpgrade: any; // 设备升级 + deviceLogUploadProgress: any // 设备日志上传 + deviceTaskProgress: any // 设备任务进度 }; const emitter: Emitter = mitt() diff --git a/src/hooks/use-g-map-tsa.ts b/src/hooks/use-g-map-tsa.ts index 6db59d8..213e3b4 100644 --- a/src/hooks/use-g-map-tsa.ts +++ b/src/hooks/use-g-map-tsa.ts @@ -3,18 +3,19 @@ import { getRoot } from '/@/root' import { ELocalStorageKey } from '/@/types' import { getDeviceBySn } from '/@/api/manage' import { message } from 'ant-design-vue' +import dockIcon from '/@/assets/icons/dock.png' +import rcIcon from '/@/assets/icons/rc.png' +import droneIcon from '/@/assets/icons/drone.png' export function deviceTsaUpdate () { const root = getRoot() const AMap = root.$aMap - const icons: { - [key: string]: string - } = { - 'sub-device': '/@/assets/icons/drone.png', - 'gateway': '/@/assets/icons/rc.png', - 'dock': '/@/assets/icons/dock.png' - } + const icons = new Map([ + ['sub-device', droneIcon], + ['gateway', rcIcon], + ['dock', dockIcon] + ]) const markers = store.state.markerInfo.coverMap const paths = store.state.markerInfo.pathMap @@ -33,13 +34,14 @@ export function deviceTsaUpdate () { function initIcon (type: string) { return new AMap.Icon({ - image: icons[type], - imageSize: new AMap.Size(40, 40) + image: icons.get(type), + imageSize: new AMap.Size(40, 40), + size: new AMap.Size(40, 40) }) } function initMarker (type: string, name: string, sn: string, lng?: number, lat?: number) { - if (markers[sn]) { + if (markers[sn] || AMap === undefined) { return } markers[sn] = new AMap.Marker({ @@ -50,7 +52,6 @@ export function deviceTsaUpdate () { offset: [0, -20], }) root.$map.add(markers[sn]) - // markers[sn].on('moving', function (e: any) { // let path = paths[sn] // if (!path) { diff --git a/src/pages/page-pilot/pilot-home.vue b/src/pages/page-pilot/pilot-home.vue index 1a1d0c4..9edd096 100644 --- a/src/pages/page-pilot/pilot-home.vue +++ b/src/pages/page-pilot/pilot-home.vue @@ -285,7 +285,7 @@ onMounted(() => { // thing const param: ThingParam = { host: res.data.mqtt_addr, - username: res.data.mqtt_username, + username: res.data.mqtt.username, password: res.data.mqtt_password, connectCallback: 'connectCallback' } diff --git a/src/pages/page-web/projects/dock.vue b/src/pages/page-web/projects/dock.vue index 72fd32f..0575267 100644 --- a/src/pages/page-web/projects/dock.vue +++ b/src/pages/page-web/projects/dock.vue @@ -9,7 +9,7 @@
-
+
{{ dock.nickname }}
diff --git a/src/pages/page-web/projects/task.vue b/src/pages/page-web/projects/task.vue index e594a8d..3e83954 100644 --- a/src/pages/page-web/projects/task.vue +++ b/src/pages/page-web/projects/task.vue @@ -5,34 +5,42 @@ Task Plan Library - - - + + + - - + +
-
- +
+
diff --git a/src/pages/page-web/projects/workspace.vue b/src/pages/page-web/projects/workspace.vue index 4fc4dd3..83db9cf 100644 --- a/src/pages/page-web/projects/workspace.vue +++ b/src/pages/page-web/projects/workspace.vue @@ -23,12 +23,13 @@ import Sidebar from '/@/components/common/sidebar.vue' import MediaPanel from '/@/components/MediaPanel.vue' -import TaskPanel from '/@/components/TaskPanel.vue' +import TaskPanel from '/@/components/task/TaskPanel.vue' import GMap from '/@/components/GMap.vue' import { EBizCode, ERouterName } from '/@/types' import { getRoot } from '/@/root' import { useMyStore } from '/@/store' import { useConnectWebSocket } from '/@/hooks/use-connect-websocket' +import EventBus from '/@/event-bus' const root = getRoot() const store = useMyStore() @@ -72,7 +73,7 @@ const messageHandler = async (payload: any) => { break } case EBizCode.FlightTaskProgress: { - store.commit('SET_FLIGHT_TASK_PROGRESS', payload.data) + EventBus.emit('deviceTaskProgress', payload) break } case EBizCode.DeviceHms: { diff --git a/src/router/index.ts b/src/router/index.ts index 8b20a35..9e5918d 100644 --- a/src/router/index.ts +++ b/src/router/index.ts @@ -1,6 +1,6 @@ import { createRouter, createWebHistory, RouteRecordRaw } from 'vue-router' import { ERouterName } from '/@/types/index' -import CreatePlan from '../pages/page-web/projects/create-plan.vue' +import CreatePlan from '/@/components/task/CreatePlan.vue' import WaylinePanel from '/@/pages/page-web/projects/wayline.vue' import DockPanel from '/@/pages/page-web/projects/dock.vue' import LiveAgora from '/@/components/livestream-agora.vue' diff --git a/src/store/index.ts b/src/store/index.ts index 36a7725..52bb154 100644 --- a/src/store/index.ts +++ b/src/store/index.ts @@ -4,7 +4,7 @@ import { EDeviceTypeName } from '../types' import { Device, DeviceHms, DeviceOsd, DeviceStatus, DockOsd, GatewayOsd, OSDVisible } from '../types/device' import { getLayers } from '/@/api/layer' import { LayerType } from '/@/types/mapLayer' -import { ETaskStatus, TaskInfo, WaylineFile } from '/@/types/wayline' +import { WaylineFile } from '/@/types/wayline' import { DevicesCmdExecuteInfo } from '/@/types/device-cmd' const initStateFunc = () => ({ @@ -81,11 +81,6 @@ const initStateFunc = () => ({ dockInfo: { } as Device, - taskProgressInfo: { - - } as { - [bid: string]: TaskInfo - }, hmsInfo: {} as { [sn: string]: DeviceHms[] }, @@ -160,17 +155,6 @@ const mutations: MutationTree = { SET_SELECT_DOCK_INFO (state, info) { state.dockInfo = info }, - SET_FLIGHT_TASK_PROGRESS (state, info) { - const taskInfo: TaskInfo = info.output - - if (taskInfo.status === ETaskStatus.OK || taskInfo.status === ETaskStatus.FAILED) { - taskInfo.status = taskInfo.status.concat('(Code:').concat(info.result).concat(')') - setTimeout(() => { - delete state.taskProgressInfo[info.bid] - }, 60000) - } - state.taskProgressInfo[info.bid] = info.output - }, SET_DEVICE_HMS_INFO (state, info) { const hmsList: Array = state.hmsInfo[info.sn] state.hmsInfo[info.sn] = info.host.concat(hmsList ?? []) diff --git a/src/types/enums.ts b/src/types/enums.ts index 00a298c..e0e1995 100644 --- a/src/types/enums.ts +++ b/src/types/enums.ts @@ -90,7 +90,7 @@ export enum EBizCode { MapElementDelete = 'map_element_delete', DeviceOnline = 'device_online', DeviceOffline = 'device_offline', - FlightTaskProgress = 'flighttask_progress', + FlightTaskProgress = 'flighttask_progress', // 机场任务执行进度 DeviceHms = 'device_hms', // 设备指令 diff --git a/src/types/task.ts b/src/types/task.ts new file mode 100644 index 0000000..a565fde --- /dev/null +++ b/src/types/task.ts @@ -0,0 +1,78 @@ +import { commonColor } from '/@/utils/color' + +// 任务类型 +export enum TaskType { + Immediate = 0, // 立即执行 + Single = 1, // 单次定时任务 +} + +export const TaskTypeMap = { + [TaskType.Immediate]: 'Immediate', + [TaskType.Single]: 'Timed & One-Time', +} + +// 任务状态 +export enum TaskStatus { + Wait = 1, // 待执行 + Carrying = 2, // 执行中 + Success = 3, // 完成 + CanCel = 4, // 取消 + Fail = 5, // 失败 +} + +export const TaskStatusMap = { + [TaskStatus.Wait]: 'To be performed', + [TaskStatus.Carrying]: 'In progress', + [TaskStatus.Success]: 'Task completed', + [TaskStatus.CanCel]: 'Task canceled', + [TaskStatus.Fail]: 'Task failed', +} + +export const TaskStatusColor = { + [TaskStatus.Wait]: commonColor.BLUE, + [TaskStatus.Carrying]: commonColor.BLUE, + [TaskStatus.Success]: commonColor.NORMAL, + [TaskStatus.CanCel]: commonColor.FAIL, + [TaskStatus.Fail]: commonColor.FAIL, +} + +// 任务执行 ws 消息状态 +export enum TaskProgressStatus { + Sent = 'sent', // 已下发 + inProgress = 'in_progress', // 执行中 + Paused = 'paused', // 暂停 + Rejected = 'rejected', // 拒绝 + Canceled = 'canceled', // 取消或终止 + Timeout = 'timeout', // 超时 + Failed = 'failed', // 失败 + OK = 'ok', // 上传成功 +} + +// 任务进度消息 +export interface TaskProgressInfo { + bid: string, + output:{ + ext: { + current_waypoint_index: number, + media_count: number // 媒体文件 + }, + progress:{ + current_step: number, + percent: number + }, + status: TaskProgressStatus + }, + result: number, +} + +// ws status => log status +export const TaskProgressWsStatusMap = { + [TaskProgressStatus.Sent]: TaskStatus.Carrying, + [TaskProgressStatus.inProgress]: TaskStatus.Carrying, + [TaskProgressStatus.Rejected]: TaskStatus.Fail, + [TaskProgressStatus.OK]: TaskStatus.Success, + [TaskProgressStatus.Failed]: TaskStatus.Fail, + [TaskProgressStatus.Canceled]: TaskStatus.CanCel, + [TaskProgressStatus.Timeout]: TaskStatus.Fail, + [TaskProgressStatus.Paused]: TaskStatus.Wait, +} diff --git a/src/types/wayline.ts b/src/types/wayline.ts index 69746e6..dfe7f91 100644 --- a/src/types/wayline.ts +++ b/src/types/wayline.ts @@ -1,30 +1,15 @@ +// 航线类型 +export enum WaylineType { + NormalWaypointWayline = 0, // 普通航点航线 + AccurateReshootingWayline = 1 // 精准复拍航线 +} + export interface WaylineFile { id: string, name: string, drone_model_key: any, payload_model_keys: string[], - template_types: number[], + template_types: WaylineType[], update_time: number, user_name: string, } - -export interface TaskExt { - current_waypoint_index: number, - media_count: number, -} - -export interface TaskProgress { - current_step: number, - percent: number, -} - -export interface TaskInfo { - status: string, - progress: TaskProgress, - ext: TaskExt, -} - -export enum ETaskStatus { - OK = 'ok', - FAILED = 'failed' -} diff --git a/src/utils/error-code/index.ts b/src/utils/error-code/index.ts new file mode 100644 index 0000000..e4c2679 --- /dev/null +++ b/src/utils/error-code/index.ts @@ -0,0 +1,310 @@ +export interface ErrorCode { + code: number; + msg: string; +} + +/** + * 根据错误码翻译错误信息 + * @param code + * @param errorMsg + * @returns + */ +export function getErrorMessage (code: number, errorMsg?: string): string { + const errorInfo = ERROR_CODE.find((item: ErrorCode) => item.code === code) + return errorInfo ? errorInfo.msg : errorMsg || 'Server error' +} + +// 暂时只添加航线错误 +export const ERROR_CODE = [ + { + code: 314001, + msg: 'The issued route task url is empty', + }, + { + code: 314002, + msg: 'The issued route task md5 is empty', + }, + { + code: 314003, + msg: 'MissionID is invalid', + }, + { + code: 314004, + msg: 'Failed to send flight route task from cloud', + }, + { + code: 314005, + msg: 'Route md5 check failed', + }, + { + code: 314006, + msg: 'Timeout waiting for aircraft to upload route (waiting for gs_state)', + }, + { + code: 314007, + msg: 'Failed to upload route to aircraft', + }, + { + code: 314008, + msg: 'Timeout waiting for the aircraft to enter the route executable state', + }, + { + code: 314009, + msg: 'Failed to open route mission', + }, + { + code: 314010, + msg: 'Route execution failed', + }, + { + code: 316001, + msg: 'Failed to set alternate point', + }, + { + code: 316002, + msg: 'Alternate safety transfer altitude equipment failed', + }, + { + code: 316003, + msg: 'Failed to set takeoff altitude. Remarks: The default safe takeoff height of the aircraft set by the current DJI Dock is: 1.8', + }, + { + code: 316004, + msg: 'Failed to set runaway behavior', + }, + { + code: 316005, + msg: 'Aircraft RTK convergence failed', + }, + { + code: 316013, + msg: 'DJI Dock Moved', + }, + { + code: 316015, + msg: 'The aircraft RTK convergence position is too far from the DJI Dock', + }, + { + code: 316007, + msg: 'Set parameter timeout while waiting for aircraft to be ready', + }, + { + code: 316008, + msg: 'Failed to gain control of aircraft', + }, + { + code: 316009, + msg: 'Aircraft power is low', + }, + { + code: 316010, + msg: 'After power on, the aircraft is not connected for more than 2 minutes (flight control OSD reception timeout)', + }, + { + code: 316011, + msg: 'Landing Position Offset', + }, + + { + code: 317001, + msg: 'Failed to get the number of media files', + }, + + { + code: 319001, + msg: 'The task center is not currently idle', + }, + { + code: 319002, + msg: 'dronenest communication timeout', + }, + { + code: 319999, + msg: 'Unknown error, e.g. restart after crash', + }, + { + code: 321000, + msg: 'Route execution failed, unknown error', + }, + { + code: 321257, + msg: 'The route has already started and cannot be started again', + }, + { + code: 321258, + msg: 'The route cannot be interrupted in this state', + }, + { + code: 321259, + msg: 'The route has not started and cannot end the route', + }, + { + code: 321513, + msg: 'Reach the height limit', + }, + { + code: 321514, + msg: 'Reach the limit', + }, + { + code: 321515, + msg: 'Crossing the restricted flight zone', + }, + { + code: 321516, + msg: 'Low limit', + }, + + { + code: 321517, + msg: 'Obstacle Avoidance', + }, + { + code: 321769, + msg: 'Weak GPS signal', + }, + { + code: 321770, + msg: 'The current gear state cannot be executed, B control seizes the control, and the gear is switched', + }, + { + code: 321771, + msg: 'The home point is not refreshed', + }, + { + code: 321772, + msg: 'The current battery is too low to start the task', + }, + { + code: 321773, + msg: 'Low battery return', + }, + { + code: 321776, + msg: 'RTK not ready', + }, + { + code: 321778, + msg: 'The aircraft is idling on the ground and is not allowed to start the route, thinking that the user is not ready.', + }, + { + code: 322282, + msg: 'User interrupt (B control takeover)', + }, + { + code: 514100, + msg: 'Command not supported', + }, + { + code: 514101, + msg: 'Failed to close putter', + }, + { + code: 514102, + msg: 'Failed to release putter', + }, + { + code: 514103, + msg: 'Aircraft battery is low', + }, + { + code: 514104, + msg: 'Failed to start charging', + }, + { + code: 514105, + msg: 'Failed to stop charging', + }, + { + code: 514106, + msg: 'Failed to restart the aircraft', + }, + { + code: 514107, + msg: 'Failed to open hatch', + }, + { + code: 514108, + msg: 'Failed to close hatch', + }, + { + code: 514109, + msg: 'Failed to open the plane', + }, + { + code: 514110, + msg: 'Failed to close the plane', + }, + { + code: 514111, + msg: 'The aircraft failed to turn on the slow-rotating propeller in the cabin', + }, + { + code: 514112, + msg: 'The aircraft failed to stop the slow-rotating propeller in the cabin', + }, + { + code: 514113, + msg: 'Failed to establish wired connection with aircraft', + }, + { + code: 514114, + msg: 'Get aircraft power status, command timed out, or return code is not 0', + }, + { + code: 514116, + msg: 'The DJI Dock is busy and other control orders are being executed at the DJI Dock', + }, + { + code: 514117, + msg: 'Check hatch status failed', + }, + { + code: 514118, + msg: 'Check putter status failed', + }, + { + code: 514120, + msg: 'DJI Dock and aircraft SDR connection failed', + }, + { + code: 514121, + msg: 'Emergency stop state', + }, + { + code: 514122, + msg: 'Failed to get the charging status of the aircraft (Failed to get the charging status, the flight mission can be executed, affecting charging and remote troubleshooting)', + }, + { + code: 514123, + msg: 'Unable to power on due to low battery', + }, + { + code: 514124, + msg: 'Failed to get battery information', + }, + { + code: 514125, + msg: 'The battery is fully charged and cannot be charged', + }, + { + code: 514145, + msg: 'Can not work while debugging on site', + }, + { + code: 514146, + msg: 'Unable to work in remote debugging', + }, + { + code: 514147, + msg: 'Unable to work in upgrade state', + }, + { + code: 514148, + msg: 'Unable to execute new tasks in job state', + }, + { + code: 514150, + msg: 'DJI Dock is automatically restarting', + }, +] diff --git a/tsconfig.json b/tsconfig.json index 8aefcd9..10e74cf 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -24,7 +24,6 @@ "src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", - "src/**/*.vue", - "src/vendors/coordtransform.js" - ] + "src/**/*.vue" +, "src/vendors/coordtransform.js" ] } \ No newline at end of file