Browse Source

解决ts报错问题

pull/26/head
pmy 11 months ago
parent
commit
e67e7c627c
  1. 2
      .gitignore
  2. 5
      .gitignore copy
  3. 2
      index.html
  4. 4
      package-lock.json
  5. 2
      package.json
  6. 10
      src/api/http/config.ts
  7. 851
      src/components/GMap.vue
  8. 58
      src/components/LayersTree.vue
  9. 42
      src/components/g-map/DeviceSettingPopover.vue
  10. 69
      src/components/g-map/DockControlPanel.vue
  11. 18
      src/components/g-map/DroneControlInfoPanel.vue
  12. 310
      src/components/g-map/DroneControlPanel.vue
  13. 45
      src/components/g-map/DroneControlPopover.vue
  14. 82
      src/components/livestream-agora.vue
  15. 58
      src/components/task/TaskPanel.vue
  16. 30
      src/types/device.ts
  17. 19
      src/types/mapLayer.ts
  18. 90
      src/utils/genjson.ts
  19. 34
      src/vendors/coordtransform.ts
  20. 4677
      yarn.lock

2
.gitignore vendored

@ -5,6 +5,8 @@ dist-ssr
*.local *.local
node_modules/ node_modules/
src/api/http/config
# Log files # Log files
npm-debug.log* npm-debug.log*
yarn-debug.log* yarn-debug.log*

5
.gitignore copy

@ -1,5 +0,0 @@
node_modules
.DS_Store
dist
dist-ssr
*.local

2
index.html

@ -4,7 +4,7 @@
<meta charset="UTF-8" /> <meta charset="UTF-8" />
<link rel="icon" href="/favicon.ico" /> <link rel="icon" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>demo-web</title> <title>web</title>
</head> </head>
<body> <body>
<div id="demo-app"></div> <div id="demo-app"></div>

4
package-lock.json generated

@ -1,11 +1,11 @@
{ {
"name": "demo-web", "name": "web",
"version": "0.0.1", "version": "0.0.1",
"lockfileVersion": 2, "lockfileVersion": 2,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "demo-web", "name": "web",
"version": "0.0.1", "version": "0.0.1",
"license": "ISC", "license": "ISC",
"dependencies": { "dependencies": {

2
package.json

@ -1,5 +1,5 @@
{ {
"name": "demo-web", "name": "web",
"version": "0.0.1", "version": "0.0.1",
"scripts": { "scripts": {
"serve": "vite", "serve": "vite",

10
src/api/http/config.ts

@ -1,12 +1,12 @@
export const CURRENT_CONFIG = { export const CURRENT_CONFIG = {
// license // license
appId: 'Please enter the app id.', // You need to go to the development website to apply. appId: '146410', // You need to go to the development website to apply.
appKey: 'Please enter the app key.', // You need to go to the development website to apply. appKey: 'd422e7fa14c4e98ea2100736bea195e', // You need to go to the development website to apply.
appLicense: 'Please enter the app license.', // You need to go to the development website to apply. appLicense: 'vNVYmp43PMf/a4Yb4nJ947S70mT8bZUnNILRZSLFLjLKaOUX58BgS3DKwgQQSsbDyOvTOSSAjrnoD5Xg/2eUXro2MxoxW3Yx55pVUDZ58I2FgHH3870I6fWw3BqWcF0W14lglfWFl5aMuvCsv84G3EnvjRfSGjklHrDiCNSf2Bo=', // You need to go to the development website to apply.
// http // http
baseURL: 'Please enter the backend access address prefix.', // This url must end with "/". Example: 'http://192.168.1.1:6789/' baseURL: 'http://192.168.2.239:6789/', // This url must end with "/". Example: 'http://192.168.1.1:6789/'
websocketURL: 'Please enter the WebSocket access address.', // Example: 'ws://192.168.1.1:6789/api/v1/ws' websocketURL: 'Please enter the WebSocket access address.', // Example: 'ws://192.168.1.1:6789/api/v1/ws'
// livestreaming // livestreaming
@ -31,6 +31,6 @@ export const CURRENT_CONFIG = {
// map // map
// You can apply on the AMap website. // You can apply on the AMap website.
amapKey: 'Please enter the amap key.', amapKey: '6e948d848f069e3fbcae5a7634ae3f8f',
} }

851
src/components/GMap.vue

File diff suppressed because it is too large Load Diff

58
src/components/LayersTree.vue

@ -1,27 +1,13 @@
<template> <template>
<span> <span>
<a-tree <a-tree draggable :defaultExpandAll="true" class="device-map-layers" @drop="onDrop" v-bind="$attrs">
draggable <a-tree-node :title="layer.name" :id="layer.id" v-for="layer in getTreeData" :key="layer.id">
:defaultExpandAll="true"
class="device-map-layers"
@drop="onDrop"
v-bind="$attrs"
>
<a-tree-node
:title="layer.name"
:id="layer.id"
v-for="layer in getTreeData"
:key="layer.id"
>
<!-- <template #title> <!-- <template #title>
{{layer.name}} {{layer.name}}
</template> --> </template> -->
<template v-if="layer.elements"> <template v-if="layer.elements">
<a-tree-node <a-tree-node v-for="resource in layer.elements" :id="getLayerTreeKey('resource', resource.id)"
v-for="resource in layer.elements" :key="getLayerTreeKey('resource', resource.id)">
:id="getLayerTreeKey('resource', resource.id)"
:key="getLayerTreeKey('resource', resource.id)"
>
<template #title> <template #title>
{{ resource.name }} {{ resource.name }}
</template> </template>
@ -55,14 +41,14 @@ const shareId = computed(() => {
const defaultId = computed(() => { const defaultId = computed(() => {
return store.state.layerBaseInfo.default return store.state.layerBaseInfo.default
}) })
async function onDrop ({ node, dragNode, dropPosition, dropToGap }: DropEvent) { async function onDrop({ node, dragNode, dropPosition, dropToGap }: DropEvent) {
let _treeData = props.layerData || [] let _treeData = props.layerData || []
let dragKey = dragNode.eventKey let dragKey = dragNode.eventKey
dragKey = dragKey.replaceAll('resource__', '') dragKey = dragKey.replaceAll('resource__', '')
const dropPos = node.pos.split('-') const dropPos = node.pos.split('-')
let dropKey = let dropKey =
node.eventKey.includes(shareId.value) || node.eventKey.includes(shareId.value) ||
node.eventKey.includes(defaultId.value) node.eventKey.includes(defaultId.value)
? node.eventKey ? node.eventKey
: node.$parent.eventKey : node.$parent.eventKey
if (!dragKey || !dropKey) return if (!dragKey || !dropKey) return
@ -99,11 +85,11 @@ async function onDrop ({ node, dragNode, dropPosition, dropToGap }: DropEvent) {
</script> </script>
<style lang="scss"> <style lang="scss">
$antPrefix: 'ant'; $antPrefix: 'ant';
.device-map-layers.#{$antPrefix}-tree { .device-map-layers.#{$antPrefix}-tree {
color: #fff; color: #fff;
.#{$antPrefix}-tree-checkbox:not(.#{$antPrefix}-tree-checkbox-checked) .#{$antPrefix}-tree-checkbox:not(.#{$antPrefix}-tree-checkbox-checked) .#{$antPrefix}-tree-checkbox-inner {
.#{$antPrefix}-tree-checkbox-inner {
background-color: unset; background-color: unset;
} }
@ -112,7 +98,7 @@ $antPrefix: 'ant';
} }
// li 16px // li 16px
> li { >li {
padding-left: 16px; padding-left: 16px;
padding-right: 16px; padding-right: 16px;
} }
@ -128,14 +114,15 @@ $antPrefix: 'ant';
padding-top: 4px; padding-top: 4px;
} }
&.#{$antPrefix}-tree-treenode-disabled &.#{$antPrefix}-tree-treenode-disabled>.#{$antPrefix}-tree-node-content-wrapper {
> .#{$antPrefix}-tree-node-content-wrapper {
height: 20px; height: 20px;
span { span {
color: #fff; color: #fff;
} }
} }
> ul {
>ul {
width: 100%; width: 100%;
} }
@ -149,9 +136,9 @@ $antPrefix: 'ant';
.#{$antPrefix}-tree-checkbox { .#{$antPrefix}-tree-checkbox {
z-index: 1; z-index: 1;
} }
.#{$antPrefix}-tree-checkbox:hover::after, .#{$antPrefix}-tree-checkbox:hover::after,
.#{$antPrefix}-tree-checkbox-wrapper:hover .#{$antPrefix}-tree-checkbox-wrapper:hover .#{$antPrefix}-tree-checkbox::after {
.#{$antPrefix}-tree-checkbox::after {
visibility: collapse; visibility: collapse;
} }
@ -177,7 +164,7 @@ $antPrefix: 'ant';
background-color: transparent; background-color: transparent;
} }
> span { >span {
&::before { &::before {
// position: absolute; // position: absolute;
// right: 0; // right: 0;
@ -188,7 +175,7 @@ $antPrefix: 'ant';
} }
// positionrelative // positionrelative
> *:not(.progress-wrapper) { >*:not(.progress-wrapper) {
position: relative; position: relative;
z-index: 1; z-index: 1;
} }
@ -197,7 +184,8 @@ $antPrefix: 'ant';
&.#{$antPrefix}-tree-node-selected { &.#{$antPrefix}-tree-node-selected {
background-color: transparent; background-color: transparent;
color: #2d8cf0; color: #2d8cf0;
> span {
>span {
&::before { &::before {
background-color: #4f4f4f; background-color: #4f4f4f;
} }
@ -205,12 +193,12 @@ $antPrefix: 'ant';
} }
} }
} }
span.#{$antPrefix}-tree-switcher.#{$antPrefix}-tree-switcher_open
.#{$antPrefix}-tree-switcher-icon { span.#{$antPrefix}-tree-switcher.#{$antPrefix}-tree-switcher_open .#{$antPrefix}-tree-switcher-icon {
transform: rotate(0deg) !important; transform: rotate(0deg) !important;
} }
span.#{$antPrefix}-tree-switcher.#{$antPrefix}-tree-switcher_close
.#{$antPrefix}-tree-switcher-icon { span.#{$antPrefix}-tree-switcher.#{$antPrefix}-tree-switcher_close .#{$antPrefix}-tree-switcher-icon {
transform: rotate(0deg) !important; transform: rotate(0deg) !important;
} }
} }

42
src/components/g-map/DeviceSettingPopover.vue

@ -1,25 +1,15 @@
<template> <template>
<a-popover :visible="state.sVisible" <a-popover :visible="state.sVisible" trigger="click" v-bind="$attrs" :overlay-class-name="overlayClassName"
trigger="click" placement="bottom" @visibleChange=";" v-on="$attrs">
v-bind="$attrs"
:overlay-class-name="overlayClassName"
placement="bottom"
@visibleChange=";"
v-on="$attrs">
<template #content> <template #content>
<div class="title-content"> <div class="title-content">
</div> </div>
<slot name="formContent" /> <slot name="formContent" />
<div class="uranus-popconfirm-btns"> <div class="uranus-popconfirm-btns">
<a-button size="sm" <a-button size="sm" @click="onCancel">
@click="onCancel"> {{ cancelText || '取消' }}
{{ cancelText || '取消'}}
</a-button> </a-button>
<a-button size="sm" <a-button size="sm" :loading="loading" type="primary" class="confirm-btn" @click="onConfirm">
:loading="loading"
type="primary"
class="confirm-btn"
@click="onConfirm">
{{ okText || '确定' }} {{ okText || '确定' }}
</a-button> </a-button>
</div> </div>
@ -34,13 +24,13 @@
import { defineProps, defineEmits, reactive, watch, computed } from 'vue' import { defineProps, defineEmits, reactive, watch, computed } from 'vue'
const props = defineProps<{ const props = defineProps<{
visible?: boolean, visible?: boolean,
loading?: Boolean, loading?: Boolean,
disabled?: Boolean, disabled?: Boolean,
title?: String, title?: String,
okText?: String, okText?: String,
cancelText?: String, cancelText?: String,
width?: Number, width?: Number,
}>() }>()
const emit = defineEmits(['cancel', 'confirm']) const emit = defineEmits(['cancel', 'confirm'])
@ -84,21 +74,21 @@ function onCancel (e: Event) {
.device-setting-popconfirm { .device-setting-popconfirm {
min-width: 300px; min-width: 300px;
.uranus-popconfirm-btns{ .uranus-popconfirm-btns {
display: flex; display: flex;
padding: 10px 0px; padding: 10px 0px;
justify-content: flex-end; justify-content: flex-end;
.confirm-btn{ .confirm-btn {
margin-left: 10px; margin-left: 10px;
} }
} }
.form-content{ .form-content {
display: inline-flex; display: inline-flex;
align-items: center; align-items: center;
.form-label{ .form-label {
padding-right: 10px; padding-right: 10px;
} }
} }

69
src/components/g-map/DockControlPanel.vue

@ -1,35 +1,37 @@
<template> <template>
<div class="dock-control-panel"> <div class="dock-control-panel">
<!-- title --> <!-- title -->
<div class="dock-control-panel-header fz16 pl5 pr5 flex-align-center flex-row flex-justify-between"> <div class="dock-control-panel-header fz16 pl5 pr5 flex-align-center flex-row flex-justify-between">
<span>Device Control<span class="fz12 pl15">{{ props.sn}}</span></span> <span>Device Control<span class="fz12 pl15">{{ props.sn }}</span></span>
<span @click="closeControlPanel"> <span @click="closeControlPanel">
<CloseOutlined /> <CloseOutlined />
</span> </span>
</div>
<!-- setting -->
<DeviceSettingBox :sn="props.sn" :deviceInfo="props.deviceInfo"></DeviceSettingBox>
<!-- cmd -->
<div class="control-cmd-wrapper">
<div class="control-cmd-header">
Device Remote Debug
<a-switch class="debug-btn" checked-children="" un-checked-children="" v-model:checked="debugStatus" @change="onDeviceStatusChange"/>
</div> </div>
<div class="control-cmd-box"> <!-- setting -->
<div v-for="(cmdItem, index) in cmdList" :key="cmdItem.cmdKey" class="control-cmd-item"> <DeviceSettingBox :sn="props.sn" :deviceInfo="props.deviceInfo"></DeviceSettingBox>
<div class="control-cmd-item-left"> <!-- cmd -->
<div class="control-cmd-wrapper">
<div class="control-cmd-header">
Device Remote Debug
<a-switch class="debug-btn" checked-children="" un-checked-children="" v-model:checked="debugStatus"
@change="onDeviceStatusChange" />
</div>
<div class="control-cmd-box">
<div v-for="(cmdItem, index) in cmdList" :key="cmdItem.cmdKey" class="control-cmd-item">
<div class="control-cmd-item-left">
<div class="item-label">{{ cmdItem.label }}</div> <div class="item-label">{{ cmdItem.label }}</div>
<div class="item-status">{{ cmdItem.status }}</div> <div class="item-status">{{ cmdItem.status }}</div>
</div> </div>
<div class="control-cmd-item-right"> <div class="control-cmd-item-right">
<a-button :disabled="!debugStatus || cmdItem.disabled" :loading="cmdItem.loading" size="small" type="primary" @click="sendControlCmd(cmdItem, index)"> <a-button :disabled="!debugStatus || cmdItem.disabled" :loading="cmdItem.loading" size="small"
{{ cmdItem.operateText }} type="primary" @click="sendControlCmd(cmdItem, index)">
{{ cmdItem.operateText }}
</a-button> </a-button>
</div>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</div>
</template> </template>
@ -116,7 +118,7 @@ async function sendControlCmd (cmdItem: DeviceCmdItem, index: number) {
</script> </script>
<style lang='scss' scoped> <style lang='scss' scoped>
.dock-control-panel{ .dock-control-panel {
position: absolute; position: absolute;
left: calc(100% + 10px); left: calc(100% + 10px);
top: 0px; top: 0px;
@ -126,28 +128,29 @@ async function sendControlCmd (cmdItem: DeviceCmdItem, index: number) {
color: #fff; color: #fff;
border-radius: 2px; border-radius: 2px;
.dock-control-panel-header{ .dock-control-panel-header {
border-bottom: 1px solid #515151; border-bottom: 1px solid #515151;
} }
.control-cmd-wrapper{ .control-cmd-wrapper {
.control-cmd-header{ .control-cmd-header {
font-size: 14px; font-size: 14px;
font-weight: 600; font-weight: 600;
padding: 10px 10px 0px; padding: 10px 10px 0px;
.debug-btn{ .debug-btn {
margin-left: 10px; margin-left: 10px;
border:1px solid #585858; border: 1px solid #585858;
} }
} }
.control-cmd-box{ .control-cmd-box {
display: flex; display: flex;
flex-wrap: wrap; flex-wrap: wrap;
justify-content: space-between; justify-content: space-between;
padding: 4px 10px; padding: 4px 10px;
.control-cmd-item{
.control-cmd-item {
width: 220px; width: 220px;
height: 58px; height: 58px;
display: flex; display: flex;
@ -157,11 +160,11 @@ async function sendControlCmd (cmdItem: DeviceCmdItem, index: number) {
margin: 4px 0; margin: 4px 0;
padding: 0 8px; padding: 0 8px;
.control-cmd-item-left{ .control-cmd-item-left {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
.item-label{ .item-label {
font-weight: 700; font-weight: 700;
} }
} }

18
src/components/g-map/DroneControlInfoPanel.vue

@ -1,14 +1,14 @@
<template> <template>
<div class="drone-control-info-wrap"> <div class="drone-control-info-wrap">
<a-textarea v-model:value="info" placeholder="drc info" :rows="5" disabled/> <a-textarea v-model:value="info" placeholder="drc info" :rows="5" disabled />
</div> </div>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { ref, defineProps, watch } from 'vue' import { ref, defineProps, watch } from 'vue'
const props = defineProps<{ const props = defineProps<{
message?: string, message?: string,
}>() }>()
const info = ref('') const info = ref('')
@ -23,12 +23,10 @@ watch(() => props.message, message => {
<style lang="scss" scoped> <style lang="scss" scoped>
.drone-control-info-wrap { .drone-control-info-wrap {
&::v-deep{ :deep(textarea.ant-input) {
textarea.ant-input { background-color: #000;
background-color: #000; color: #fff;
color: #fff; white-space: pre-wrap;
white-space: pre-wrap;
}
} }
} }
</style> </style>

310
src/components/g-map/DroneControlPanel.vue

@ -4,145 +4,141 @@
<div class="drone-control-box"> <div class="drone-control-box">
<div class="box"> <div class="box">
<div class="row"> <div class="row">
<div class="drone-control"><Button :ghost="!flightController" size="small" @click="onClickFightControl">{{ flightController ? 'Exit Remote Control' : 'Enter Remote Control'}}</Button></div> <div class="drone-control"><Button :ghost="!flightController" size="small" @click="onClickFightControl">{{
flightController ? 'Exit Remote Control' : 'Enter Remote Control' }}</Button></div>
</div> </div>
<div class="row"> <div class="row">
<div class="drone-control-direction"> <div class="drone-control-direction">
<Button size="small" ghost @mousedown="onMouseDown(KeyCode.KEY_Q)" @onmouseup="onMouseUp"> <Button size="small" ghost @mousedown="onMouseDown(KeyCode.KEY_Q)" @onmouseup="onMouseUp">
<template #icon><UndoOutlined /></template><span class="word">Q</span> <template #icon>
<UndoOutlined />
</template><span class="word">Q</span>
</Button> </Button>
<Button size="small" ghost @mousedown="onMouseDown(KeyCode.KEY_W)" @onmouseup="onMouseUp"> <Button size="small" ghost @mousedown="onMouseDown(KeyCode.KEY_W)" @onmouseup="onMouseUp">
<template #icon><UpOutlined/></template><span class="word">W</span> <template #icon>
<UpOutlined />
</template><span class="word">W</span>
</Button> </Button>
<Button size="small" ghost @mousedown="onMouseDown(KeyCode.KEY_E)" @onmouseup="onMouseUp"> <Button size="small" ghost @mousedown="onMouseDown(KeyCode.KEY_E)" @onmouseup="onMouseUp">
<template #icon><RedoOutlined /></template><span class="word">E</span> <template #icon>
<RedoOutlined />
</template><span class="word">E</span>
</Button> </Button>
<Button size="small" ghost @mousedown="onMouseDown(KeyCode.ARROW_UP)" @onmouseup="onMouseUp"> <Button size="small" ghost @mousedown="onMouseDown(KeyCode.ARROW_UP)" @onmouseup="onMouseUp">
<template #icon><ArrowUpOutlined /></template> <template #icon>
<ArrowUpOutlined />
</template>
</Button> </Button>
<br /> <br />
<Button size="small" ghost @mousedown="onMouseDown(KeyCode.KEY_A)" @onmouseup="onMouseUp"> <Button size="small" ghost @mousedown="onMouseDown(KeyCode.KEY_A)" @onmouseup="onMouseUp">
<template #icon><LeftOutlined/></template><span class="word">A</span> <template #icon>
<LeftOutlined />
</template><span class="word">A</span>
</Button> </Button>
<Button size="small" ghost @mousedown="onMouseDown(KeyCode.KEY_S)" @onmouseup="onMouseUp"> <Button size="small" ghost @mousedown="onMouseDown(KeyCode.KEY_S)" @onmouseup="onMouseUp">
<template #icon><DownOutlined/></template><span class="word">S</span> <template #icon>
<DownOutlined />
</template><span class="word">S</span>
</Button> </Button>
<Button size="small" ghost @mousedown="onMouseDown(KeyCode.KEY_D)" @onmouseup="onMouseUp"> <Button size="small" ghost @mousedown="onMouseDown(KeyCode.KEY_D)" @onmouseup="onMouseUp">
<template #icon><RightOutlined/></template><span class="word">D</span> <template #icon>
<RightOutlined />
</template><span class="word">D</span>
</Button> </Button>
<Button size="small" ghost @mousedown="onMouseDown(KeyCode.ARROW_DOWN)" @onmouseup="onMouseUp"> <Button size="small" ghost @mousedown="onMouseDown(KeyCode.ARROW_DOWN)" @onmouseup="onMouseUp">
<template #icon><ArrowDownOutlined /></template> <template #icon>
<ArrowDownOutlined />
</template>
</Button> </Button>
</div> </div>
<Button type="primary" size="small" danger ghost @click="handleEmergencyStop" > <Button type="primary" size="small" danger ghost @click="handleEmergencyStop">
<template #icon><PauseCircleOutlined/></template><span>Break</span> <template #icon>
<PauseCircleOutlined />
</template><span>Break</span>
</Button> </Button>
</div> </div>
<div class="row"> <div class="row">
<DroneControlPopover <DroneControlPopover :visible="flyToPointPopoverData.visible" :loading="flyToPointPopoverData.loading"
:visible="flyToPointPopoverData.visible" @confirm="($event) => onFlyToConfirm(true)" @cancel="($event) => onFlyToConfirm(false)">
:loading="flyToPointPopoverData.loading"
@confirm="($event) => onFlyToConfirm(true)"
@cancel="($event) =>onFlyToConfirm(false)"
>
<template #formContent> <template #formContent>
<div class="form-content"> <div class="form-content">
<div> <div>
<span class="form-label">latitude:</span> <span class="form-label">latitude:</span>
<a-input-number v-model:value="flyToPointPopoverData.latitude"/> <a-input-number v-model:value="flyToPointPopoverData.latitude" />
</div> </div>
<div> <div>
<span class="form-label">longitude:</span> <span class="form-label">longitude:</span>
<a-input-number v-model:value="flyToPointPopoverData.longitude"/> <a-input-number v-model:value="flyToPointPopoverData.longitude" />
</div> </div>
<div> <div>
<span class="form-label">height(m):</span> <span class="form-label">height(m):</span>
<a-input-number v-model:value="flyToPointPopoverData.height"/> <a-input-number v-model:value="flyToPointPopoverData.height" />
</div> </div>
</div> </div>
</template> </template>
<Button size="small" ghost @click="onShowFlyToPopover" > <Button size="small" ghost @click="onShowFlyToPopover">
<span>Fly to</span> <span>Fly to</span>
</Button> </Button>
</DroneControlPopover> </DroneControlPopover>
<Button size="small" ghost @click="onStopFlyToPoint" > <Button size="small" ghost @click="onStopFlyToPoint">
<span>Stop Fly to</span> <span>Stop Fly to</span>
</Button> </Button>
<DroneControlPopover <DroneControlPopover :visible="takeoffToPointPopoverData.visible" :loading="takeoffToPointPopoverData.loading"
:visible="takeoffToPointPopoverData.visible" @confirm="($event) => onTakeoffToPointConfirm(true)" @cancel="($event) => onTakeoffToPointConfirm(false)">
:loading="takeoffToPointPopoverData.loading"
@confirm="($event) => onTakeoffToPointConfirm(true)"
@cancel="($event) =>onTakeoffToPointConfirm(false)"
>
<template #formContent> <template #formContent>
<div class="form-content"> <div class="form-content">
<div> <div>
<span class="form-label">latitude:</span> <span class="form-label">latitude:</span>
<a-input-number v-model:value="takeoffToPointPopoverData.latitude"/> <a-input-number v-model:value="takeoffToPointPopoverData.latitude" />
</div> </div>
<div> <div>
<span class="form-label">longitude:</span> <span class="form-label">longitude:</span>
<a-input-number v-model:value="takeoffToPointPopoverData.longitude"/> <a-input-number v-model:value="takeoffToPointPopoverData.longitude" />
</div> </div>
<div> <div>
<span class="form-label">height(m):</span> <span class="form-label">height(m):</span>
<a-input-number v-model:value="takeoffToPointPopoverData.height"/> <a-input-number v-model:value="takeoffToPointPopoverData.height" />
</div> </div>
<div> <div>
<span class="form-label">Safe Takeoff Altitude(m):</span> <span class="form-label">Safe Takeoff Altitude(m):</span>
<a-input-number v-model:value="takeoffToPointPopoverData.securityTakeoffHeight"/> <a-input-number v-model:value="takeoffToPointPopoverData.securityTakeoffHeight" />
</div> </div>
<div> <div>
<span class="form-label">Return-to-Home Altitude(m):</span> <span class="form-label">Return-to-Home Altitude(m):</span>
<a-input-number v-model:value="takeoffToPointPopoverData.rthAltitude"/> <a-input-number v-model:value="takeoffToPointPopoverData.rthAltitude" />
</div> </div>
<div> <div>
<span class="form-label">Lost Action:</span> <span class="form-label">Lost Action:</span>
<a-select <a-select v-model:value="takeoffToPointPopoverData.rcLostAction" style="width: 120px"
v-model:value="takeoffToPointPopoverData.rcLostAction" :options="LostControlActionInCommandFLightOptions"></a-select>
style="width: 120px"
:options="LostControlActionInCommandFLightOptions"
></a-select>
</div> </div>
<div> <div>
<span class="form-label">Wayline Lost Action:</span> <span class="form-label">Wayline Lost Action:</span>
<a-select <a-select v-model:value="takeoffToPointPopoverData.exitWaylineWhenRcLost" style="width: 120px"
v-model:value="takeoffToPointPopoverData.exitWaylineWhenRcLost" :options="WaylineLostControlActionInCommandFlightOptions"></a-select>
style="width: 120px"
:options="WaylineLostControlActionInCommandFlightOptions"
></a-select>
</div> </div>
<div> <div>
<span class="form-label">Return-to-Home Mode:</span> <span class="form-label">Return-to-Home Mode:</span>
<a-select <a-select v-model:value="takeoffToPointPopoverData.rthMode" style="width: 120px"
v-model:value="takeoffToPointPopoverData.rthMode" :options="RthModeInCommandFlightOptions"></a-select>
style="width: 120px"
:options="RthModeInCommandFlightOptions"
></a-select>
</div> </div>
<div> <div>
<span class="form-label">Commander Mode Lost Action:</span> <span class="form-label">Commander Mode Lost Action:</span>
<a-select <a-select v-model:value="takeoffToPointPopoverData.commanderModeLostAction" style="width: 120px"
v-model:value="takeoffToPointPopoverData.commanderModeLostAction" :options="CommanderModeLostActionInCommandFlightOptions"></a-select>
style="width: 120px"
:options="CommanderModeLostActionInCommandFlightOptions"
></a-select>
</div> </div>
<div> <div>
<span class="form-label">Commander Flight Mode:</span> <span class="form-label">Commander Flight Mode:</span>
<a-select <a-select v-model:value="takeoffToPointPopoverData.commanderFlightMode" style="width: 120px"
v-model:value="takeoffToPointPopoverData.commanderFlightMode" :options="CommanderFlightModeInCommandFlightOptions"></a-select>
style="width: 120px"
:options="CommanderFlightModeInCommandFlightOptions"
></a-select>
</div> </div>
<div> <div>
<span class="form-label">Commander Flight Height(m):</span> <span class="form-label">Commander Flight Height(m):</span>
<a-input-number v-model:value="takeoffToPointPopoverData.commanderFlightHeight"/> <a-input-number v-model:value="takeoffToPointPopoverData.commanderFlightHeight" />
</div> </div>
</div> </div>
</template> </template>
<Button size="small" ghost @click="onShowTakeoffToPointPopover" > <Button size="small" ghost @click="onShowTakeoffToPointPopover">
<span>Take off</span> <span>Take off</span>
</Button> </Button>
<div v-for="(cmdItem) in cmdList" :key="cmdItem.cmdKey" class="control-cmd-item"> <div v-for="(cmdItem) in cmdList" :key="cmdItem.cmdKey" class="control-cmd-item">
@ -151,115 +147,95 @@
</Button> </Button>
</div> </div>
<div> <div>
<Button size="small" ghost @click="openLivestreamAgora" > <Button size="small" ghost @click="openLivestreamAgora">
<span>Agora Live</span> <span>Agora Live</span>
</Button> </Button>
<Button size="small" ghost @click="openLivestreamOthers" > <Button size="small" ghost @click="openLivestreamOthers">
<span>RTMP/GB28181 Live</span> <span>RTMP/GB28181 Live</span>
</Button> </Button>
</div> </div>
</DroneControlPopover> </DroneControlPopover>
</div> </div>
</div>
<div class="box">
<div class="row">
<Select v-model:value="payloadSelectInfo.value" style="width: 110px; marginRight: 5px" :options="payloadSelectInfo.options" @change="handlePayloadChange"/>
<div class="drone-control">
<Button type="primary" size="small" @click="onAuthPayload">Payload Control</Button>
</div>
</div> </div>
<div class="row"> <div class="box">
<DroneControlPopover <div class="row">
:visible="gimbalResetPopoverData.visible" <Select v-model:value="payloadSelectInfo.value" style="width: 110px; margin-right: 5px"
:loading="gimbalResetPopoverData.loading" :options="payloadSelectInfo.options" @change="handlePayloadChange" />
@confirm="($event) => onGimbalResetConfirm(true)" <div class="drone-control">
@cancel="($event) =>onGimbalResetConfirm(false)" <Button type="primary" size="small" @click="onAuthPayload">Payload Control</Button>
> </div>
<template #formContent> </div>
<div class="form-content"> <div class="row">
<div> <DroneControlPopover :visible="gimbalResetPopoverData.visible" :loading="gimbalResetPopoverData.loading"
<span class="form-label">reset mode:</span> @confirm="($event) => onGimbalResetConfirm(true)" @cancel="($event) => onGimbalResetConfirm(false)">
<a-select <template #formContent>
v-model:value="gimbalResetPopoverData.resetMode" <div class="form-content">
style="width: 180px" <div>
:options="GimbalResetModeOptions" <span class="form-label">reset mode:</span>
></a-select> <a-select v-model:value="gimbalResetPopoverData.resetMode" style="width: 180px"
:options="GimbalResetModeOptions"></a-select>
</div>
</div> </div>
</div> </template>
</template> <Button size="small" ghost @click="onShowGimbalResetPopover">
<Button size="small" ghost @click="onShowGimbalResetPopover"> <span>Gimbal Reset</span>
<span>Gimbal Reset</span> </Button>
</DroneControlPopover>
<Button size="small" ghost @click="onSwitchCameraMode">
<span>Camera Mode Switch</span>
</Button> </Button>
</DroneControlPopover> </div>
<Button size="small" ghost @click="onSwitchCameraMode"> <div class="row">
<span>Camera Mode Switch</span> <Button size="small" ghost @click="onStartCameraRecording">
</Button> <span>Start Recording</span>
</div>
<div class="row">
<Button size="small" ghost @click="onStartCameraRecording">
<span>Start Recording</span>
</Button>
<Button size="small" ghost @click="onStopCameraRecording">
<span>Stop Recording</span>
</Button>
</div>
<div class="row">
<Button size="small" ghost @click="onTakeCameraPhoto">
<span>Take Photo</span>
</Button>
<DroneControlPopover
:visible="zoomFactorPopoverData.visible"
:loading="zoomFactorPopoverData.loading"
@confirm="($event) => onZoomFactorConfirm(true)"
@cancel="($event) =>onZoomFactorConfirm(false)"
>
<template #formContent>
<div class="form-content">
<div>
<span class="form-label">camera type:</span>
<a-select
v-model:value="zoomFactorPopoverData.cameraType"
style="width: 120px"
:options="ZoomCameraTypeOptions"
></a-select>
</div>
<div>
<span class="form-label">zoom factor:</span>
<a-input-number v-model:value="zoomFactorPopoverData.zoomFactor" :min="2" :max="200" />
</div>
</div>
</template>
<Button size="small" ghost @click="($event) => onShowZoomFactorPopover()">
<span class="word" @click=";">Zoom</span>
</Button> </Button>
</DroneControlPopover> <Button size="small" ghost @click="onStopCameraRecording">
<DroneControlPopover <span>Stop Recording</span>
:visible="cameraAimPopoverData.visible" </Button>
:loading="cameraAimPopoverData.loading" </div>
@confirm="($event) => onCameraAimConfirm(true)" <div class="row">
@cancel="($event) =>onCameraAimConfirm(false)" <Button size="small" ghost @click="onTakeCameraPhoto">
> <span>Take Photo</span>
</Button>
<DroneControlPopover :visible="zoomFactorPopoverData.visible" :loading="zoomFactorPopoverData.loading"
@confirm="($event) => onZoomFactorConfirm(true)" @cancel="($event) => onZoomFactorConfirm(false)">
<template #formContent>
<div class="form-content">
<div>
<span class="form-label">camera type:</span>
<a-select v-model:value="zoomFactorPopoverData.cameraType" style="width: 120px"
:options="ZoomCameraTypeOptions"></a-select>
</div>
<div>
<span class="form-label">zoom factor:</span>
<a-input-number v-model:value="zoomFactorPopoverData.zoomFactor" :min="2" :max="200" />
</div>
</div>
</template>
<Button size="small" ghost @click="($event) => onShowZoomFactorPopover()">
<span class="word" @click=";">Zoom</span>
</Button>
</DroneControlPopover>
<DroneControlPopover :visible="cameraAimPopoverData.visible" :loading="cameraAimPopoverData.loading"
@confirm="($event) => onCameraAimConfirm(true)" @cancel="($event) => onCameraAimConfirm(false)">
<template #formContent> <template #formContent>
<div class="form-content"> <div class="form-content">
<div> <div>
<span class="form-label">camera type:</span> <span class="form-label">camera type:</span>
<a-select <a-select v-model:value="cameraAimPopoverData.cameraType" style="width: 120px"
v-model:value="cameraAimPopoverData.cameraType" :options="CameraTypeOptions"></a-select>
style="width: 120px"
:options="CameraTypeOptions"
></a-select>
</div> </div>
<div> <div>
<span class="form-label">locked:</span> <span class="form-label">locked:</span>
<a-switch v-model:checked="cameraAimPopoverData.locked"/> <a-switch v-model:checked="cameraAimPopoverData.locked" />
</div> </div>
<div> <div>
<span class="form-label">x:</span> <span class="form-label">x:</span>
<a-input-number v-model:value="cameraAimPopoverData.x" :min="0" :max="1"/> <a-input-number v-model:value="cameraAimPopoverData.x" :min="0" :max="1" />
</div> </div>
<div> <div>
<span class="form-label">y:</span> <span class="form-label">y:</span>
<a-input-number v-model:value="cameraAimPopoverData.y" :min="0" :max="1"/> <a-input-number v-model:value="cameraAimPopoverData.y" :min="0" :max="1" />
</div> </div>
</div> </div>
</template> </template>
@ -267,9 +243,9 @@
<span class="word" @click=";">AIM</span> <span class="word" @click=";">AIM</span>
</Button> </Button>
</DroneControlPopover> </DroneControlPopover>
</div>
</div> </div>
</div> </div>
</div>
<!-- 信息提示 --> <!-- 信息提示 -->
<DroneControlInfoPanel :message="drcInfo"></DroneControlInfoPanel> <DroneControlInfoPanel :message="drcInfo"></DroneControlInfoPanel>
</div> </div>
@ -420,11 +396,11 @@ function onShowTakeoffToPointPopover () {
async function onTakeoffToPointConfirm (confirm: boolean) { async function onTakeoffToPointConfirm (confirm: boolean) {
if (confirm) { if (confirm) {
if (!takeoffToPointPopoverData.height || if (!takeoffToPointPopoverData.height ||
!takeoffToPointPopoverData.latitude || !takeoffToPointPopoverData.latitude ||
!takeoffToPointPopoverData.longitude || !takeoffToPointPopoverData.longitude ||
!takeoffToPointPopoverData.securityTakeoffHeight || !takeoffToPointPopoverData.securityTakeoffHeight ||
!takeoffToPointPopoverData.rthAltitude || !takeoffToPointPopoverData.rthAltitude ||
!takeoffToPointPopoverData.commanderFlightHeight) { !takeoffToPointPopoverData.commanderFlightHeight) {
message.error('Input error') message.error('Input error')
return return
} }
@ -772,10 +748,10 @@ watch(() => errorInfo, (errorInfo) => {
</script> </script>
<style lang='scss' scoped> <style lang='scss' scoped>
.drone-control-wrapper{ .drone-control-wrapper {
// border-bottom: 1px solid #515151; // border-bottom: 1px solid #515151;
.drone-control-header{ .drone-control-header {
font-size: 14px; font-size: 14px;
font-weight: 600; font-weight: 600;
padding: 10px 10px 0px; padding: 10px 10px 0px;
@ -784,39 +760,35 @@ watch(() => errorInfo, (errorInfo) => {
.drone-control-box { .drone-control-box {
display: flex; display: flex;
flex-wrap: 1; flex-wrap: 1;
.box { .box {
width: 50%; width: 50%;
padding: 5px; padding: 5px;
border: 0.5px solid rgba(255,255,255,0.3); border: 0.5px solid rgba(255, 255, 255, 0.3);
.row { .row {
display: flex; display: flex;
flex-wrap: wrap; flex-wrap: wrap;
padding: 2px; padding: 2px;
+ .row{ +.row {
margin-bottom: 6px; margin-bottom: 6px;
} }
&::v-deep{ :deep(.ant-btn) {
.ant-btn{ font-size: 12px;
font-size: 12px; padding: 0px 4px;
padding: 0px 4px; margin-right: 5px;
margin-right: 5px;
}
} }
} }
.drone-control{ .drone-control {
&::v-deep{ :deep(.ant-select-single:not(.ant-select-customize-input) .ant-select-selector) {
padding: 0 2px;
.ant-select-single:not(.ant-select-customize-input) .ant-select-selector{
padding: 0 2px;
}
} }
} }
.drone-control-direction{ .drone-control-direction {
margin-right: 10px; margin-right: 10px;
.ant-btn { .ant-btn {
@ -824,7 +796,7 @@ watch(() => errorInfo, (errorInfo) => {
margin-right: 0; margin-right: 0;
} }
.word{ .word {
width: 12px; width: 12px;
margin-left: 2px; margin-left: 2px;
font-size: 12px; font-size: 12px;

45
src/components/g-map/DroneControlPopover.vue

@ -1,25 +1,15 @@
<template> <template>
<a-popover :visible="state.sVisible" <a-popover :visible="state.sVisible" trigger="click" v-bind="$attrs" :overlay-class-name="overlayClassName"
trigger="click" placement="bottom" @visibleChange=";" v-on="$attrs">
v-bind="$attrs"
:overlay-class-name="overlayClassName"
placement="bottom"
@visibleChange=";"
v-on="$attrs">
<template #content> <template #content>
<div class="title-content"> <div class="title-content">
</div> </div>
<slot name="formContent" /> <slot name="formContent" />
<div class="uranus-popconfirm-btns"> <div class="uranus-popconfirm-btns">
<a-button size="sm" <a-button size="sm" @click="onCancel">
@click="onCancel"> {{ cancelText || 'cancel' }}
{{ cancelText || 'cancel'}}
</a-button> </a-button>
<a-button size="sm" <a-button size="sm" :loading="loading" type="primary" class="confirm-btn" @click="onConfirm">
:loading="loading"
type="primary"
class="confirm-btn"
@click="onConfirm">
{{ okText || 'ok' }} {{ okText || 'ok' }}
</a-button> </a-button>
</div> </div>
@ -34,13 +24,13 @@
import { defineProps, defineEmits, reactive, watch, computed } from 'vue' import { defineProps, defineEmits, reactive, watch, computed } from 'vue'
const props = defineProps<{ const props = defineProps<{
visible?: boolean, visible?: boolean,
loading?: Boolean, loading?: Boolean,
disabled?: Boolean, disabled?: Boolean,
title?: String, title?: String,
okText?: String, okText?: String,
cancelText?: String, cancelText?: String,
width?: Number, width?: Number,
}>() }>()
const emit = defineEmits(['cancel', 'confirm']) const emit = defineEmits(['cancel', 'confirm'])
@ -84,21 +74,21 @@ function onCancel (e: Event) {
.drone-control-popconfirm { .drone-control-popconfirm {
min-width: 300px; min-width: 300px;
.uranus-popconfirm-btns{ .uranus-popconfirm-btns {
display: flex; display: flex;
padding: 10px 0px; padding: 10px 0px;
justify-content: flex-end; justify-content: flex-end;
.confirm-btn{ .confirm-btn {
margin-left: 10px; margin-left: 10px;
} }
} }
.form-content{ .form-content {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
> div { >div {
display: flex; display: flex;
margin-bottom: 5px; margin-bottom: 5px;
@ -106,9 +96,6 @@ function onCancel (e: Event) {
flex: 1 0 60px; flex: 1 0 60px;
margin-right: 10px; margin-right: 10px;
} }
> div {
}
} }
} }
} }

82
src/components/livestream-agora.vue

@ -6,38 +6,19 @@
<template v-if="livePara.liveState && dronePara.isDockLive"> <template v-if="livePara.liveState && dronePara.isDockLive">
<span class="mr10">Lens:</span> <span class="mr10">Lens:</span>
<a-radio-group v-model:value="dronePara.lensSelected" button-style="solid"> <a-radio-group v-model:value="dronePara.lensSelected" button-style="solid">
<a-radio-button v-for="lens in dronePara.lensList" :key="lens" :value="lens">{{lens}}</a-radio-button> <a-radio-button v-for="lens in dronePara.lensList" :key="lens" :value="lens">{{ lens }}</a-radio-button>
</a-radio-group> </a-radio-group>
</template> </template>
<template v-else> <template v-else>
<a-select <a-select style="width:150px" placeholder="Select Drone" v-model:value="dronePara.droneSelected">
style="width:150px" <a-select-option v-for="item in dronePara.droneList" :key="item.value" :value="item.value"
placeholder="Select Drone" @click="onDroneSelect(item)">{{ item.label }}</a-select-option>
v-model:value="dronePara.droneSelected" </a-select>
> <a-select class="ml10" style="width:150px" placeholder="Select Camera" v-model:value="dronePara.cameraSelected">
<a-select-option <a-select-option v-for="item in dronePara.cameraList" :key="item.value" :value="item.value"
v-for="item in dronePara.droneList" @click="onCameraSelect(item)">{{ item.label }}</a-select-option>
:key="item.value" </a-select>
:value="item.value" <!-- <a-select
@click="onDroneSelect(item)"
>{{ item.label }}</a-select-option
>
</a-select>
<a-select
class="ml10"
style="width:150px"
placeholder="Select Camera"
v-model:value="dronePara.cameraSelected"
>
<a-select-option
v-for="item in dronePara.cameraList"
:key="item.value"
:value="item.value"
@click="onCameraSelect(item)"
>{{ item.label }}</a-select-option
>
</a-select>
<!-- <a-select
class="ml10" class="ml10"
style="width:150px" style="width:150px"
placeholder="Select Lens" placeholder="Select Lens"
@ -51,18 +32,9 @@
> >
</a-select> --> </a-select> -->
</template> </template>
<a-select <a-select class="ml10" style="width:150px" placeholder="Select Clarity" @select="onClaritySelect">
class="ml10" <a-select-option v-for="item in clarityList" :key="item.value" :value="item.value">{{ item.label
style="width:150px" }}</a-select-option>
placeholder="Select Clarity"
@select="onClaritySelect"
>
<a-select-option
v-for="item in clarityList"
:key="item.value"
:value="item.value"
>{{ item.label }}</a-select-option
>
</a-select> </a-select>
</div> </div>
<p class="fz16 mt10"> <p class="fz16 mt10">
@ -72,30 +44,18 @@
<span class="mr10">AppId:</span> <span class="mr10">AppId:</span>
<a-input v-model:value="agoraPara.appid" placeholder="APP ID"></a-input> <a-input v-model:value="agoraPara.appid" placeholder="APP ID"></a-input>
<span class="ml10">Token:</span> <span class="ml10">Token:</span>
<a-input <a-input class="ml10" v-model:value="agoraPara.token" placeholder="Token"></a-input>
class="ml10"
v-model:value="agoraPara.token"
placeholder="Token"
></a-input>
<span class="ml10">Channel:</span> <span class="ml10">Channel:</span>
<a-input <a-input class="ml10" v-model:value="agoraPara.channel" placeholder="Channel"></a-input>
class="ml10"
v-model:value="agoraPara.channel"
placeholder="Channel"
></a-input>
</div> </div>
<div class="mt20 flex-row flex-justify-center flex-align-center"> <div class="mt20 flex-row flex-justify-center flex-align-center">
<a-button v-if="livePara.liveState && dronePara.isDockLive" type="primary" large @click="onSwitch">Switch Lens</a-button> <a-button v-if="livePara.liveState && dronePara.isDockLive" type="primary" large @click="onSwitch">Switch
Lens</a-button>
<a-button v-else type="primary" large @click="onStart">Play</a-button> <a-button v-else type="primary" large @click="onStart">Play</a-button>
<a-button class="ml20" type="primary" large @click="onStop" <a-button class="ml20" type="primary" large @click="onStop">Stop</a-button>
>Stop</a-button <a-button class="ml20" type="primary" large @click="onUpdateQuality">Update Clarity</a-button>
> <a-button v-if="!livePara.liveState || !dronePara.isDockLive" class="ml20" type="primary" large
<a-button class="ml20" type="primary" large @click="onUpdateQuality" @click="onRefresh">Refresh Live Capacity</a-button>
>Update Clarity</a-button
>
<a-button v-if="!livePara.liveState || !dronePara.isDockLive" class="ml20" type="primary" large @click="onRefresh"
>Refresh Live Capacity</a-button
>
</div> </div>
</div> </div>
</template> </template>

58
src/components/task/TaskPanel.vue

@ -20,13 +20,13 @@
<template #status="{ record }"> <template #status="{ record }">
<div> <div>
<div class="flex-display flex-align-center"> <div class="flex-display flex-align-center">
<span class="circle-icon" :style="{backgroundColor: formatTaskStatus(record).color}"></span> <span class="circle-icon" :style="{ backgroundColor: formatTaskStatus(record).color }"></span>
{{ formatTaskStatus(record).text }} {{ formatTaskStatus(record).text }}
<a-tooltip v-if="!!record.code" placement="bottom" arrow-point-at-center > <a-tooltip v-if="!!record.code" placement="bottom" arrow-point-at-center>
<template #title> <template #title>
<div>{{ getCodeMessage(record.code) }}</div> <div>{{ getCodeMessage(record.code) }}</div>
</template> </template>
<exclamation-circle-outlined class="ml5" :style="{color: commonColor.WARN, fontSize: '16px' }"/> <exclamation-circle-outlined class="ml5" :style="{ color: commonColor.WARN, fontSize: '16px' }" />
</a-tooltip> </a-tooltip>
</div> </div>
<div v-if="record.status === TaskStatus.Carrying"> <div v-if="record.status === TaskStatus.Carrying">
@ -42,20 +42,22 @@
<template #lostAction="{ record }"> <template #lostAction="{ record }">
<div>{{ formatLostAction(record) }}</div> <div>{{ formatLostAction(record) }}</div>
</template> </template>
<!-- 媒体上传状态 --> <!-- 媒体上传状态 -->
<template #media_upload="{ record }"> <template #media_upload="{ record }">
<div> <div>
<div class="flex-display flex-align-center"> <div class="flex-display flex-align-center">
<span class="circle-icon" :style="{backgroundColor: formatMediaTaskStatus(record).color}"></span> <span class="circle-icon" :style="{ backgroundColor: formatMediaTaskStatus(record).color }"></span>
{{ formatMediaTaskStatus(record).text }} {{ formatMediaTaskStatus(record).text }}
</div> </div>
<div class="pl15"> <div class="pl15">
{{ formatMediaTaskStatus(record).number }} {{ formatMediaTaskStatus(record).number }}
<a-tooltip v-if="formatMediaTaskStatus(record).status === MediaStatus.ToUpload" placement="bottom" arrow-point-at-center > <a-tooltip v-if="formatMediaTaskStatus(record).status === MediaStatus.ToUpload" placement="bottom"
arrow-point-at-center>
<template #title> <template #title>
<div>Upload now</div> <div>Upload now</div>
</template> </template>
<UploadOutlined class="ml5" :style="{color: commonColor.BLUE, fontSize: '16px' }" @click="onUploadMediaFileNow(record.job_id)"/> <UploadOutlined class="ml5" :style="{ color: commonColor.BLUE, fontSize: '16px' }"
@click="onUploadMediaFileNow(record.job_id)" />
</a-tooltip> </a-tooltip>
</div> </div>
</div> </div>
@ -63,31 +65,16 @@
<!-- 操作 --> <!-- 操作 -->
<template #action="{ record }"> <template #action="{ record }">
<div class="action-area"> <div class="action-area">
<a-popconfirm <a-popconfirm v-if="record.status === TaskStatus.Wait" title="Are you sure you want to delete flight task?"
v-if="record.status === TaskStatus.Wait" ok-text="Yes" cancel-text="No" @confirm="onDeleteTask(record.job_id)">
title="Are you sure you want to delete flight task?"
ok-text="Yes"
cancel-text="No"
@confirm="onDeleteTask(record.job_id)"
>
<a-button type="primary" size="small">Delete</a-button> <a-button type="primary" size="small">Delete</a-button>
</a-popconfirm> </a-popconfirm>
<a-popconfirm <a-popconfirm v-if="record.status === TaskStatus.Carrying" title="Are you sure you want to suspend?"
v-if="record.status === TaskStatus.Carrying" ok-text="Yes" cancel-text="No" @confirm="onSuspendTask(record.job_id)">
title="Are you sure you want to suspend?"
ok-text="Yes"
cancel-text="No"
@confirm="onSuspendTask(record.job_id)"
>
<a-button type="primary" size="small">Suspend</a-button> <a-button type="primary" size="small">Suspend</a-button>
</a-popconfirm> </a-popconfirm>
<a-popconfirm <a-popconfirm v-if="record.status === TaskStatus.Paused" title="Are you sure you want to resume?"
v-if="record.status === TaskStatus.Paused" ok-text="Yes" cancel-text="No" @confirm="onResumeTask(record.job_id)">
title="Are you sure you want to resume?"
ok-text="Yes"
cancel-text="No"
@confirm="onResumeTask(record.job_id)"
>
<a-button type="primary" size="small">Resume</a-button> <a-button type="primary" size="small">Resume</a-button>
</a-popconfirm> </a-popconfirm>
</div> </div>
@ -328,17 +315,17 @@ async function onUploadMediaFileNow (jobId: string) {
.plan-panel-wrapper { .plan-panel-wrapper {
width: 100%; width: 100%;
padding: 16px; padding: 16px;
.plan-table { .plan-table {
background: #fff; background: #fff;
margin-top: 10px; margin-top: 10px;
} }
.action-area { .action-area {
&::v-deep { :deep(.ant-btn) {
.ant-btn { margin-right: 10px;
margin-right: 10px; margin-bottom: 10px;
margin-bottom: 10px;
}
} }
} }
@ -352,6 +339,7 @@ async function onUploadMediaFileNow (jobId: string) {
flex-shrink: 0; flex-shrink: 0;
} }
} }
.header { .header {
width: 100%; width: 100%;
height: 60px; height: 60px;

30
src/types/device.ts

@ -22,7 +22,7 @@ export enum DOMAIN {
export enum DRONE_TYPE { export enum DRONE_TYPE {
M30 = 67, M30 = 67,
M300 = 60, M300 = 60,
Mavic3EnterpriseAdvanced= 77, Mavic3EnterpriseAdvanced = 77,
M350 = 89, M350 = 89,
M3D = 91, M3D = 91,
} }
@ -184,7 +184,7 @@ export interface OnlineDevice {
// 固件升级类型 // 固件升级类型
export enum DeviceFirmwareTypeEnum { export enum DeviceFirmwareTypeEnum {
ToUpgraded = 3, // 普通升级 ToUpgraded = 3, // 普通升级
ConsistencyUpgrade =2, // 一致性升级 ConsistencyUpgrade = 2, // 一致性升级
} }
// 固件升级状态 // 固件升级状态
@ -245,7 +245,7 @@ export interface OSDVisible {
is_dock: boolean, is_dock: boolean,
gateway_sn: string, gateway_sn: string,
gateway_callsign: string, gateway_callsign: string,
payloads: null | PayloadInfo [], payloads: null | PayloadInfo[],
} }
export interface GatewayOsd { export interface GatewayOsd {
@ -299,7 +299,11 @@ export interface DeviceOsd {
height_limit?: number;// 限高设置 height_limit?: number;// 限高设置
distance_limit_status?: DistanceLimitStatus;// 限远开关 distance_limit_status?: DistanceLimitStatus;// 限远开关
obstacle_avoidance?: ObstacleAvoidance;// 飞行器避障开关设置 obstacle_avoidance?: ObstacleAvoidance;// 飞行器避障开关设置
cameras?: DeviceOsdCamera[] cameras?: DeviceOsdCamera[],
storage: {
used: number,
total: number
}
} }
export enum NetworkStateTypeEnum { export enum NetworkStateTypeEnum {
@ -361,10 +365,6 @@ export interface DockBasicOsd {
is_calibration: number, is_calibration: number,
quality: number, quality: number,
}, },
storage?: {
total: number,
used: number,
},
mode_code: number, mode_code: number,
cover_state: number, cover_state: number,
supplement_light_state: number, supplement_light_state: number,
@ -382,6 +382,10 @@ export interface DockBasicOsd {
device_online_status: number, device_online_status: number,
device_paired: number, device_paired: number,
}, },
storage: {
total: number,
used: number,
},
// live_capacity?: LiveCapacity; // 直播能力 // live_capacity?: LiveCapacity; // 直播能力
// live_status?: Array<LiveStatus>; // 直播状态 // live_status?: Array<LiveStatus>; // 直播状态
} }
@ -402,7 +406,7 @@ export interface DockLinkOsd {
down_quality: string, down_quality: string,
frequency_band: number, frequency_band: number,
}, },
wireless_link?:{ // 图传链路<会包括4G和sdr信息 wireless_link?: { // 图传链路<会包括4G和sdr信息
dongle_number: number, // dongle 数量 dongle_number: number, // dongle 数量
['4g_link_state']: FourGLinkStateEnum, // 4g_link_state ['4g_link_state']: FourGLinkStateEnum, // 4g_link_state
sdr_link_state: SdrLinkStateEnum, // sdr链路连接状态 sdr_link_state: SdrLinkStateEnum, // sdr链路连接状态
@ -429,7 +433,7 @@ export interface DockWorkOsd {
activation_time: number, activation_time: number,
maintain_status?: { maintain_status?: {
maintain_status_array: MaintainStatus[] maintain_status_array: MaintainStatus[]
} },
electric_supply_voltage: number, electric_supply_voltage: number,
working_voltage: string, working_voltage: string,
working_current: string, working_current: string,
@ -437,17 +441,17 @@ export interface DockWorkOsd {
voltage: number, voltage: number,
temperature: number, temperature: number,
switch: number, switch: number,
} },
drone_battery_maintenance_info?: { // 飞行器电池保养信息 drone_battery_maintenance_info?: { // 飞行器电池保养信息
maintenance_state: DroneBatteryStateEnum, // 保养状态 maintenance_state: DroneBatteryStateEnum, // 保养状态
maintenance_time_left: number, // 电池保养剩余时间(小时) maintenance_time_left: number, // 电池保养剩余时间(小时)
} },
} }
export interface DockOsd { export interface DockOsd {
basic_osd: DockBasicOsd, basic_osd: DockBasicOsd,
link_osd: DockLinkOsd, link_osd: DockLinkOsd,
work_osd: DockWorkOsd work_osd: DockWorkOsd,
} }
export enum EModeCode { export enum EModeCode {

19
src/types/mapLayer.ts

@ -1,4 +1,5 @@
import { MapElementEnum } from '/@/constants/map' import { MapElementEnum } from '/@/constants/map'
import { GeojsonFeature } from '/@/utils/genjson'
export interface mapLayerStyle { export interface mapLayerStyle {
background: string background: string
@ -38,7 +39,7 @@ export interface mapLayer {
style: mapLayerStyle style: mapLayerStyle
elements: any elements: any
} }
export interface elementGroupsReq{ export interface elementGroupsReq {
groupId: string groupId: string
isDistributed: boolean isDistributed: boolean
} }
@ -46,19 +47,9 @@ export interface PostElementsBody {
id: string id: string
name: string name: string
resource: { resource: {
type: MapElementEnum, type: MapElementEnum,
user_name?: string, user_name?: string,
content: { content: GeojsonFeature,
type:string,
properties:{
color:string,
clampToGround:boolean
},
geometry:{
type:string,
coordinates:unknown
}
},
} }
} }

90
src/utils/genjson.ts

@ -1,58 +1,68 @@
import { import { MapGeographicPosition } from '/@/types/map'
MapGeographicPosition,
} from '/@/types/map'
export type GeojsonCoordinate = [number, number, number?] export type GeojsonCoordinate = [number, number, number?]
export interface GeojsonLine { export interface GeojsonLine {
type: 'Feature' type: 'Feature'
properties: { properties: {
color: string color: string
directConnected?: boolean directConnected?: boolean
} }
geometry: { geometry: {
type: 'LineString' type: 'LineString'
coordinates: GeojsonCoordinate[] coordinates: GeojsonCoordinate[]
} }
} }
export interface GeojsonPolygon { export interface GeojsonPolygon {
type: 'Feature' type: 'Feature'
properties: { properties: {
color: string color: string
} }
geometry: { geometry: {
type: 'Polygon' type: 'Polygon'
coordinates: GeojsonCoordinate[][] coordinates: GeojsonCoordinate[][]
} }
} }
export interface GeojsonPoint { export interface GeojsonPoint {
type: 'Feature' type: 'Feature'
properties: { properties: {
color: string color: string
clampToGround?: boolean clampToGround?: boolean
} }
geometry: { geometry: {
type: 'Point' type: 'Point'
coordinates: GeojsonCoordinate coordinates: GeojsonCoordinate
} }
} }
export interface GeojsonCircle { export interface GeojsonCircle {
type: 'Feature' type: 'Feature'
properties: { properties: {
color: string color: string
clampToGround?: boolean clampToGround?: boolean
} }
geometry: { geometry: {
type: 'Circle' type: 'Circle'
coordinates: GeojsonCoordinate coordinates: GeojsonCoordinate
radius: number radius: number
} }
}
export interface contentType {
type: string,
properties: {
color: string,
clampToGround: boolean
},
geometry: {
type: string,
coordinates: unknown
}
} }
export type GeojsonFeature = GeojsonLine | GeojsonPolygon | GeojsonPoint | GeojsonCircle export type GeojsonFeature = GeojsonLine | GeojsonPolygon | GeojsonPoint | GeojsonCircle | contentType
export function geographic2Coordinate (position: MapGeographicPosition): GeojsonCoordinate { export function geographic2Coordinate (position: MapGeographicPosition): GeojsonCoordinate {
const coordinates: GeojsonCoordinate = [position.longitude, position.latitude] const coordinates: GeojsonCoordinate = [position.longitude, position.latitude]

34
src/vendors/coordtransform.js → src/vendors/coordtransform.ts vendored

@ -13,7 +13,7 @@ const ee = 0.00669342162296594323;
* @param lat * @param lat
* @returns {*[]} * @returns {*[]}
*/ */
export function wgs84togcj02(lng, lat) { export function wgs84togcj02(lng: number, lat: number) {
if (out_of_china(lng, lat)) { if (out_of_china(lng, lat)) {
return [lng, lat] return [lng, lat]
} }
@ -38,27 +38,27 @@ export function wgs84togcj02(lng, lat) {
* @param lat * @param lat
* @returns {*[]} * @returns {*[]}
*/ */
export function gcj02towgs84(lng, lat) { export function gcj02towgs84(lng: number, lat: number) {
var lat = +lat; var lat = +lat;
var lng = +lng; var lng = +lng;
if (out_of_china(lng, lat)) { if (out_of_china(lng, lat)) {
return [lng, lat] return [lng, lat]
} else { } else {
var dlat = transformlat(lng - 105.0, lat - 35.0); var dlat = transformlat(lng - 105.0, lat - 35.0);
var dlng = transformlng(lng - 105.0, lat - 35.0); var dlng = transformlng(lng - 105.0, lat - 35.0);
var radlat = lat / 180.0 * PI; var radlat = lat / 180.0 * PI;
var magic = Math.sin(radlat); var magic = Math.sin(radlat);
magic = 1 - ee * magic * magic; magic = 1 - ee * magic * magic;
var sqrtmagic = Math.sqrt(magic); var sqrtmagic = Math.sqrt(magic);
dlat = (dlat * 180.0) / ((a * (1 - ee)) / (magic * sqrtmagic) * PI); dlat = (dlat * 180.0) / ((a * (1 - ee)) / (magic * sqrtmagic) * PI);
dlng = (dlng * 180.0) / (a / sqrtmagic * Math.cos(radlat) * PI); dlng = (dlng * 180.0) / (a / sqrtmagic * Math.cos(radlat) * PI);
var mglat = lat + dlat; var mglat = lat + dlat;
var mglng = lng + dlng; var mglng = lng + dlng;
return [lng * 2 - mglng, lat * 2 - mglat] return [lng * 2 - mglng, lat * 2 - mglat]
} }
} }
function transformlat(lng, lat) { function transformlat(lng: number, lat: number) {
var ret = -100.0 + 2.0 * lng + 3.0 * lat + 0.2 * lat * lat + 0.1 * lng * lat + 0.2 * Math.sqrt(Math.abs(lng)); var ret = -100.0 + 2.0 * lng + 3.0 * lat + 0.2 * lat * lat + 0.1 * lng * lat + 0.2 * Math.sqrt(Math.abs(lng));
ret += (20.0 * Math.sin(6.0 * lng * PI) + 20.0 * Math.sin(2.0 * lng * PI)) * 2.0 / 3.0; ret += (20.0 * Math.sin(6.0 * lng * PI) + 20.0 * Math.sin(2.0 * lng * PI)) * 2.0 / 3.0;
ret += (20.0 * Math.sin(lat * PI) + 40.0 * Math.sin(lat / 3.0 * PI)) * 2.0 / 3.0; ret += (20.0 * Math.sin(lat * PI) + 40.0 * Math.sin(lat / 3.0 * PI)) * 2.0 / 3.0;
@ -66,7 +66,7 @@ function transformlat(lng, lat) {
return ret return ret
} }
export function transformlng(lng, lat) { export function transformlng(lng: number, lat: number) {
var ret = 300.0 + lng + 2.0 * lat + 0.1 * lng * lng + 0.1 * lng * lat + 0.1 * Math.sqrt(Math.abs(lng)); var ret = 300.0 + lng + 2.0 * lat + 0.1 * lng * lng + 0.1 * lng * lat + 0.1 * Math.sqrt(Math.abs(lng));
ret += (20.0 * Math.sin(6.0 * lng * PI) + 20.0 * Math.sin(2.0 * lng * PI)) * 2.0 / 3.0; ret += (20.0 * Math.sin(6.0 * lng * PI) + 20.0 * Math.sin(2.0 * lng * PI)) * 2.0 / 3.0;
ret += (20.0 * Math.sin(lng * PI) + 40.0 * Math.sin(lng / 3.0 * PI)) * 2.0 / 3.0; ret += (20.0 * Math.sin(lng * PI) + 40.0 * Math.sin(lng / 3.0 * PI)) * 2.0 / 3.0;
@ -80,6 +80,6 @@ export function transformlng(lng, lat) {
* @param lat * @param lat
* @returns {boolean} * @returns {boolean}
*/ */
function out_of_china(lng, lat) { function out_of_china(lng: number, lat: number) {
return (lng < 72.004 || lng > 137.8347) || ((lat < 0.8293 || lat > 55.8271) || false); return (lng < 72.004 || lng > 137.8347) || ((lat < 0.8293 || lat > 55.8271) || false);
} }

4677
yarn.lock

File diff suppressed because it is too large Load Diff
Loading…
Cancel
Save