Merge branch 'main' of http://123.132.248.154:10000/gitY/LinYeFangHuo
|
|
@ -129,6 +129,7 @@
|
|||
"moment": "^2.30.1",
|
||||
"monaco-editor": "^0.33.0",
|
||||
"monaco-editor-core": "^0.46.0",
|
||||
"mqtt": "^5.14.1",
|
||||
"naive-ui": "2.34.3",
|
||||
"nprogress": "^0.2.0",
|
||||
"path-to-regexp": "^6.2.1",
|
||||
|
|
|
|||
|
|
@ -0,0 +1,28 @@
|
|||
import { defHttp } from '@/utils/http/axios';
|
||||
|
||||
interface AddOrUpdateRedisUserParams {
|
||||
clientId?: string;
|
||||
userId?: string;
|
||||
userName?: string;
|
||||
connectTime?: string;
|
||||
isLock?: boolean;
|
||||
}
|
||||
|
||||
enum Api {
|
||||
GetRedisUser = '/api/AirportMaintenance/GetRedisUser',
|
||||
GetLockedClients = '/api/AirportMaintenance/GetLockedClients',
|
||||
AddOrUpdateRedisUser = '/api/AirportMaintenance/AddOrUpdateRedisUser',
|
||||
}
|
||||
|
||||
export function getRedisUser(id) {
|
||||
return defHttp.get({ url: Api.GetRedisUser + '?id=' + id });
|
||||
}
|
||||
|
||||
export function getLockedClients(params?: any) {
|
||||
return defHttp.get({ url: Api.GetLockedClients, params });
|
||||
}
|
||||
export const addOrUpdateRedisUser = (params: AddOrUpdateRedisUserParams) =>
|
||||
defHttp.post({
|
||||
url: Api.AddOrUpdateRedisUser,
|
||||
params,
|
||||
});
|
||||
|
After Width: | Height: | Size: 5.3 KiB |
|
After Width: | Height: | Size: 5.0 KiB |
|
After Width: | Height: | Size: 55 KiB |
|
After Width: | Height: | Size: 6.6 KiB |
|
After Width: | Height: | Size: 5.3 KiB |
|
After Width: | Height: | Size: 6.5 KiB |
|
After Width: | Height: | Size: 5.4 KiB |
|
After Width: | Height: | Size: 5.3 KiB |
|
After Width: | Height: | Size: 5.0 KiB |
|
After Width: | Height: | Size: 759 B |
|
After Width: | Height: | Size: 695 B |
|
After Width: | Height: | Size: 62 KiB |
|
After Width: | Height: | Size: 12 KiB |
|
After Width: | Height: | Size: 4.3 KiB |
|
After Width: | Height: | Size: 12 KiB |
|
After Width: | Height: | Size: 5.5 KiB |
|
After Width: | Height: | Size: 13 KiB |
|
After Width: | Height: | Size: 5.4 KiB |
|
After Width: | Height: | Size: 12 KiB |
|
After Width: | Height: | Size: 4.2 KiB |
|
After Width: | Height: | Size: 14 KiB |
|
After Width: | Height: | Size: 1.8 KiB |
|
|
@ -1,24 +1,33 @@
|
|||
<template>
|
||||
<div class="go-title-03">
|
||||
<div class="go-title-03">
|
||||
<div class="flex ai-c jc-sb max-w navsbox">
|
||||
<div class="flex navsli ai-c jc-c" v-for="(item,index) in navsArr" :class="index==navsIndex?'navsliactive':''" @click="navsClick(item,index)">
|
||||
<div
|
||||
class="flex navsli ai-c jc-c"
|
||||
v-for="(item, index) in navsArr"
|
||||
:class="index == navsIndex ? 'navsliactive' : ''"
|
||||
@click="navsClick(item, index)"
|
||||
>
|
||||
{{ item.label }}
|
||||
<span class="navsNum" v-if="item.value!=0">{{item.value}}</span>
|
||||
<span class="navsNum" v-if="item.value != 0">{{ item.value }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex column sectionBox">
|
||||
<div class="mt-1 sectionLi" v-for="(item,index) in sectionDatas" @click="handlerFireDetail(item)">
|
||||
<div
|
||||
class="mt-1 sectionLi"
|
||||
v-for="(item, index) in sectionDatas"
|
||||
@click="handlerFireDetail(item)"
|
||||
>
|
||||
<div class="flex jc-sb">
|
||||
<div class="titleText">{{item.describe}}</div>
|
||||
<div class="mr-2 desStyle">{{item.degreeType}}</div>
|
||||
<div class="titleText">{{ item.describe }}</div>
|
||||
<div class="mr-2 desStyle">{{ item.degreeType }}</div>
|
||||
</div>
|
||||
<div class="flex mt-1 ai-c">
|
||||
<img class="mr-1" src="@/assets/images/chart/equipment/address.png" />
|
||||
<div class="numStyle" :title="item.address">{{item.address}}</div>
|
||||
<div class="numStyle" :title="item.address">{{ item.address }}</div>
|
||||
</div>
|
||||
<div class="flex mt-1 ai-c">
|
||||
<img class="mr-1 timeicon" src="@/assets/images/chart/equipment/time.png" />
|
||||
<div class="numStyle">{{item.reportTime}}</div>
|
||||
<div class="numStyle">{{ item.reportTime }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -26,284 +35,276 @@
|
|||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { PropType, toRefs, ref,onMounted } from 'vue'
|
||||
import { CreateComponentType } from '@/packages/index.d'
|
||||
import { useChartDataFetch } from '@/hooks';
|
||||
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore';
|
||||
import * as mars3d from "mars3d";
|
||||
import { EventBus } from '@/utils/eventBus';
|
||||
import { PropType, toRefs, ref, onMounted } from 'vue';
|
||||
import { CreateComponentType } from '@/packages/index.d';
|
||||
import { useChartDataFetch } from '@/hooks';
|
||||
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore';
|
||||
import * as mars3d from 'mars3d';
|
||||
import { EventBus } from '@/utils/eventBus';
|
||||
|
||||
import { eventHandlerHook } from '@/hooks/eventHandler.hook';
|
||||
const chartEditStore = useChartEditStore();
|
||||
import { eventHandlerHook } from '@/hooks/eventHandler.hook';
|
||||
const chartEditStore = useChartEditStore();
|
||||
|
||||
const props = defineProps({
|
||||
chartConfig: {
|
||||
type: Object as PropType<CreateComponentType>,
|
||||
required: true
|
||||
}
|
||||
})
|
||||
const props = defineProps({
|
||||
chartConfig: {
|
||||
type: Object as PropType<CreateComponentType>,
|
||||
required: true,
|
||||
},
|
||||
});
|
||||
|
||||
const navsIndex = ref(0)
|
||||
const { w, h } = toRefs(props.chartConfig.attr)
|
||||
const {
|
||||
navsArr,
|
||||
navsSize,
|
||||
navsColor,
|
||||
navsCheckSize,
|
||||
navsCheckColor,
|
||||
navsCheckBackground,
|
||||
navsBackground,
|
||||
titleSize,
|
||||
titleColor,
|
||||
sectionDatas,
|
||||
desColor,
|
||||
desSize,
|
||||
datasColor,
|
||||
datasSize
|
||||
} = toRefs(props.chartConfig.option)
|
||||
const navsIndex = ref(0);
|
||||
const { w, h } = toRefs(props.chartConfig.attr);
|
||||
const {
|
||||
navsArr,
|
||||
navsSize,
|
||||
navsColor,
|
||||
navsCheckSize,
|
||||
navsCheckColor,
|
||||
navsCheckBackground,
|
||||
navsBackground,
|
||||
titleSize,
|
||||
titleColor,
|
||||
sectionDatas,
|
||||
desColor,
|
||||
desSize,
|
||||
datasColor,
|
||||
datasSize,
|
||||
} = toRefs(props.chartConfig.option);
|
||||
|
||||
const navsClick = function (item, index) {
|
||||
navsIndex.value = index;
|
||||
props.chartConfig.request.requestSQLContent.sql = item.sql;
|
||||
useChartDataFetch(props.chartConfig, useChartEditStore, (resData: any) => {
|
||||
props.chartConfig.option.sectionDatas = resData;
|
||||
});
|
||||
};
|
||||
// 数据callback处理(预览时触发)
|
||||
useChartDataFetch(props.chartConfig, useChartEditStore, (resData: any[]) => {
|
||||
props.chartConfig.option.sectionDatas = resData;
|
||||
});
|
||||
|
||||
onMounted(() => {
|
||||
// 加载火点
|
||||
setTimeout(function () {
|
||||
handlerLoadFirePoint(sectionDatas.value);
|
||||
}, 5000);
|
||||
});
|
||||
|
||||
const navsClick = function(item,index){
|
||||
navsIndex.value = index
|
||||
props.chartConfig.request.requestSQLContent.sql = item.sql
|
||||
useChartDataFetch(props.chartConfig, useChartEditStore, (resData: any) => {
|
||||
props.chartConfig.option.sectionDatas = resData
|
||||
})
|
||||
}
|
||||
// 数据callback处理(预览时触发)
|
||||
useChartDataFetch(props.chartConfig, useChartEditStore, (resData: any[]) => {
|
||||
props.chartConfig.option.sectionDatas = resData;
|
||||
});
|
||||
|
||||
|
||||
onMounted(()=>{
|
||||
// 加载火点
|
||||
setTimeout(function(){
|
||||
handlerLoadFirePoint(sectionDatas.value);
|
||||
},5000)
|
||||
})
|
||||
|
||||
// 加载火点信息
|
||||
const handlerLoadFirePoint = (points:[])=>{
|
||||
|
||||
points?.forEach((item,index)=>{
|
||||
let graphicOptions = {
|
||||
id:item.id,
|
||||
attr:item,
|
||||
position: [parseFloat(item.lng), parseFloat(item.lat)],
|
||||
style: {
|
||||
image: "/public/map/fire.png",
|
||||
clampToGround: true,
|
||||
scale: 0.8,
|
||||
label: {
|
||||
text: item.title,
|
||||
font_size: 12,
|
||||
color: "#ffffff",
|
||||
pixelOffsetY: -36,
|
||||
distanceDisplayCondition: true,
|
||||
distanceDisplayCondition_far: 500000,
|
||||
distanceDisplayCondition_near: 0,
|
||||
// 加载火点信息
|
||||
const handlerLoadFirePoint = (points: []) => {
|
||||
points?.forEach((item, index) => {
|
||||
let graphicOptions = {
|
||||
id: item.id,
|
||||
attr: item,
|
||||
position: [parseFloat(item.lng), parseFloat(item.lat)],
|
||||
style: {
|
||||
image: '/public/map/fire.png',
|
||||
clampToGround: true,
|
||||
scale: 0.8,
|
||||
label: {
|
||||
text: item.title,
|
||||
font_size: 12,
|
||||
color: '#ffffff',
|
||||
pixelOffsetY: -36,
|
||||
distanceDisplayCondition: true,
|
||||
distanceDisplayCondition_far: 500000,
|
||||
distanceDisplayCondition_near: 0,
|
||||
},
|
||||
},
|
||||
},
|
||||
popup: 'all',
|
||||
// `<div class="marsTiltPanel marsTiltPanel-theme-red" style="font-size:12px;">
|
||||
// <div class="marsTiltPanel-wrap">
|
||||
// <div class="area">
|
||||
// <div class="arrow-lt"></div>
|
||||
// <div class="b-t"></div>
|
||||
// <div class="b-r"></div>
|
||||
// <div class="b-b"></div>
|
||||
// <div class="b-l"></div>
|
||||
// <div class="arrow-rb"></div>
|
||||
// <div class="label-wrap">
|
||||
// <div class="title">火点信息</div>
|
||||
// <div class="label-content">
|
||||
// <div class="data-li">
|
||||
// <div class="data-label">火点地址:${item.position}</div>
|
||||
// </div>
|
||||
// <div class="data-li">
|
||||
// <div class="data-label">上报时间:</div>
|
||||
// <div class="data-value"><span id="lablYeWei" class="label-num">2025-2-11 12:00:00</span><span class="label-unit"></span>
|
||||
// </div>
|
||||
// </div>
|
||||
// </div>
|
||||
// </div>
|
||||
// </div>
|
||||
// <div class="b-t-l"></div>
|
||||
// <div class="b-b-r"></div>
|
||||
// </div>
|
||||
// <div class="arrow" ></div>
|
||||
// </div>`,
|
||||
popupOptions: {
|
||||
offsetY: -30,
|
||||
template: "{content}",
|
||||
horizontalOrigin: "Cesium.HorizontalOrigin.LEFT",
|
||||
verticalOrigin: "Cesium.VerticalOrigin.CENTER",
|
||||
},
|
||||
}
|
||||
popup: 'all',
|
||||
// `<div class="marsTiltPanel marsTiltPanel-theme-red" style="font-size:12px;">
|
||||
// <div class="marsTiltPanel-wrap">
|
||||
// <div class="area">
|
||||
// <div class="arrow-lt"></div>
|
||||
// <div class="b-t"></div>
|
||||
// <div class="b-r"></div>
|
||||
// <div class="b-b"></div>
|
||||
// <div class="b-l"></div>
|
||||
// <div class="arrow-rb"></div>
|
||||
// <div class="label-wrap">
|
||||
// <div class="title">火点信息</div>
|
||||
// <div class="label-content">
|
||||
// <div class="data-li">
|
||||
// <div class="data-label">火点地址:${item.position}</div>
|
||||
// </div>
|
||||
// <div class="data-li">
|
||||
// <div class="data-label">上报时间:</div>
|
||||
// <div class="data-value"><span id="lablYeWei" class="label-num">2025-2-11 12:00:00</span><span class="label-unit"></span>
|
||||
// </div>
|
||||
// </div>
|
||||
// </div>
|
||||
// </div>
|
||||
// </div>
|
||||
// <div class="b-t-l"></div>
|
||||
// <div class="b-b-r"></div>
|
||||
// </div>
|
||||
// <div class="arrow" ></div>
|
||||
// </div>`,
|
||||
popupOptions: {
|
||||
offsetY: -30,
|
||||
template: '{content}',
|
||||
horizontalOrigin: 'Cesium.HorizontalOrigin.LEFT',
|
||||
verticalOrigin: 'Cesium.VerticalOrigin.CENTER',
|
||||
},
|
||||
};
|
||||
|
||||
let graphic = new mars3d.graphic.BillboardEntity(graphicOptions);
|
||||
window.graphicLayer.addGraphic(graphic);
|
||||
})
|
||||
|
||||
window.graphicLayer.on(mars3d.EventType.click,function(e){
|
||||
handlerFireDetail(e.graphic.options.attr)
|
||||
})
|
||||
let graphic = new mars3d.graphic.BillboardEntity(graphicOptions);
|
||||
window.graphicLayer.addGraphic(graphic);
|
||||
});
|
||||
|
||||
}
|
||||
window.graphicLayer.on(mars3d.EventType.click, function (e) {
|
||||
handlerFireDetail(e.graphic.options.attr);
|
||||
});
|
||||
};
|
||||
|
||||
// 查看详情
|
||||
const handlerFireDetail = (item) => {
|
||||
|
||||
// 显示弹窗
|
||||
eventHandlerHook(
|
||||
chartEditStore.getComponentList,
|
||||
props.chartConfig.events.interactConfigEvents,
|
||||
'click',
|
||||
item
|
||||
);
|
||||
// 查看详情
|
||||
const handlerFireDetail = (item) => {
|
||||
console.log(item);
|
||||
// 显示弹窗
|
||||
eventHandlerHook(
|
||||
chartEditStore.getComponentList,
|
||||
props.chartConfig.events.interactConfigEvents,
|
||||
'click',
|
||||
item,
|
||||
);
|
||||
|
||||
// 更新详情弹窗信息
|
||||
let bindEvents = props.chartConfig.events.interactConfigEvents
|
||||
|
||||
console.log("bindEvents",bindEvents);
|
||||
for(let i=0;i<bindEvents.length;i++){
|
||||
for(let j=0;j<bindEvents[i].movementList.length;j++){
|
||||
EventBus.emit(bindEvents[i].movementList[j].elementId[j]+"dataupdate",item);
|
||||
// 更新详情弹窗信息
|
||||
let bindEvents = props.chartConfig.events.interactConfigEvents;
|
||||
|
||||
console.log('bindEvents', bindEvents);
|
||||
for (let i = 0; i < bindEvents.length; i++) {
|
||||
for (let j = 0; j < bindEvents[i].movementList.length; j++) {
|
||||
EventBus.emit(bindEvents[i].movementList[j].elementId[j] + 'dataupdate', item);
|
||||
}
|
||||
}
|
||||
let graphic = window.graphicLayer.getGraphicById(item.id);
|
||||
|
||||
if(graphic){
|
||||
window.globalMap.flyToGraphic(graphic,{radius:300});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
let graphic = window.graphicLayer.getGraphicById(item.id);
|
||||
|
||||
if (graphic) {
|
||||
window.globalMap.flyToGraphic(graphic, { radius: 300 });
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@include go('title-03') {
|
||||
height: v-bind('h');
|
||||
position: relative;
|
||||
padding-top:10px;
|
||||
scrollbar-width: none;
|
||||
-ms-overflow-style: none;
|
||||
.max-w{
|
||||
width: 100%;
|
||||
}
|
||||
.column{
|
||||
flex-direction: column;
|
||||
}
|
||||
.flex{
|
||||
display: flex;
|
||||
}
|
||||
.jc-sb{
|
||||
justify-content: space-between;
|
||||
}
|
||||
.jc-sa{
|
||||
justify-content: space-around;
|
||||
}
|
||||
.jc-c{
|
||||
justify-content: center;
|
||||
}
|
||||
.ai-c{
|
||||
align-items: center;
|
||||
}
|
||||
.img{
|
||||
width: 148px;
|
||||
height: 16px;
|
||||
}
|
||||
.navsbox{
|
||||
width: 92%;
|
||||
margin-left: 4%;
|
||||
height: 28px;
|
||||
background: v-bind('navsBackground');
|
||||
border-radius: 1px;
|
||||
border: 1px solid #4FE985;
|
||||
margin-bottom: 13px;
|
||||
display: flex;
|
||||
}
|
||||
.navsli{
|
||||
flex: 1;
|
||||
height: 25px;
|
||||
color: v-bind('navsColor');
|
||||
font-size: v-bind('navsSize+"px"');
|
||||
cursor: pointer;
|
||||
@include go('title-03') {
|
||||
height: v-bind('h');
|
||||
position: relative;
|
||||
}
|
||||
.navsNum{
|
||||
background: #F91B1B;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
border-radius: 20px;
|
||||
text-align: center;
|
||||
line-height:20px;
|
||||
color: #fff;
|
||||
font-size: 8px;
|
||||
position: absolute;
|
||||
left: 60%;
|
||||
top: 0;
|
||||
margin-top: -10px;
|
||||
}
|
||||
.navsliactive{
|
||||
color: v-bind('navsCheckColor');
|
||||
font-size: v-bind('navsCheckSize+"px"');
|
||||
background: v-bind('navsCheckBackground');
|
||||
}
|
||||
.sectionBox{
|
||||
width: 92%;
|
||||
height: calc(100% - 40px);
|
||||
margin-left: 4%;
|
||||
overflow: auto;
|
||||
img{
|
||||
width: 21px;
|
||||
height: 21px;
|
||||
padding-top: 10px;
|
||||
scrollbar-width: none;
|
||||
-ms-overflow-style: none;
|
||||
.max-w {
|
||||
width: 100%;
|
||||
}
|
||||
.timeicon{
|
||||
width: 15px;
|
||||
height: 15px;
|
||||
margin-left: 3px;
|
||||
.column {
|
||||
flex-direction: column;
|
||||
}
|
||||
.flex {
|
||||
display: flex;
|
||||
}
|
||||
.jc-sb {
|
||||
justify-content: space-between;
|
||||
}
|
||||
.jc-sa {
|
||||
justify-content: space-around;
|
||||
}
|
||||
.jc-c {
|
||||
justify-content: center;
|
||||
}
|
||||
.ai-c {
|
||||
align-items: center;
|
||||
}
|
||||
.img {
|
||||
width: 148px;
|
||||
height: 16px;
|
||||
}
|
||||
.navsbox {
|
||||
width: 92%;
|
||||
margin-left: 4%;
|
||||
height: 28px;
|
||||
background: v-bind('navsBackground');
|
||||
border-radius: 1px;
|
||||
border: 1px solid #4fe985;
|
||||
margin-bottom: 13px;
|
||||
display: flex;
|
||||
}
|
||||
.navsli {
|
||||
flex: 1;
|
||||
height: 25px;
|
||||
color: v-bind('navsColor');
|
||||
font-size: v-bind('navsSize+"px"');
|
||||
cursor: pointer;
|
||||
position: relative;
|
||||
}
|
||||
.navsNum {
|
||||
background: #f91b1b;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
border-radius: 20px;
|
||||
text-align: center;
|
||||
line-height: 20px;
|
||||
color: #fff;
|
||||
font-size: 8px;
|
||||
position: absolute;
|
||||
left: 60%;
|
||||
top: 0;
|
||||
margin-top: -10px;
|
||||
}
|
||||
.navsliactive {
|
||||
color: v-bind('navsCheckColor');
|
||||
font-size: v-bind('navsCheckSize+"px"');
|
||||
background: v-bind('navsCheckBackground');
|
||||
}
|
||||
.sectionBox {
|
||||
width: 92%;
|
||||
height: calc(100% - 40px);
|
||||
margin-left: 4%;
|
||||
overflow: auto;
|
||||
img {
|
||||
width: 21px;
|
||||
height: 21px;
|
||||
}
|
||||
.timeicon {
|
||||
width: 15px;
|
||||
height: 15px;
|
||||
margin-left: 3px;
|
||||
}
|
||||
}
|
||||
.sectionLi {
|
||||
padding: 9px 12px;
|
||||
height: 104px;
|
||||
background: url('@/assets/images/chart/equipment/sectionbg.png');
|
||||
background-size: 100% 100%;
|
||||
}
|
||||
.titleText {
|
||||
color: v-bind('titleColor');
|
||||
font-size: v-bind('titleSize+"px"');
|
||||
}
|
||||
.dataStyle {
|
||||
font-size: 14px;
|
||||
color: #cbe7cd;
|
||||
}
|
||||
.numStyle {
|
||||
color: v-bind('datasColor');
|
||||
font-size: v-bind('datasSize+"px"');
|
||||
white-space: nowrap;
|
||||
overflow: hidden; /* 隐藏溢出内容 :ml-search[overflow] */
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
.desStyle {
|
||||
color: v-bind('desColor');
|
||||
font-size: v-bind('desSize+"px"');
|
||||
}
|
||||
.desImg {
|
||||
margin-right: 10px;
|
||||
}
|
||||
.mr-2 {
|
||||
margin-right: 20px;
|
||||
}
|
||||
.mr-1 {
|
||||
margin-right: 6px;
|
||||
}
|
||||
.mt-1 {
|
||||
margin-top: 8px;
|
||||
}
|
||||
}
|
||||
.sectionLi{
|
||||
padding: 9px 12px;
|
||||
height: 104px;
|
||||
background: url('@/assets/images/chart/equipment/sectionbg.png');
|
||||
background-size: 100% 100%;
|
||||
}
|
||||
.titleText{
|
||||
color: v-bind('titleColor');
|
||||
font-size: v-bind('titleSize+"px"');
|
||||
}
|
||||
.dataStyle{
|
||||
font-size: 14px;
|
||||
color: #CBE7CD;
|
||||
}
|
||||
.numStyle{
|
||||
color: v-bind('datasColor');
|
||||
font-size: v-bind('datasSize+"px"');
|
||||
white-space: nowrap;
|
||||
overflow: hidden; /* 隐藏溢出内容 :ml-search[overflow] */
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
.desStyle{
|
||||
color: v-bind('desColor');
|
||||
font-size: v-bind('desSize+"px"');
|
||||
}
|
||||
.desImg{
|
||||
margin-right: 10px;
|
||||
}
|
||||
.mr-2{
|
||||
margin-right: 20px;
|
||||
}
|
||||
.mr-1{
|
||||
margin-right: 6px;
|
||||
}
|
||||
.mt-1{
|
||||
margin-top: 8px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,14 @@
|
|||
import { PublicConfigClass } from '@/packages/public';
|
||||
import { CreateComponentType } from '@/packages/index.d';
|
||||
import { FlightControlConfig } from './index';
|
||||
import cloneDeep from 'lodash/cloneDeep';
|
||||
import { chartInitConfig } from '@/settings/designSetting';
|
||||
|
||||
export const option = {};
|
||||
|
||||
export default class Config extends PublicConfigClass implements CreateComponentType {
|
||||
public key = FlightControlConfig.key;
|
||||
public chartConfig = cloneDeep(FlightControlConfig);
|
||||
public attr = { ...chartInitConfig, w: 370, h: 900, zIndex: -1 };
|
||||
public option = cloneDeep(option);
|
||||
}
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
<template>
|
||||
<div> </div>
|
||||
</template>
|
||||
<script lang="ts" setup></script>
|
||||
<style lang="scss" scoped></style>
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
import { ConfigType, PackagesCategoryEnum, ChartFrameEnum } from '@/packages/index.d';
|
||||
import { ChatCategoryEnum, ChatCategoryEnumName } from '../../index.d';
|
||||
|
||||
export const FlightControlConfig: ConfigType = {
|
||||
key: 'FlightControl',
|
||||
chartKey: 'VFlightControl',
|
||||
conKey: 'VCFlightControl',
|
||||
title: '无人机',
|
||||
category: ChatCategoryEnum.UAV,
|
||||
categoryName: ChatCategoryEnumName.UAV,
|
||||
package: PackagesCategoryEnum.UAVS,
|
||||
chartFrame: ChartFrameEnum.STATIC,
|
||||
image: 'text_gradient.png',
|
||||
};
|
||||
|
|
@ -0,0 +1,850 @@
|
|||
<template>
|
||||
<div class="flight-control">
|
||||
<div class="title"> 飞行控制 </div>
|
||||
<div class="closeButton" @click="option.status.hide = true">
|
||||
<img src="@/assets/images/chart/uav/close.png" alt="" />
|
||||
</div>
|
||||
<div class="button-group">
|
||||
<button class="take-off" @click="takeOff">一键起飞</button>
|
||||
<button class="guided-flight" @click="flyTo">指点飞行</button>
|
||||
<button class="return-home" @click="returnVoyage">一键返航</button>
|
||||
<button class="fly-to-point" @click="obtain">获取飞行控制权</button>
|
||||
</div>
|
||||
<div class="direction-control">
|
||||
<div class="control-left">
|
||||
<div class="control-left-center"> </div>
|
||||
<div
|
||||
class="control-left-top"
|
||||
title="上升"
|
||||
@mousedown="changeDRC('throttle', 'up', '上升')"
|
||||
@mouseup="changeDRC('throttle', 'up', '')"
|
||||
>
|
||||
<img
|
||||
src="@/assets/images/chart/uav/flight-top-active.png"
|
||||
alt=""
|
||||
v-if="selectName == '上升'"
|
||||
/>
|
||||
<img src="@/assets/images/chart/uav/flight-top.png" alt="" v-else />
|
||||
</div>
|
||||
<div
|
||||
class="control-left-right"
|
||||
title="右旋转"
|
||||
@mousedown="changeDRC('yaw', 'up', '右旋转')"
|
||||
@mouseup="changeDRC('yaw', 'up', '')"
|
||||
>
|
||||
<img
|
||||
src="@/assets/images/chart/uav/flight-right-active.png"
|
||||
alt=""
|
||||
v-if="selectName == '右旋转'"
|
||||
/>
|
||||
<img src="@/assets/images/chart/uav/flight-right.png" alt="" v-else />
|
||||
</div>
|
||||
<div
|
||||
class="control-left-bottom"
|
||||
title="下降"
|
||||
@mousedown="changeDRC('throttle', 'down', '下降')"
|
||||
@mouseup="changeDRC('throttle', 'down', '')"
|
||||
>
|
||||
<img
|
||||
src="@/assets/images/chart/uav/flight-bottom-active.png"
|
||||
alt=""
|
||||
v-if="selectName == '下降'"
|
||||
/>
|
||||
<img src="@/assets/images/chart/uav/flight-bottom.png" alt="" v-else />
|
||||
</div>
|
||||
<div
|
||||
class="control-left-left"
|
||||
title="左旋转"
|
||||
@mousedown="changeDRC('yaw', 'down', '左旋转')"
|
||||
@mouseup="changeDRC('yaw', 'down', '')"
|
||||
>
|
||||
<img
|
||||
src="@/assets/images/chart/uav/flight-left-active.png"
|
||||
alt=""
|
||||
v-if="selectName == '左旋转'"
|
||||
/>
|
||||
<img src="@/assets/images/chart/uav/flight-left.png" alt="" v-else />
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-right">
|
||||
<div class="control-left-center"> </div>
|
||||
<div
|
||||
class="control-left-top"
|
||||
title="前进"
|
||||
@mousedown="changeDRC('pitch', 'up', '前进')"
|
||||
@mouseup="changeDRC('pitch', 'up', '')"
|
||||
>
|
||||
<img
|
||||
src="@/assets/images/chart/uav/flight-top-active.png"
|
||||
alt=""
|
||||
v-if="selectName == '前进'"
|
||||
/>
|
||||
<img src="@/assets/images/chart/uav/flight-top.png" alt="" v-else />
|
||||
</div>
|
||||
<div
|
||||
class="control-left-right"
|
||||
title="右移"
|
||||
@mousedown="changeDRC('roll', 'up', '右移')"
|
||||
@mouseup="changeDRC('roll', 'up', '')"
|
||||
>
|
||||
<img
|
||||
src="@/assets/images/chart/uav/flight-right-active.png"
|
||||
alt=""
|
||||
v-if="selectName == '右移'"
|
||||
/>
|
||||
<img src="@/assets/images/chart/uav/flight-right.png" alt="" v-else />
|
||||
</div>
|
||||
<div
|
||||
class="control-left-bottom"
|
||||
title="后退"
|
||||
@mousedown="changeDRC('pitch', 'down', '后退')"
|
||||
@mouseup="changeDRC('pitch', 'down', '')"
|
||||
>
|
||||
<img
|
||||
src="@/assets/images/chart/uav/flight-bottom-active.png"
|
||||
alt=""
|
||||
v-if="selectName == '后退'"
|
||||
/>
|
||||
<img src="@/assets/images/chart/uav/flight-bottom.png" alt="" v-else />
|
||||
</div>
|
||||
<div
|
||||
class="control-left-left"
|
||||
title="左移"
|
||||
@mousedown="changeDRC('roll', 'down', '左移')"
|
||||
@mouseup="changeDRC('roll', 'down', '')"
|
||||
>
|
||||
<img
|
||||
src="@/assets/images/chart/uav/flight-left-active.png"
|
||||
alt=""
|
||||
v-if="selectName == '左移'"
|
||||
/>
|
||||
<img src="@/assets/images/chart/uav/flight-left.png" alt="" v-else />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="camera-title">
|
||||
<button @click="cameraObtain">获取相机控制权</button>
|
||||
<button @click="singleShot">
|
||||
<img src="@/assets/images/chart/uav/camera.png" alt="" />
|
||||
单拍</button
|
||||
>
|
||||
</div>
|
||||
<div class="camera-control">
|
||||
<div class="camera-control-top">
|
||||
<img class="camera-center" src="@/assets/images/chart/uav/camera-center.png" alt="" />
|
||||
<div
|
||||
class="control-left-top"
|
||||
title="仰视"
|
||||
@mousedown="changeCameraDRC('pitch_speed', 'up', '仰视')"
|
||||
@mouseup="changeCameraDRC('pitch_speed', 'up', '')"
|
||||
>
|
||||
<img
|
||||
src="@/assets/images/chart/uav/camera-top-active.png"
|
||||
alt=""
|
||||
v-if="selectCameraName == '仰视'"
|
||||
/>
|
||||
<img src="@/assets/images/chart/uav/camera-top.png" alt="" v-else />
|
||||
</div>
|
||||
<div
|
||||
class="control-left-right"
|
||||
title="右移"
|
||||
@mousedown="changeCameraDRC('yaw_speed', 'up', '右移')"
|
||||
@mouseup="changeCameraDRC('yaw_speed', 'up', '')"
|
||||
>
|
||||
<img
|
||||
src="@/assets/images/chart/uav/camera-right-active.png"
|
||||
alt=""
|
||||
v-if="selectCameraName == '右移'"
|
||||
/>
|
||||
<img src="@/assets/images/chart/uav/camera-right.png" alt="" v-else />
|
||||
</div>
|
||||
<div
|
||||
class="control-left-bottom"
|
||||
title="俯视"
|
||||
@mousedown="changeCameraDRC('pitch_speed', 'down', '俯视')"
|
||||
@mouseup="changeCameraDRC('pitch_speed', 'down', '')"
|
||||
>
|
||||
<img
|
||||
src="@/assets/images/chart/uav/camera-bottom-active.png"
|
||||
alt=""
|
||||
v-if="selectCameraName == '俯视'"
|
||||
/>
|
||||
<img src="@/assets/images/chart/uav/camera-bottom.png" alt="" v-else />
|
||||
</div>
|
||||
<div
|
||||
class="control-left-left"
|
||||
title="左移"
|
||||
@mousedown="changeCameraDRC('yaw_speed', 'down', '左移')"
|
||||
@mouseup="changeCameraDRC('yaw_speed', 'down', '')"
|
||||
>
|
||||
<img
|
||||
src="@/assets/images/chart/uav/camera-left-active.png"
|
||||
alt=""
|
||||
v-if="selectCameraName == '左移'"
|
||||
/>
|
||||
<img src="@/assets/images/chart/uav/camera-left.png" alt="" v-else />
|
||||
</div>
|
||||
<div class="zoom">
|
||||
<a-slider
|
||||
v-model:value="zoomVale"
|
||||
:max="maxval"
|
||||
:min="2"
|
||||
:marks="marks"
|
||||
@change="cameraZoom"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ai-title">
|
||||
<button>开启AI智能巡检</button>
|
||||
</div>
|
||||
<div class="ai-control">
|
||||
<div class="no-picture">
|
||||
<img src="@/assets/images/chart/uav/no-picture.png" alt="" />
|
||||
<span>暂无画面 请您耐心等待</span>
|
||||
<span>......</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import {
|
||||
computed,
|
||||
PropType,
|
||||
toRefs,
|
||||
watch,
|
||||
reactive,
|
||||
ref,
|
||||
onMounted,
|
||||
onUnmounted,
|
||||
createVNode,
|
||||
} from 'vue';
|
||||
import { CreateComponentType } from '@/packages/index.d';
|
||||
import {
|
||||
getClient,
|
||||
createConnection,
|
||||
clientSubscribe,
|
||||
destroyConnection,
|
||||
createSeizeConnection,
|
||||
} from '@/utils/mqtt';
|
||||
import {
|
||||
servicesTopic,
|
||||
services_replyTopic,
|
||||
drcDownTopic,
|
||||
eventsTopicSubscribe,
|
||||
drcUpTopic,
|
||||
errorName,
|
||||
setTopic,
|
||||
} from '@/utils/debugging/remote';
|
||||
import { buildGUID } from '@/utils/uuid';
|
||||
import { airPortStore } from '@/store/modules/airport';
|
||||
import { useMessage } from '@/hooks/web/useMessage';
|
||||
import {
|
||||
drcDownTopicReize,
|
||||
eventsTopicSubscribeReize,
|
||||
servicesTopicReize,
|
||||
services_replyTopicReize,
|
||||
} from '@/utils/debugging/events';
|
||||
import { EventBus } from '@/utils/eventBus';
|
||||
import {
|
||||
getRedisUser,
|
||||
addOrUpdateRedisUser,
|
||||
getLockedClients,
|
||||
} from '@/api/demo/airportMaintenance';
|
||||
import { useUserStore } from '@/store/modules/user';
|
||||
import { timestampToFormattedDate } from '@/utils/index';
|
||||
|
||||
const { createMessage } = useMessage();
|
||||
const userStore = useUserStore();
|
||||
const userInfo = userStore.getUserInfo;
|
||||
|
||||
const props = defineProps({
|
||||
chartConfig: {
|
||||
type: Object as PropType<CreateComponentType>,
|
||||
required: true,
|
||||
},
|
||||
});
|
||||
const option = reactive({
|
||||
status: props.chartConfig.status,
|
||||
});
|
||||
const airPortStoreVal = airPortStore();
|
||||
const uav = airPortStoreVal.getUAV;
|
||||
const bid = buildGUID();
|
||||
const selectName = ref('');
|
||||
const selectCameraName = ref('');
|
||||
const seq = ref(1);
|
||||
const longPressTimer = ref();
|
||||
const longPressInterval = ref();
|
||||
const longPressDuration = ref(1000); // 长按时间阈值,单位为毫秒
|
||||
const uavStatus = ref();
|
||||
const { w, h, x, y } = toRefs(props.chartConfig.attr);
|
||||
const zoomVale = ref(2);
|
||||
const maxval = ref(20);
|
||||
const marks = ref<Record<number, any>>({
|
||||
2: {
|
||||
style: {
|
||||
color: '#f50',
|
||||
},
|
||||
label: createVNode('strong', {}, '2'),
|
||||
},
|
||||
10: {
|
||||
style: {
|
||||
color: '#f50',
|
||||
},
|
||||
label: createVNode('strong', {}, '10'),
|
||||
},
|
||||
20: {
|
||||
style: {
|
||||
color: '#f50',
|
||||
},
|
||||
label: createVNode('strong', {}, '20'),
|
||||
},
|
||||
});
|
||||
const flightGrab = ref(false);
|
||||
const redisUser = ref({});
|
||||
|
||||
const cameraZoom = () => {};
|
||||
// 一键起飞
|
||||
const takeOff = () => {};
|
||||
// 指点飞行
|
||||
const flyTo = () => {};
|
||||
// 一键返航
|
||||
const returnVoyage = () => {
|
||||
servicesTopic({
|
||||
bid: buildGUID(),
|
||||
method: 'return_home',
|
||||
tid: buildGUID(),
|
||||
timestamp: new Date().getTime(),
|
||||
data: {},
|
||||
});
|
||||
};
|
||||
// 获取飞行控制权
|
||||
const obtain = () => {
|
||||
// 飞行控制权抢夺
|
||||
servicesTopic({
|
||||
bid: bid,
|
||||
method: 'flight_authority_grab',
|
||||
tid: buildGUID(),
|
||||
timestamp: new Date().getTime(),
|
||||
data: {},
|
||||
});
|
||||
// 负载控制权抢夺
|
||||
servicesTopic({
|
||||
bid: bid,
|
||||
method: 'payload_authority_grab',
|
||||
tid: buildGUID(),
|
||||
timestamp: new Date().getTime(),
|
||||
data: {
|
||||
payload_index: uav.camera_index,
|
||||
},
|
||||
});
|
||||
services_replyTopic();
|
||||
changeRedisUser(true);
|
||||
};
|
||||
// 飞行控制方向调整
|
||||
const changeDRC = (type, value, name) => {
|
||||
selectName.value = name;
|
||||
if (name !== '') {
|
||||
console.log('鼠标按下');
|
||||
if (!flightGrab.value) {
|
||||
createMessage.warning('请先获取飞行器控制权');
|
||||
return;
|
||||
}
|
||||
let isLongPress = false;
|
||||
longPressTimer.value = setTimeout(() => {
|
||||
console.log('长按事件触发!');
|
||||
isLongPress = true;
|
||||
longPressInterval.value = setInterval(() => {
|
||||
seq.value = seq.value + 1;
|
||||
let querys = getDRCFlightQuery(type, value, seq);
|
||||
drcDownTopicReize(querys);
|
||||
createMessage.info(name + '指令已发送');
|
||||
}, 1000);
|
||||
}, longPressDuration.value);
|
||||
if (isLongPress) {
|
||||
isLongPress = false;
|
||||
return;
|
||||
}
|
||||
seq.value = seq.value + 1;
|
||||
let querys = getDRCFlightQuery(type, value, seq);
|
||||
drcDownTopicReize(querys);
|
||||
createMessage.info(name + '指令已发送');
|
||||
} else {
|
||||
if (longPressTimer.value) {
|
||||
clearTimeout(longPressTimer.value);
|
||||
longPressTimer.value = null;
|
||||
console.log('清除延时器');
|
||||
}
|
||||
if (longPressInterval.value) {
|
||||
clearTimeout(longPressInterval.value);
|
||||
longPressInterval.value = null;
|
||||
console.log('清除定时器');
|
||||
}
|
||||
console.log('鼠标松开');
|
||||
}
|
||||
};
|
||||
const getDRCFlightQuery = (type, value, seq) => {
|
||||
let data = {
|
||||
roll: 1024,
|
||||
pitch: 1024,
|
||||
throttle: 1024,
|
||||
yaw: 1024,
|
||||
gimbal_pitch: 1024,
|
||||
};
|
||||
if (value == 'up') {
|
||||
data[type] = 1684;
|
||||
} else {
|
||||
data[type] = 364;
|
||||
}
|
||||
const querys = {
|
||||
seq: seq.value,
|
||||
method: 'stick_control',
|
||||
data: data,
|
||||
bid: buildGUID(),
|
||||
tid: buildGUID(),
|
||||
timestamp: new Date().getTime(),
|
||||
};
|
||||
console.log(querys);
|
||||
return querys;
|
||||
};
|
||||
// 云台方向调整
|
||||
const changeCameraDRC = (type, val, name) => {
|
||||
selectCameraName.value = name;
|
||||
if (name !== '') {
|
||||
if (!flightGrab.value) {
|
||||
createMessage.warning('请先获取相机控制权');
|
||||
return;
|
||||
}
|
||||
let isLongPress = false;
|
||||
longPressTimer.value = setTimeout(() => {
|
||||
console.log('长按事件触发!');
|
||||
isLongPress = true;
|
||||
longPressInterval.value = setInterval(() => {
|
||||
let querys = getCameraDRCFlightQuery(type, val);
|
||||
servicesTopicReize(querys);
|
||||
createMessage.info(name + '指令已发送');
|
||||
}, 2000);
|
||||
}, longPressDuration.value);
|
||||
if (isLongPress) {
|
||||
isLongPress = false;
|
||||
return;
|
||||
}
|
||||
// 画面拖动控制
|
||||
let querys = getCameraDRCFlightQuery(type, val);
|
||||
servicesTopicReize(querys);
|
||||
createMessage.info(name + '指令已发送');
|
||||
} else {
|
||||
if (longPressTimer.value) {
|
||||
clearTimeout(longPressTimer.value);
|
||||
longPressTimer.value = null;
|
||||
console.log('清除延时器');
|
||||
}
|
||||
if (longPressInterval.value) {
|
||||
clearTimeout(longPressInterval.value);
|
||||
longPressInterval.value = null;
|
||||
console.log('清除定时器');
|
||||
}
|
||||
console.log('鼠标松开');
|
||||
}
|
||||
};
|
||||
const getCameraDRCFlightQuery = (type, val) => {
|
||||
let data = {
|
||||
payload_index: uav.camera_index,
|
||||
locked: true,
|
||||
pitch_speed: 0,
|
||||
yaw_speed: 0,
|
||||
};
|
||||
if (val == 'up') {
|
||||
data[type] = 8;
|
||||
} else {
|
||||
data[type] = -8;
|
||||
}
|
||||
const querys = {
|
||||
bid: buildGUID(),
|
||||
method: 'camera_screen_drag',
|
||||
tid: buildGUID(),
|
||||
timestamp: new Date().getTime(),
|
||||
data: data,
|
||||
};
|
||||
console.log(querys);
|
||||
return querys;
|
||||
};
|
||||
// 获取相机控制权
|
||||
const cameraObtain = () => {
|
||||
// 飞行控制权抢夺
|
||||
servicesTopic({
|
||||
bid: bid,
|
||||
method: 'flight_authority_grab',
|
||||
tid: buildGUID(),
|
||||
timestamp: new Date().getTime(),
|
||||
data: {},
|
||||
});
|
||||
// 负载控制权抢夺
|
||||
servicesTopic({
|
||||
bid: bid,
|
||||
method: 'payload_authority_grab',
|
||||
tid: buildGUID(),
|
||||
timestamp: new Date().getTime(),
|
||||
data: {
|
||||
payload_index: uav.camera_index,
|
||||
},
|
||||
});
|
||||
services_replyTopic();
|
||||
changeRedisUser(true);
|
||||
};
|
||||
// 单拍
|
||||
const singleShot = () => {
|
||||
if (!flightGrab.value) {
|
||||
createMessage.warning('请先获取相机控制权');
|
||||
return;
|
||||
}
|
||||
// 开始拍照
|
||||
servicesTopicReize({
|
||||
bid: buildGUID(),
|
||||
method: 'camera_photo_take',
|
||||
tid: buildGUID(),
|
||||
timestamp: new Date().getTime(),
|
||||
data: {
|
||||
payload_index: uav.camera_index,
|
||||
},
|
||||
});
|
||||
services_replyTopicReize();
|
||||
};
|
||||
//修改redis用户锁
|
||||
const changeRedisUser = (val: boolean) => {
|
||||
const querys = redisUser.value;
|
||||
querys.isLock = val;
|
||||
querys.connectTime = timestampToFormattedDate(new Date().getTime());
|
||||
addOrUpdateRedisUser(querys);
|
||||
};
|
||||
onMounted(() => {
|
||||
// mqtt连接
|
||||
createConnection();
|
||||
// 获取mqtt客户端信息
|
||||
getRedisUser(userInfo.id).then((res) => {
|
||||
if (res) {
|
||||
redisUser.value = res;
|
||||
}
|
||||
});
|
||||
setTimeout(() => {
|
||||
// 接收消息
|
||||
getClient().on('message', (topic, message) => {
|
||||
const rs = JSON.parse(message);
|
||||
if (rs.data.sub_device) {
|
||||
uavStatus.value = rs.data.sub_device.device_online_status;
|
||||
}
|
||||
if (rs.method == 'camera_photo_take') {
|
||||
if (rs.data.result == 0) {
|
||||
createMessage.success('拍照成功');
|
||||
} else {
|
||||
flightGrab.value = false;
|
||||
createMessage.error('拍照失败,' + errorName(rs.data.result));
|
||||
}
|
||||
}
|
||||
if (rs.method == 'flight_authority_grab' && rs.bid == bid) {
|
||||
if (rs.data.result == 0) {
|
||||
flightGrab.value = true;
|
||||
createSeizeConnection();
|
||||
createMessage.success('相机控制权获取成功');
|
||||
} else {
|
||||
flightGrab.value = false;
|
||||
createMessage.error('相机控制权获取失败,' + errorName(rs.data.result));
|
||||
}
|
||||
}
|
||||
});
|
||||
}, 1000);
|
||||
// 组件通信
|
||||
EventBus.on(props.chartConfig.id + 'dataupdate', (data) => {
|
||||
console.log('dataupdate', data);
|
||||
});
|
||||
});
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.flight-control {
|
||||
width: v-bind('`${w}px`');
|
||||
height: v-bind('`${h}px`');
|
||||
|
||||
// 页面不能被选中
|
||||
-webkit-user-select: none; /* Safari */
|
||||
-moz-user-select: none; /* Firefox */
|
||||
-ms-user-select: none; /* IE/Edge */
|
||||
user-select: none;
|
||||
|
||||
background-image: url('@/assets/images/chart/uav/flight-bg.png');
|
||||
background-size: 100% 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
.title {
|
||||
color: #58ff95;
|
||||
font-size: 20px;
|
||||
position: absolute;
|
||||
top: 16px;
|
||||
left: 16px;
|
||||
}
|
||||
.closeButton {
|
||||
position: absolute;
|
||||
right: 10px;
|
||||
top: 10px;
|
||||
img {
|
||||
width: 30px;
|
||||
}
|
||||
}
|
||||
.button-group {
|
||||
margin-top: 13%;
|
||||
margin-left: 10%;
|
||||
button {
|
||||
margin: 10px;
|
||||
width: 120px;
|
||||
height: 36px;
|
||||
color: #fff;
|
||||
display: inline-block;
|
||||
}
|
||||
.take-off {
|
||||
background: #00b155;
|
||||
box-shadow: 0px 10px 30px 0px rgba(0, 0, 6, 0.15);
|
||||
border-radius: 15px 15px 0px 15px;
|
||||
border: 1px solid #00ae4a;
|
||||
}
|
||||
.guided-flight {
|
||||
background: #ff9538;
|
||||
box-shadow: 0px 10px 30px 0px rgba(0, 0, 6, 0.15);
|
||||
border-radius: 15px 15px 15px 0px;
|
||||
}
|
||||
.return-home {
|
||||
background: none;
|
||||
box-shadow: 0px 10px 30px 0px rgba(0, 0, 6, 0.15);
|
||||
border-radius: 15px 0px 15px 15px;
|
||||
border: 1px solid #00ae4a;
|
||||
}
|
||||
.fly-to-point {
|
||||
background: #0c29b2;
|
||||
box-shadow: 0px 10px 30px 0px rgba(0, 0, 6, 0.15);
|
||||
border-radius: 0px 15px 15px 15px;
|
||||
border: none;
|
||||
}
|
||||
}
|
||||
.direction-control {
|
||||
width: 90%;
|
||||
margin-left: 5%;
|
||||
height: 160px;
|
||||
background: #0c2e25;
|
||||
box-shadow: 0px 10px 30px 0px rgba(0, 0, 6, 0.15);
|
||||
border-radius: 10px;
|
||||
display: flex;
|
||||
}
|
||||
.control-left {
|
||||
width: 40%;
|
||||
height: 100%;
|
||||
margin-left: 10%;
|
||||
position: relative;
|
||||
.control-left-center {
|
||||
width: 46px;
|
||||
height: 46px;
|
||||
border-radius: 50%;
|
||||
// background: linear-gradient(148deg, #374249 0%, #151c20 100%);
|
||||
// box-shadow:
|
||||
// 0px 10px 30px 0px rgba(0, 0, 6, 0.15),
|
||||
// 0px 2px 4px 0px rgba(0, 0, 0, 0.5);
|
||||
// border-image: linear-gradient(134deg, rgba(0, 177, 85, 1), rgba(2, 87, 43, 1)) 1 1;
|
||||
border: 1px solid #00b155;
|
||||
position: absolute;
|
||||
top: 36%;
|
||||
left: 29%;
|
||||
}
|
||||
img {
|
||||
width: 68px;
|
||||
}
|
||||
.control-left-top {
|
||||
position: absolute;
|
||||
left: 20%;
|
||||
top: 12%;
|
||||
}
|
||||
.control-left-bottom {
|
||||
position: absolute;
|
||||
left: 20%;
|
||||
bottom: 11%;
|
||||
}
|
||||
.control-left-left {
|
||||
position: absolute;
|
||||
left: -1%;
|
||||
top: 30%;
|
||||
img {
|
||||
width: 40px;
|
||||
}
|
||||
}
|
||||
.control-left-right {
|
||||
position: absolute;
|
||||
right: 6%;
|
||||
top: 30%;
|
||||
img {
|
||||
width: 40px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.control-right {
|
||||
width: 40%;
|
||||
height: 100%;
|
||||
margin-left: 2%;
|
||||
position: relative;
|
||||
.control-left-center {
|
||||
width: 46px;
|
||||
height: 46px;
|
||||
border-radius: 50%;
|
||||
// background: linear-gradient(148deg, #374249 0%, #151c20 100%);
|
||||
// box-shadow:
|
||||
// 0px 10px 30px 0px rgba(0, 0, 6, 0.15),
|
||||
// 0px 2px 4px 0px rgba(0, 0, 0, 0.5);
|
||||
// border-image: linear-gradient(134deg, rgba(0, 177, 85, 1), rgba(2, 87, 43, 1)) 1 1;
|
||||
border: 1px solid #00b155;
|
||||
position: absolute;
|
||||
top: 36%;
|
||||
left: 29%;
|
||||
}
|
||||
img {
|
||||
width: 68px;
|
||||
}
|
||||
.control-left-top {
|
||||
position: absolute;
|
||||
left: 20%;
|
||||
top: 12%;
|
||||
}
|
||||
.control-left-bottom {
|
||||
position: absolute;
|
||||
left: 20%;
|
||||
bottom: 11%;
|
||||
}
|
||||
.control-left-left {
|
||||
position: absolute;
|
||||
left: -1%;
|
||||
top: 30%;
|
||||
img {
|
||||
width: 40px;
|
||||
}
|
||||
}
|
||||
.control-left-right {
|
||||
position: absolute;
|
||||
right: 6%;
|
||||
top: 30%;
|
||||
img {
|
||||
width: 40px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.camera-title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin: 16px 4%;
|
||||
button:first-child {
|
||||
border: 1px solid #00ae4a;
|
||||
background: none;
|
||||
color: #fff;
|
||||
border-radius: 10px;
|
||||
padding: 6px 10px;
|
||||
}
|
||||
button:last-child {
|
||||
background: #00b155;
|
||||
color: #fff;
|
||||
border-radius: 10px;
|
||||
padding: 6px 14px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
img {
|
||||
width: 16px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.camera-control {
|
||||
width: 90%;
|
||||
margin-left: 5%;
|
||||
background: #0c2e25;
|
||||
box-shadow: 0px 10px 30px 0px rgba(0, 0, 6, 0.15);
|
||||
border-radius: 10px;
|
||||
padding-bottom: 30px;
|
||||
.camera-control-top {
|
||||
position: relative;
|
||||
height: 180px;
|
||||
.camera-center {
|
||||
position: absolute;
|
||||
top: 4%;
|
||||
left: 25%;
|
||||
width: 40%;
|
||||
}
|
||||
img {
|
||||
width: 54px;
|
||||
}
|
||||
.control-left-top {
|
||||
position: absolute;
|
||||
left: 37%;
|
||||
top: 20%;
|
||||
}
|
||||
.control-left-bottom {
|
||||
position: absolute;
|
||||
left: 37%;
|
||||
bottom: 38%;
|
||||
}
|
||||
.control-left-left {
|
||||
position: absolute;
|
||||
left: 34%;
|
||||
top: 28%;
|
||||
img {
|
||||
width: 24px;
|
||||
}
|
||||
}
|
||||
.control-left-right {
|
||||
position: absolute;
|
||||
right: 43.5%;
|
||||
top: 28%;
|
||||
img {
|
||||
width: 24px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.zoom {
|
||||
position: absolute;
|
||||
bottom: -6%;
|
||||
left: 5%;
|
||||
width: 90%;
|
||||
height: 20px;
|
||||
}
|
||||
}
|
||||
::v-deep .ant-slider-rail {
|
||||
background: #0f4c2d;
|
||||
}
|
||||
::v-deep .ant-slider-track {
|
||||
background: #07b35a;
|
||||
}
|
||||
::v-deep .ant-slider-mark-text {
|
||||
color: #fff !important;
|
||||
}
|
||||
.ai-title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin: 16px 4%;
|
||||
button:first-child {
|
||||
border: 1px solid #00ae4a;
|
||||
background: none;
|
||||
color: #fff;
|
||||
border-radius: 10px;
|
||||
padding: 6px 10px;
|
||||
}
|
||||
}
|
||||
.ai-control {
|
||||
width: 90%;
|
||||
background: #0c2e25;
|
||||
box-shadow: 0px 10px 30px 0px rgba(0, 0, 6, 0.15);
|
||||
border-radius: 10px;
|
||||
border: 1px solid #00611a;
|
||||
margin-left: 5%;
|
||||
.no-picture {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: #fff;
|
||||
margin-top: 6%;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
import { PublicConfigClass } from '@/packages/public';
|
||||
import { CreateComponentType } from '@/packages/index.d';
|
||||
import { PatrolConfig } from './index';
|
||||
import cloneDeep from 'lodash/cloneDeep';
|
||||
import { chartInitConfig } from '@/settings/designSetting';
|
||||
|
||||
export const option = {};
|
||||
|
||||
export default class Config extends PublicConfigClass implements CreateComponentType {
|
||||
public key = PatrolConfig.key;
|
||||
public chartConfig = cloneDeep(PatrolConfig);
|
||||
public attr = { ...chartInitConfig, w: 110, h: 30, zIndex: -1 };
|
||||
public option = cloneDeep(option);
|
||||
}
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
<template>
|
||||
<div> </div>
|
||||
</template>
|
||||
<script lang="ts" setup></script>
|
||||
<style lang="scss" scoped></style>
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
import { ConfigType, PackagesCategoryEnum, ChartFrameEnum } from '@/packages/index.d';
|
||||
import { ChatCategoryEnum, ChatCategoryEnumName } from '../../index.d';
|
||||
|
||||
export const PatrolConfig: ConfigType = {
|
||||
key: 'Patrol',
|
||||
chartKey: 'VPatrol',
|
||||
conKey: 'VCPatrol',
|
||||
title: '无人机巡查',
|
||||
category: ChatCategoryEnum.UAV,
|
||||
categoryName: ChatCategoryEnumName.UAV,
|
||||
package: PackagesCategoryEnum.UAVS,
|
||||
chartFrame: ChartFrameEnum.STATIC,
|
||||
image: 'text_gradient.png',
|
||||
};
|
||||
|
|
@ -0,0 +1,151 @@
|
|||
<template>
|
||||
<div
|
||||
class="patrol-container"
|
||||
@click="clickBtn"
|
||||
@dblclick="dblclickBtn"
|
||||
@contextmenu="rightclickBtn"
|
||||
@mouseenter="mouseenterBtn"
|
||||
@mouseleave="mouseleaveBtn"
|
||||
>
|
||||
<img src="@/assets/images/chart/uav/uav.png" alt="" />
|
||||
<span>无人机巡查</span>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import {
|
||||
computed,
|
||||
PropType,
|
||||
toRefs,
|
||||
watch,
|
||||
reactive,
|
||||
ref,
|
||||
onMounted,
|
||||
onUnmounted,
|
||||
createVNode,
|
||||
} from 'vue';
|
||||
import { CreateComponentType } from '@/packages/index.d';
|
||||
import { eventHandlerHook } from '@/hooks/eventHandler.hook';
|
||||
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore';
|
||||
import { EventBus } from '@/utils/eventBus';
|
||||
import { uuid, buildGUID } from '@/utils/uuid';
|
||||
import { servicesTopic, services_replyTopic } from '@/utils/debugging/remote';
|
||||
import {
|
||||
getClient,
|
||||
createConnection,
|
||||
clientSubscribe,
|
||||
destroyConnection,
|
||||
createSeizeConnection,
|
||||
} from '@/utils/mqtt';
|
||||
|
||||
const props = defineProps({
|
||||
chartConfig: {
|
||||
type: Object as PropType<CreateComponentType>,
|
||||
required: true,
|
||||
},
|
||||
});
|
||||
const { w, h, x, y } = toRefs(props.chartConfig.attr);
|
||||
const chartEditStore = useChartEditStore();
|
||||
// 传递过来的线索信息
|
||||
const deliveryData = ref();
|
||||
|
||||
const clickBtn = (val) => {
|
||||
console.log('value000', val);
|
||||
eventHandlerHook(
|
||||
chartEditStore.getComponentList,
|
||||
props.chartConfig.events.interactConfigEvents,
|
||||
'click',
|
||||
val,
|
||||
);
|
||||
console.log(deliveryData.value);
|
||||
// 一键起飞
|
||||
const data = {
|
||||
flight_id: uuid(14, 14),
|
||||
target_latitude: Number(deliveryData.value.lat),
|
||||
target_longitude: Number(deliveryData.value.lng),
|
||||
target_height: 200,
|
||||
security_takeoff_height: 100,
|
||||
rth_altitude: 115,
|
||||
rth_mode: 1,
|
||||
max_speed: 10,
|
||||
commander_flight_mode: 1,
|
||||
rc_lost_action: 2,
|
||||
commander_mode_lost_action: 1,
|
||||
commander_flight_height: 115.0,
|
||||
flight_safety_advance_check: 1,
|
||||
};
|
||||
const querys = {
|
||||
bid: buildGUID(),
|
||||
data: data,
|
||||
tid: buildGUID(),
|
||||
timestamp: new Date().getTime(),
|
||||
method: 'takeoff_to_point',
|
||||
};
|
||||
console.log(querys);
|
||||
// 新的
|
||||
// servicesTopicReize(querys);
|
||||
// services_replyTopicReize();
|
||||
// 老的
|
||||
servicesTopic(querys);
|
||||
services_replyTopic();
|
||||
};
|
||||
const dblclickBtn = (val) => {
|
||||
eventHandlerHook(
|
||||
chartEditStore.getComponentList,
|
||||
props.chartConfig.events.interactConfigEvents,
|
||||
'dblclick',
|
||||
val,
|
||||
);
|
||||
};
|
||||
const rightclickBtn = (event) => {
|
||||
event.preventDefault(); // 阻止默认的右键菜单
|
||||
eventHandlerHook(
|
||||
chartEditStore.getComponentList,
|
||||
props.chartConfig.events.interactConfigEvents,
|
||||
'rightclick',
|
||||
);
|
||||
};
|
||||
const mouseenterBtn = (val) => {
|
||||
eventHandlerHook(
|
||||
chartEditStore.getComponentList,
|
||||
props.chartConfig.events.interactConfigEvents,
|
||||
'mousein',
|
||||
val,
|
||||
);
|
||||
};
|
||||
const mouseleaveBtn = (val) => {
|
||||
eventHandlerHook(
|
||||
chartEditStore.getComponentList,
|
||||
props.chartConfig.events.interactConfigEvents,
|
||||
'mouseout',
|
||||
val,
|
||||
);
|
||||
};
|
||||
onMounted(() => {
|
||||
// 组件通信
|
||||
EventBus.on(props.chartConfig.id + 'dataupdate', (data) => {
|
||||
console.log('dataupdate', data);
|
||||
deliveryData.value = data;
|
||||
});
|
||||
createConnection();
|
||||
});
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.patrol-container {
|
||||
width: v-bind('`${w}px`');
|
||||
height: v-bind('`${h}px`');
|
||||
background: linear-gradient(180deg, #182b20 0%, #136c3d 100%);
|
||||
border-radius: 2px;
|
||||
border: 1px solid #8ff4b1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 14px;
|
||||
img {
|
||||
width: 20px;
|
||||
}
|
||||
span {
|
||||
margin-left: 6px;
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
import { FlightControlConfig } from './FlightControl/index';
|
||||
import { PatrolConfig } from './Patrol/index';
|
||||
|
||||
export default [FlightControlConfig, PatrolConfig];
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
export enum ChatCategoryEnum {
|
||||
UAV = 'Uav',
|
||||
}
|
||||
|
||||
export enum ChatCategoryEnumName {
|
||||
UAV = '无人机',
|
||||
}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
import Uav from './Uav';
|
||||
|
||||
export const UAVList = [...Uav];
|
||||
|
|
@ -171,11 +171,11 @@ export interface PublicConfigType {
|
|||
}[];
|
||||
interactConfigEvents: {}[];
|
||||
};
|
||||
mouseSetting:{
|
||||
mouseSetting: {
|
||||
mouseEventClose: boolean;
|
||||
mouseSelectClose: boolean;
|
||||
mouseCursor: string;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export interface CreateComponentType extends PublicConfigType, requestConfig {
|
||||
|
|
@ -213,7 +213,8 @@ export enum PackagesCategoryEnum {
|
|||
ZHIKU = 'Zhiku',
|
||||
EQUIPMENT = 'Equipment',
|
||||
TASKS = 'Tasks',
|
||||
XUNCHAGUIJI= 'XunChaGuiJi'
|
||||
XUNCHAGUIJI = 'XunChaGuiJi',
|
||||
UAVS = 'Uav',
|
||||
}
|
||||
|
||||
// 包分类名称
|
||||
|
|
@ -233,7 +234,8 @@ export enum PackagesCategoryName {
|
|||
ZHIKU = '智库',
|
||||
EQUIPMENT = '设备',
|
||||
TASKS = '任务',
|
||||
XUNCHAGUIJI = '巡查'
|
||||
XUNCHAGUIJI = '巡查',
|
||||
UAVS = '无人机',
|
||||
}
|
||||
|
||||
// 获取组件
|
||||
|
|
@ -260,4 +262,5 @@ export type PackagesType = {
|
|||
[PackagesCategoryEnum.EQUIPMENT]: ConfigType[];
|
||||
[PackagesCategoryEnum.TASKS]: ConfigType[];
|
||||
[PackagesCategoryEnum.XUNCHAGUIJI]: ConfigType[];
|
||||
[PackagesCategoryEnum.UAVS]: ConfigType[];
|
||||
};
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ import { ZhikuList } from '@/packages/components/Zhiku/index';
|
|||
import { EquipmentList } from '@/packages/components/Equipment/index';
|
||||
import { TasksList } from '@/packages/components/Tasks/index';
|
||||
import { XunChaGuiJiList } from '@/packages/components/XunChaGuiJi/index';
|
||||
|
||||
import { UAVList } from '@/packages/components/Uav/index';
|
||||
|
||||
import {
|
||||
PackagesCategoryEnum,
|
||||
|
|
@ -60,18 +60,21 @@ export let packagesList: PackagesType = {
|
|||
[PackagesCategoryEnum.ZHIKU]: ZhikuList,
|
||||
[PackagesCategoryEnum.EQUIPMENT]: EquipmentList,
|
||||
[PackagesCategoryEnum.TASKS]: TasksList,
|
||||
[PackagesCategoryEnum.UAVS]: UAVList,
|
||||
};
|
||||
|
||||
// 组件缓存, 可以大幅度提升组件加载速度
|
||||
const componentCacheMap = new Map<string, any>();
|
||||
const loadConfig = (packageName: string, categoryName: string, keyName: string) => {
|
||||
const key = packageName + categoryName + keyName;
|
||||
console.log('loadConfig', key);
|
||||
if (!componentCacheMap.has(key)) {
|
||||
componentCacheMap.set(
|
||||
key,
|
||||
import(`./components/${packageName}/${categoryName}/${keyName}/config.ts`),
|
||||
);
|
||||
}
|
||||
console.log('loadConfig', componentCacheMap.get(key));
|
||||
return componentCacheMap.get(key);
|
||||
};
|
||||
|
||||
|
|
@ -88,6 +91,7 @@ export const createComponent = async (targetData: ConfigType) => {
|
|||
return new redirectChart.default();
|
||||
}
|
||||
const chart = await loadConfig(targetData.package, category, key);
|
||||
console.log('chart', chart);
|
||||
return new chart.default();
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,67 @@
|
|||
import { defineStore } from 'pinia';
|
||||
|
||||
export const airPortStore = defineStore({
|
||||
id: 'airport',
|
||||
state: () => ({
|
||||
airport: {
|
||||
sn: null,
|
||||
camera_index: '165-0-7',
|
||||
video_index: 'normal-0',
|
||||
video_id: '8UUXN5400A079H/165-0-7/normal-0',
|
||||
},
|
||||
uav: {
|
||||
sn: null,
|
||||
camera_index: '99-0-0',
|
||||
video_index: 'normal-0',
|
||||
video_id: '1581F8HGX254V00A0BUY/99-0-0/normal-0',
|
||||
},
|
||||
liveInfo: {
|
||||
rtmp: 'rtmp://175.27.168.120:6019/live/',
|
||||
url: 'http://175.27.168.120:6012/live/',
|
||||
// rtmp: 'rtmp://box.wisestcity.com:1935/live/',
|
||||
// url: 'http://box.wisestcity.com:8081/live/',
|
||||
// rtmp: 'http://175.27.168.120:5005/rtc/v1/whip/?app=live&stream=',
|
||||
// url: 'http://175.27.168.120:5005/rtc/v1/whep/?app=live&stream=',
|
||||
},
|
||||
gateway: null,
|
||||
project: null,
|
||||
taskId: null,
|
||||
}),
|
||||
getters: {
|
||||
getAirport(state) {
|
||||
return state.airport;
|
||||
},
|
||||
getUAV(state) {
|
||||
return state.uav;
|
||||
},
|
||||
getLiveInfo(state) {
|
||||
return state.liveInfo;
|
||||
},
|
||||
getGateway(state) {
|
||||
return state.gateway;
|
||||
},
|
||||
getProject(state) {
|
||||
return state.project;
|
||||
},
|
||||
getTaskId(state) {
|
||||
return state.taskId;
|
||||
},
|
||||
},
|
||||
actions: {
|
||||
setAirPort(item: any, value: any) {
|
||||
this.airport[item] = value;
|
||||
},
|
||||
setUAV(item: any, value: any) {
|
||||
this.uav[item] = value;
|
||||
},
|
||||
setGateway(value: any) {
|
||||
this.gateway = value;
|
||||
},
|
||||
setProject(value: any) {
|
||||
this.project = value;
|
||||
},
|
||||
setTaskId(value: any) {
|
||||
this.taskId = value;
|
||||
},
|
||||
},
|
||||
});
|
||||
|
|
@ -0,0 +1,447 @@
|
|||
{
|
||||
"error_code": {
|
||||
"312014": "设备升级中,请勿重复操作",
|
||||
"312015": "机场:{dock_org_name} 业务繁忙无法进行设备升级,请等待机场处于空闲中后再试",
|
||||
"312016": "升级失败,机场和飞行器图传链路异常,请重启机场和飞行器后重试",
|
||||
"312022": "飞行器开机失败或未连接,请检查飞行器是否在舱内,是否安装电池,机场和飞行器是否已对频",
|
||||
"312023": "推杆闭合失败无法升级飞行器,请检查急停按钮是否被按下,推杆是否有异物卡住",
|
||||
"312027": "升级失败,机场未检测到飞行器",
|
||||
"312028": "升级失败,设备升级过程中设备被重启",
|
||||
"312029": "设备重启中无法进行设备升级,请等待设备重启完成后重试",
|
||||
"312030": "升级失败,飞行器增强图传开启后无法升级,请关闭飞行器增强图传后重试",
|
||||
"312704": "设备电量过低,请充电至20%以上后重试",
|
||||
"314000": "设备当前无法支持该操作,建议检查设备当前工作状态",
|
||||
"314001": "飞行任务下发失败,请稍后重试",
|
||||
"314002": "飞行任务下发失败,请稍后重试",
|
||||
"314003": "航线文件格式不兼容,请检查航线文件是否正确",
|
||||
"314005": "飞行任务下发失败,请稍后重试或重启机场后重试",
|
||||
"314006": "飞行器初始化失败,请重启机场后重试",
|
||||
"314007": "机场传输航线至飞行器失败,请重启机场后重试",
|
||||
"314008": "飞行器起飞前准备超时,请重启机场后重试",
|
||||
"314009": "飞行器初始化失败,请重启机场后重试",
|
||||
"314010": "航线执行失败,请重启机场后重试",
|
||||
"314011": "机场系统异常,无法获取飞行任务执行结果",
|
||||
"314012": "飞行器起飞前准备失败,无法执行飞行任务,请重启机场后重试",
|
||||
"314013": "飞行任务下发失败,机场无法获取到本次飞行任务的航线,无法执行飞行任务,请稍后重试",
|
||||
"314014": "机场系统异常,飞行任务执行失败,请稍后重试",
|
||||
"314015": "机场传输精准复拍航线至飞行器失败,无法执行飞行任务,请稍后重试或重启机场后重试",
|
||||
"314016": "航线文件解析失败,无法执行飞行任务,请检查航线文件",
|
||||
"314017": "航线文件解析失败,请检查航线后再试",
|
||||
"314018": "飞行器 RTK 定位异常,无法执行飞行任务,请稍后重试或重启机场后重试",
|
||||
"314019": "飞行器 RTK 收敛失败,无法执行飞行任务,请稍后重试或重启机场后重试",
|
||||
"314020": "飞行器不在停机坪正中间或飞行器朝向不正确,无法执行飞行任务,请检查飞行器位置和朝向",
|
||||
"314021": "飞行器 RTK 定位异常,无法执行飞行任务,请稍后重试或重启机场后重试",
|
||||
"314024": "进离场航线下发失败,请稍后重试或重启机场后重试",
|
||||
"314025": "RTK收敛超时,用户手动取消任务",
|
||||
"314200": "任务失败,由于机场网络断开,飞行器已自动返航,请确保机场已连接网络后再试",
|
||||
"315000": "机场通信异常,请重启机场后重试",
|
||||
"315001": "机场通信异常,请远程开启飞机并等待 1min 后,再次下发任务重试",
|
||||
"315002": "机场通信异常,请重启机场后重试",
|
||||
"315003": "机场通信异常,请重启机场后重试",
|
||||
"315004": "任务失败,请等待两个机场都空闲后,再次下发任务重试",
|
||||
"315005": "机场通信异常,请重启机场后重试",
|
||||
"315006": "机场通信异常,请重启机场后重试",
|
||||
"315007": "机场通信异常,请将机场升级到最新版本或重启机场后重试",
|
||||
"315008": "降落机场和起飞机场标定信息不一致,请确认两个机场均链路通畅且使用了相同的网络信息标定",
|
||||
"315009": "机场通信异常,请重启机场后重试",
|
||||
"315010": "无法停止飞行任务,请稍后重试,如果仍报错请联系大疆售后",
|
||||
"315011": "无法停止飞行任务,请稍后重试,如果仍报错请联系大疆售后",
|
||||
"315012": "无法停止飞行任务,请稍后重试,如果仍报错请联系大疆售后",
|
||||
"315013": "飞行任务下发失败,请稍后重试,如果仍报错请联系大疆售后",
|
||||
"315014": "当前任务类型不支持设置返航点",
|
||||
"315015": "返航点设置失败,请稍后重试,如果仍报错请联系大疆售后",
|
||||
"315016": "飞行任务下发失败,请稍后重试,如果仍报错请联系大疆售后",
|
||||
"315017": "飞行任务下发失败,请稍后重试,如果仍报错请联系大疆售后",
|
||||
"315018": "任务失败,请等待两个机场都空闲后,再次下发任务重试",
|
||||
"315019": "设备部署位置不佳,无法执行蛙跳任务,请选择其它机场再试",
|
||||
"315050": "机场系统异常,请重启机场后重试",
|
||||
"315051": "任务失败,请重启机场并再次下发任务后重试,如果仍报错请联系大疆售后",
|
||||
"315052": "机场位置未收敛,请等待一段时间后重试",
|
||||
"315053": "任务失败,请重启机场并再次下发任务后重试,如果仍报错请联系大疆售后",
|
||||
"315054": "任务失败,请重启机场并再次下发任务后重试,如果仍报错请联系大疆售后",
|
||||
"315055": "任务失败,请重启机场并再次下发任务后重试,如果仍报错请联系大疆售后",
|
||||
"315056": "任务失败,请重启机场并再次下发任务后重试,如果仍报错请联系大疆售后",
|
||||
"315057": "任务失败,请重启机场并再次下发任务后重试,如果仍报错请联系大疆售后",
|
||||
"315058": "任务失败,请重启机场并再次下发任务后重试,如果仍报错请联系大疆售后",
|
||||
"315059": "任务失败,请重启机场并再次下发任务后重试,如果仍报错请联系大疆售后",
|
||||
"315060": "任务失败,请重启机场并再次下发任务后重试,如果仍报错请联系大疆售后",
|
||||
"315061": "任务失败,请重启机场并再次下发任务后重试,如果仍报错请联系大疆售后",
|
||||
"315062": "任务失败,请重启机场并再次下发任务后重试,如果仍报错请联系大疆售后",
|
||||
"315063": "任务失败,请重启机场并再次下发任务后重试,如果仍报错请联系大疆售后",
|
||||
"315064": "任务失败,请重启机场并再次下发任务后重试,如果仍报错请联系大疆售后",
|
||||
"315065": "任务失败,请重启机场并再次下发任务后重试,如果仍报错请联系大疆售后",
|
||||
"316001": "飞行器参数配置失败,请重启机场后重试",
|
||||
"316002": "飞行器参数配置失败,请重启机场后重试",
|
||||
"316003": "飞行器参数配置失败,请重启机场后重试",
|
||||
"316004": "飞行器参数配置失败,请重启机场后重试",
|
||||
"316005": "飞行器 RTK 收敛失败,无法执行飞行任务,请重启机场后重试",
|
||||
"316006": "任务超时,飞行器已丢失或降落时机场未开启舱盖或展开推杆,飞行器无法降落回机场,请尽快至机场部署现场检查飞行器状况",
|
||||
"316007": "飞行器初始化失败,请重启机场后重试",
|
||||
"316008": "机场获取飞行器控制权失败,无法执行飞行任务,请确认遥控器未锁定控制权",
|
||||
"316009": "飞行器电量低于30%,无法执行飞行任务,请充电后重试(建议电量≥50%)",
|
||||
"316010": "机场未检测到飞行器,无法执行飞行任务,请检查舱内是否有飞行器,机场与飞行器是否已对频,或重启机场后重试",
|
||||
"316011": "飞行器降落位置偏移过大,请检查飞行器是否需要现场摆正",
|
||||
"316012": "飞行器起飞前准备失败,无法执行飞行任务,请重启机场后重试",
|
||||
"316013": "飞行器起飞前准备失败,无法执行飞行任务,请重启机场后重试",
|
||||
"316014": "飞行器起飞前准备失败,无法执行飞行任务,请重启机场后重试",
|
||||
"316015": "飞行器 RTK 收敛位置距离机场过远,无法执行飞行任务,请重启机场后重试",
|
||||
"316016": "飞行器降落至机场超时,可能是机场与飞行器断连导致,请通过直播查看飞行器是否降落至舱内",
|
||||
"316017": "获取飞行器媒体数量超时,可能是机场与飞行器断连导致,请通过直播查看飞行器是否降落至舱内",
|
||||
"316018": "飞行任务执行超时,可能是机场与飞行器断连导致,请通过直播查看飞行器是否降落至舱内",
|
||||
"316019": "机场系统错误,无法执行飞行任务,请稍后重试",
|
||||
"316020": "飞行器使用的 RTK 信号源错误,请稍后重试",
|
||||
"316021": "飞行器 RTK 信号源检查超时,请稍后重试",
|
||||
"316022": "飞行器无法执行返航指令,请检查飞行器是否已开机,机场与飞行器是否已断连,请确认无以上问题后重试",
|
||||
"316023": "飞行器无法执行返航指令,飞行器已被 B 控接管,请在 B 控操控飞行器,或关闭 B 控后重试",
|
||||
"316024": "飞行器执行返航指令失败,请检查飞行器是否已起飞,确认飞行器已起飞后请重试",
|
||||
"316025": "飞行器参数配置失败,请稍后重试或重启机场后重试",
|
||||
"316026": "机场急停按钮被按下,无法执行飞行任务,请释放急停按钮后重试",
|
||||
"316027": "飞行器参数配置超时,请稍后重试或重启机场后重试",
|
||||
"316029": "机场急停按钮被按下,飞行器将飞往备降点降落,请立即检查飞行器是否已安全降落并将飞行器放回至机场",
|
||||
"316032": "获取电池数据超时,请稍后重试或重启飞行器后重试",
|
||||
"316033": "飞行器电池循环次数过高,为保证飞行安全,已自动终止任务,建议更换该电池",
|
||||
"316034": "无法起飞,飞行器固件版本与机场固件版本不匹配,为保证飞行安全请升级固件后再试",
|
||||
"316035": "进离场航线下发失败,请确保设备固件为最新版本后重新下发任务,如果持续报错,请联系大疆售后。",
|
||||
"316050": "飞行器因电量过低在舱外降落,请立即检查飞行器是否已安全降落并将飞行器放回至机场",
|
||||
"316051": "飞行任务异常,飞行器在舱外降落,请立即检查飞行器是否已安全降落并将飞行器放回至机场",
|
||||
"316052": "飞行任务异常,飞行器将飞往备降点降落,请立即检查飞行器是否已安全降落并将飞行器放回至机场",
|
||||
"316053": "用户已操控飞行器降落,请立即检查飞行器是否已安全降落并将飞行器放回至机场",
|
||||
"316100": "获取相机概要信息失败,请重试",
|
||||
"316101": "设置相机为单拍模式失败,请重试",
|
||||
"316102": "关闭相机水印失败,请重试",
|
||||
"316103": "设置测光模式到平均测光失败,请重试",
|
||||
"316104": "切换镜头到广角镜头失败,请重试",
|
||||
"316105": "设置相机存储照片失败,请重试",
|
||||
"316106": "红外变焦倍数设置失败,请重试",
|
||||
"316107": "照片尺寸设置4k失败,请重试",
|
||||
"316108": "设置照片存储格式为jpeg格式失败,请重试",
|
||||
"316109": "关闭相机畸变矫正失败,请重试",
|
||||
"316110": "打开相机机械快门失败,请重试",
|
||||
"316111": "设置对焦模式失败,请重试",
|
||||
"317001": "获取飞行器媒体文件数量失败,请重启机场后重试",
|
||||
"317002": "飞行器存储格式化失败,飞行器未开机、未连接或未检测到相机,请确认无以上问题后重试,或重启飞行器后重试",
|
||||
"317003": "飞行器存储格式化失败,请重启飞行器后重试",
|
||||
"317004": "机场媒体文件格式化失败,请稍后重试或重启机场后重试",
|
||||
"317005": "飞行器结束录像失败,本次飞行任务的媒体文件可能无法上传",
|
||||
"317006": "无法格式化,请等待当前飞行器媒体文件下载完成后再试",
|
||||
"317007": "获取媒体文件数量失败,请稍后重试,如本架次任务有媒体文件且持续报错可联系大疆售后",
|
||||
"319001": "机场作业中或设备异常反馈上传日志中,无法执行飞行任务,请等待当前飞行任务或操作执行完成后重试",
|
||||
"319002": "机场系统运行异常,请重启机场后重试",
|
||||
"319003": "机场系统运行异常,请重新下发任务",
|
||||
"319004": "飞行任务执行超时,已自动终止本次飞行任务",
|
||||
"319005": "云端与机场通信异常,无法执行飞行任务",
|
||||
"319006": "取消飞行任务失败,飞行任务已经在执行中",
|
||||
"319007": "修改飞行任务失败,飞行任务已经在执行中",
|
||||
"319008": "机场时间与云端时间不同步,机场无法执行飞行任务",
|
||||
"319009": "飞行任务下发失败,请稍后重试或重启机场后重试",
|
||||
"319010": "机场固件版本过低,无法执行飞行任务,请升级机场固件为最新版本后重试",
|
||||
"319015": "机场正在初始化中,无法执行飞行任务,请等待机场初始化完成后重试",
|
||||
"319016": "机场正在执行其他飞行任务,无法执行本次飞行任务",
|
||||
"319017": "机场正在处理上次飞行任务媒体文件,无法执行本次飞行任务,请稍后重试",
|
||||
"319018": "机场正在自动导出日志中(设备异常反馈),无法执行飞行任务,请稍后重试",
|
||||
"319019": "机场正在拉取日志中(设备异常反馈),无法执行飞行任务,请稍后重试",
|
||||
"319020": "航线中断失败,请稍后重试",
|
||||
"319021": "退出远程控制失败,请稍后重试",
|
||||
"319022": "指点飞行失败,请稍后重试",
|
||||
"319023": "指点飞行停止失败,请稍后重试",
|
||||
"319024": "一键起飞失败,请稍后重试",
|
||||
"319025": "机场未准备完成,无法执行云端下发的飞行任务,请稍后重试",
|
||||
"319026": "飞行器电池电量低于用户设置的任务开始执行的电量,请等待充电完成后再执行飞行任务",
|
||||
"319027": "机场或飞行器剩余存储容量过低,无法执行飞行任务,请等待媒体文件上传,机场和飞行器存储容量释放后再执行飞行任务",
|
||||
"319028": "正在更新自定义飞行区",
|
||||
"319029": "正在更新离线地图",
|
||||
"319030": "操作失败,无飞行器控制权",
|
||||
"319031": "控制权异常,请刷新重试",
|
||||
"319032": "指点飞行失败,请稍后重试",
|
||||
"319033": "虚拟摇杆操作失败,请稍后重试",
|
||||
"319034": "虚拟摇杆操作失败,请稍后重试",
|
||||
"319035": "急停失败,请稍后重试",
|
||||
"319036": "设备远程调试中,请稍后重试",
|
||||
"319037": "设备本地调试中,请稍后重试",
|
||||
"319038": "设备正在升级,请稍后重试",
|
||||
"319042": "航线恢复失败,请稍后重试",
|
||||
"319043": "取消返航失败,请稍后重试",
|
||||
"319044": "航线任务已结束,无法恢复",
|
||||
"319045": "急停成功,请重新按键操作",
|
||||
"319046": "无法暂停航线,飞行器尚未进入航线或已退出航线",
|
||||
"319999": "机场系统运行异常,请重启机场后重试",
|
||||
"321000": "航线执行异常,请稍后重试或重启机场后重试",
|
||||
"321004": "航线文件解析失败,无法执行飞行任务,请检查航线文件",
|
||||
"321005": "航线缺少断点信息,机场无法执行飞行任务",
|
||||
"321257": "飞行任务已在执行中,请勿重复执行",
|
||||
"321258": "飞行任务无法终止,请检查飞行器状态",
|
||||
"321259": "飞行任务未开始执行,无法终止飞行任务",
|
||||
"321260": "飞行任务未开始执行,无法中断飞行任务",
|
||||
"321513": "航线规划高度已超过飞行器限高,机场无法执行飞行任务",
|
||||
"321514": "任务失败,起点或终点位于限远区域的缓冲区内或超过了限远距离",
|
||||
"321515": "航线穿过限飞区,机场无法执行飞行任务",
|
||||
"321516": "飞行器飞行高度过低,飞行任务执行被终止",
|
||||
"321517": "飞行器触发避障,飞行任务执行被终止。为保证飞行安全,请勿用当前航线执行断点续飞任务",
|
||||
"321519": "飞行器接近限飞区或限远距离自动返航,无法完成航线飞行",
|
||||
"321523": "飞行器起飞失败,请稍后重试,如果仍报错请联系大疆售后。",
|
||||
"321524": "飞行器起飞前准备失败,可能是飞行器无法定位或档位错误导致,请检查飞行器状态",
|
||||
"321528": "触碰自定义飞行区边界,航线任务已暂停",
|
||||
"321529": "目标点位于禁飞区域或者障碍物内,无法到达,航线任务已暂停,请重新规划后再试",
|
||||
"321530": "飞行器飞行航线过程中轨迹规划失败,航线任务已暂停",
|
||||
"321531": "进离场航线执行失败,请联系大疆售后。",
|
||||
"321532": "进离场航线执行失败,请联系大疆售后。",
|
||||
"321533": "进离场航线执行失败,请联系大疆售后。",
|
||||
"321769": "飞行器卫星定位信号差,无法执行飞行任务,请重启机场后重试",
|
||||
"321770": "飞行器挡位错误,无法执行飞行任务,请重启机场后重试",
|
||||
"321771": "飞行器返航点未设置,无法执行飞行任务,请重启机场后重试",
|
||||
"321772": "飞行器电量低于30%,无法执行飞行任务,请充电后重试(建议电量≥50%)",
|
||||
"321773": "飞行器执行飞行任务过程中低电量返航,无法完成航线飞行",
|
||||
"321775": "飞行器航线飞行过程中失联,无法完成航线飞行",
|
||||
"321776": "飞行器 RTK 收敛失败,无法执行飞行任务,请重启机场后重试",
|
||||
"321777": "飞行器未悬停,无法开始执行飞行任务",
|
||||
"321778": "用户使用 B 控操控飞行器起桨,机场无法执行飞行任务",
|
||||
"321784": "任务过程中遇到大风紧急返航",
|
||||
"322281": "任务失败,机场执行飞行任务过程被手动打断或异常终止",
|
||||
"322282": "机场执行飞行任务过程中被中断,飞行器被云端用户或遥控器接管",
|
||||
"322283": "机场执行飞行任务过程中被用户触发返航,无法完成航线飞行",
|
||||
"322539": "航线的断点信息错误,机场无法执行飞行任务",
|
||||
"322563": "航线轨迹生成失败,请检查飞行器视觉镜头是否存在脏污或重启飞行器后再试,如果仍报错请联系大疆售后",
|
||||
"324012": "日志压缩过程超时,所选日志过多,请减少选择的日志后重试",
|
||||
"324013": "设备日志列表获取失败,请稍后重试",
|
||||
"324014": "设备日志列表为空,请刷新页面或重启机场后重试",
|
||||
"324015": "飞行器已关机或未连接,无法获取日志列表,请确认飞行器在舱内,通过远程调试将飞行器开机后重试",
|
||||
"324016": "机场存储空间不足,日志压缩失败,请清理机场存储空间或稍后重试",
|
||||
"324017": "日志压缩失败,无法获取所选飞行器日志,请刷新页面或重启机场后重试",
|
||||
"324018": "日志文件拉取失败,导致本次设备异常反馈上传失败,请稍后重试或重启机场后重试",
|
||||
"324019": "因机场网络异常,日志上传失败,请稍后重试。如果连续多次出现该问题,请联系代理商或大疆售后进行网络排障",
|
||||
"324021": "因机场断电或重启导致日志导出中断,日志导出失败,请稍后重试",
|
||||
"324030": "因机场网络异常、飞行器图传链路异常等原因,媒体文件暂时无法上传或文件已上传但云端读取失败",
|
||||
"325001": "云端下发命令不符合格式要求,设备无法执行",
|
||||
"325003": "指令响应失败,请重试",
|
||||
"325004": "设备端命令请求已超时,请重试",
|
||||
"325005": "当前机场无法响应任务,请稍后重试",
|
||||
"325006": "当前机场启动检查中,请稍后重试",
|
||||
"325007": "当前机场执行作业任务中,请稍后重试",
|
||||
"325008": "当前机场处理作业任务结果中,请稍后重试",
|
||||
"325009": "当前机场执行远程日志导出中,请稍后重试",
|
||||
"325010": "当前机场更新自定义飞行区中,请稍后重试",
|
||||
"325011": "当前机场更新离线地图中,请稍后重试",
|
||||
"325012": "当前飞机未连接,请稍后重试",
|
||||
"326002": "飞行器未安装 DJI Cellualr 模块",
|
||||
"326003": "飞行器 DJI Cellualr 模块中未安装 SIM 卡",
|
||||
"326004": "飞行器 DJI Cellualr 模块需要强制升级,否则无法使用",
|
||||
"326005": "操作失败,增强图传无法建立连接,请检查 4G 信号强度,或咨询运营商查询套餐流量和 APN 设置",
|
||||
"326006": "增强图传开关切换失败,请稍后重试",
|
||||
"326008": "机场未安装 DJI Cellualr 模块",
|
||||
"326009": "机场 DJI Cellualr 模块中未安装 SIM 卡",
|
||||
"326010": "机场 DJI Cellualr 模块需要强制升级,否则无法使用",
|
||||
"326103": "当前 eSIM 正在激活中,请稍后再试",
|
||||
"326104": "当前 eSIM 正在切换运营商中,请稍后再试",
|
||||
"326105": "DJI 增强图传模块正在切换模式中,请稍后再试",
|
||||
"326106": "DJI 增强图传模块异常,请重启设备后再试,如果仍报错请联系大疆售后",
|
||||
"326107": "请在设备管理 > 机场 > 设备运维中激活DJI增强图传模块的 eSIM 或插入 SIM 卡后再试",
|
||||
"327000": "参数设置失败,请稍后重试",
|
||||
"327001": "参数设置失败,请稍后重试",
|
||||
"327002": "获取控制权失败,请稍后重试",
|
||||
"327003": "获取控制权失败,请稍后重试",
|
||||
"327004": "画面拖动失败,请重试",
|
||||
"327005": "双击画面归中失败",
|
||||
"327006": "拍照失败",
|
||||
"327007": "开始录像失败",
|
||||
"327008": "停止录像失败",
|
||||
"327009": "切换相机模式失败",
|
||||
"327010": "ZOOM相机变焦失败",
|
||||
"327011": "IR相机变焦失败",
|
||||
"327012": "获取控制权失败,请稍后重试",
|
||||
"327013": "参数设置失败,请稍后重试",
|
||||
"327014": "云台已达限位",
|
||||
"327015": "直播启动失败,建议刷新直播或重新打开设备小窗",
|
||||
"327016": "失联动作设置失败,请重试",
|
||||
"327017": "指点飞行高度设置失败,请重试",
|
||||
"327018": "指点飞行模式切换失败,请重试",
|
||||
"327019": "当前状态无法看向标注点",
|
||||
"327020": "全景拍照停止命令超时",
|
||||
"327050": "当前设备状态不支持播放音频",
|
||||
"327051": "下载音频文件失败",
|
||||
"327052": "喊话器处理模式切换失败",
|
||||
"327053": "上传音频文件失败",
|
||||
"327054": "播放音频失败",
|
||||
"327055": "设置工作模式失败",
|
||||
"327056": "上传文本失败",
|
||||
"327057": "停止播放失败",
|
||||
"327058": "设置播放模式失败",
|
||||
"327059": "设置音量失败",
|
||||
"327060": "设置控件值失败",
|
||||
"327061": "发送文本值失败",
|
||||
"327062": "切换系统语言失败",
|
||||
"327063": "获取设备功能列表失败",
|
||||
"327064": "获取设备配置文件失败",
|
||||
"327065": "获取设备图片文件失败",
|
||||
"327066": "设备文件压缩失败",
|
||||
"327067": "设备文件上传失败",
|
||||
"327068": "上传音频文件失败,md5校验失败",
|
||||
"327069": "上传音频文件失败",
|
||||
"327070": "上传音频文件失败,异常终止",
|
||||
"327071": "上传TTS文本失败,md5校验失败",
|
||||
"327072": "上传TTS文本失败",
|
||||
"327073": "上传TTS文本失败,异常终止",
|
||||
"327074": "喊话器重播失败",
|
||||
"327075": "喊话器编码失败",
|
||||
"327201": "全景拍照失败",
|
||||
"327202": "全景拍摄终止",
|
||||
"327203": "当前设备不支持全景拍照",
|
||||
"327204": "系统繁忙,无法全景拍照",
|
||||
"327205": "请求失败,无法全景拍照",
|
||||
"327206": "飞机未起飞,无法开始全景拍摄",
|
||||
"327207": "控制权获取失败,全景拍摄终止",
|
||||
"327208": "未知相机错误,无法开始全景拍摄",
|
||||
"327209": "相机超时,全景拍摄终止",
|
||||
"327210": "无法全景拍照",
|
||||
"327211": "存储空间不足,全景拍摄终止",
|
||||
"327212": "飞机运动中,无法开始全景拍摄",
|
||||
"327213": "云台运动中,无法开始全景拍摄",
|
||||
"327214": "用户操作摇杆,全景拍摄终止",
|
||||
"327215": "碰到限飞区,全景拍摄终止",
|
||||
"327216": "触发距离限制,全景拍摄终止",
|
||||
"327217": "云台受阻,全景拍摄终止",
|
||||
"327218": "拍照失败,全景拍摄终止",
|
||||
"327219": "全景图片拼接失败",
|
||||
"327220": "加载标定参数失败,全景拍摄终止",
|
||||
"327221": "调整相机参数失败,全景拍摄终止",
|
||||
"327500": "飞行器镜头除雾失败,请稍后重试",
|
||||
"328051": "飞机未完成实名登记,请连接遥控器,按照指引完成、实名登记后飞行",
|
||||
"328052": "飞机实名登记状态已注销,请连接遥控器,按照指引完成实名登记后飞行",
|
||||
"336000": "指点飞行命令发送失败,请重试",
|
||||
"336001": "飞行器数据异常,无法响应指令",
|
||||
"336002": "飞行器GPS信号差",
|
||||
"336003": "飞行器定位失效,无法响应指令",
|
||||
"336004": "指点飞行自主规划失败",
|
||||
"336005": "飞行器返航点未更新",
|
||||
"336006": "飞行器已失联,已退出指点飞行",
|
||||
"336017": "飞行器电量不足以完成当前任务",
|
||||
"336018": "已切换飞行器规划模式",
|
||||
"336019": "指点飞行因限高自动调整飞行高度",
|
||||
"336513": "目标点在禁飞区内",
|
||||
"336514": "目标点超出飞行器限远",
|
||||
"336515": "目标点在禁飞区内",
|
||||
"336516": "目标点超出飞行器限高",
|
||||
"336517": "目标点超出飞行器限低",
|
||||
"337025": "飞行器无法起飞",
|
||||
"337026": "目标点异常,请重试",
|
||||
"337027": "飞行器速度设置异常,请重试",
|
||||
"337028": "飞行器版本异常,请检查飞行器版本",
|
||||
"337029": "飞行器无法响应当前任务,请稍后重试",
|
||||
"337030": "指令飞行安全离场高过低",
|
||||
"337537": "已触碰禁飞区",
|
||||
"337538": "已触碰飞行器限远",
|
||||
"337539": "已触碰禁飞区",
|
||||
"337540": "已触碰飞行器限高或限高区",
|
||||
"337541": "已触碰飞行器限低",
|
||||
"337542": "飞行器起飞失败,请重试",
|
||||
"337543": "目标点可能在障碍物内,请检查周边环境",
|
||||
"337544": "检测到障碍物,请检查周边环境",
|
||||
"337545": "飞行器规划异常,请重试",
|
||||
"337546": "已触碰自定义飞行区边界",
|
||||
"338001": "飞行器通信异常,无法执行飞行任务,请重启飞行器与机场后重试",
|
||||
"338002": "飞行器通信异常,无法执行飞行任务,请重启飞行器与机场后重试",
|
||||
"338003": "飞行器通信异常,无法执行飞行任务,请重启飞行器与机场后重试",
|
||||
"338004": "飞行器通信异常,无法执行飞行任务,请重启飞行器与机场后重试",
|
||||
"338005": "起飞机场与降落机场部署距离超出限制,无法执行飞行任务,请选择两个部署距离不超过 15km 的机场执行任务",
|
||||
"338006": "无法执行飞行任务,请检查降落机场是否已申请解禁证书、是否位于自定义禁飞区或是否位于自定义飞行区外",
|
||||
"338007": "目标降落机场部署突破限高区限高,无法执行任务,请申请解禁证书后再试",
|
||||
"338008": "目标降落机场部署突破飞行器设置的限高,无法执行任务,请调整限高后重试",
|
||||
"338009": "飞行器 GPS 定位信号差,无法执行任务,请重启飞行器后重试",
|
||||
"338010": "飞行器定位失效,无法执行任务,请重启飞行器后重试",
|
||||
"338011": "任务失败,目标机场处于地理鸟笼作业区域外,请重新规划任务后再试",
|
||||
"338017": "飞行器数据更新失败,无法执行任务,请重启飞行器后重试",
|
||||
"338018": "飞行器数据更新失败,无法执行任务,请重启飞行器后重试",
|
||||
"338019": "飞行器到目标机场的返航路线正在规划中,无法执行任务,请重启飞行器后重试",
|
||||
"338020": "飞行器无法根据规划的路径到达目标降落机场,无法执行任务,请重新选择降落机场后再试",
|
||||
"338021": "飞行器当前电量不足以到达目标降落机场,无法执行任务,请给飞行器充电后重试",
|
||||
"338049": "响应遥控器杆量,已退出指点飞行",
|
||||
"338050": "响应终止指令,已退出指点飞行",
|
||||
"338051": "飞行器低电量返航,已退出指点飞行",
|
||||
"338052": "飞行器低电量降落,已退出指点飞行",
|
||||
"338053": "附近有载人机,已退出指点飞行",
|
||||
"338054": "响应其他高优先级任务,已退出指点飞行",
|
||||
"338255": "飞行器通信异常,无法执行飞行任务,请重启飞行器与机场后重试",
|
||||
"386535": "航线执行异常,请稍后重试或重启机场后重试",
|
||||
"513002": "直播失败,相机不存在或相机类型错误",
|
||||
"513003": "相机已经在直播中,请勿重复开启直播",
|
||||
"513005": "直播失败,直播参数(清晰度)设置错误",
|
||||
"513006": "直播启动失败,请刷新重试",
|
||||
"513008": "直播失败,设备端图传数据异常",
|
||||
"513010": "直播失败,设备无法联网",
|
||||
"513011": "操作失败,设备未开启直播",
|
||||
"513012": "操作失败,设备已在直播中,不支持切换镜头",
|
||||
"513013": "直播失败,直播使用的视频传输协议不支持",
|
||||
"513014": "直播失败,直播参数错误或者不完整",
|
||||
"513015": "直播异常,网络卡顿, 请刷新后重试",
|
||||
"513016": "直播异常,视频解码失败",
|
||||
"513017": "直播已暂停,请等待当前飞行器媒体文件下载完成后再试",
|
||||
"513099": "直播失败,请稍后重试",
|
||||
"514100": "机场运行异常,请重启机场后重试",
|
||||
"514101": "推杆闭合失败,请检查停机坪上是否存在异物,飞行器方向是否放反,或重启机场后重试",
|
||||
"514102": "推杆展开失败,请检查停机坪上是否存在异物,或重启机场后重试",
|
||||
"514103": "飞行器电量低于30%,无法执行飞行任务,请充电后重试(建议电量≥50%)",
|
||||
"514104": "飞行器电池开始充电失败,请重启机场后重试",
|
||||
"514105": "飞行器电池停止充电失败,请重启机场后重试",
|
||||
"514106": "飞行器电源控制异常,请重启机场后重试",
|
||||
"514107": "舱盖开启失败,请检查舱盖周围是否存在异物,或重启机场后重试",
|
||||
"514108": "舱盖关闭失败,请检查舱盖周围是否存在异物,或重启机场后重试",
|
||||
"514109": "飞行器开机失败,请检查飞行器是否在舱和飞机电量是否正常,或重启机场后重试",
|
||||
"514110": "飞行器关机失败,请重启机场后重试",
|
||||
"514111": "飞行器慢转收桨控制异常,请重启机场后重试",
|
||||
"514112": "飞行器慢转收桨控制异常,请重启机场后重试",
|
||||
"514113": "机场推杆与飞行器无法连接,请检查飞行器是否在舱内,推杆闭合时是否被卡住,充电连接器是否脏污或损坏",
|
||||
"514114": "获取飞行器电源状态失败,请重启机场后重试",
|
||||
"514116": "无法执行当前操作,机场正在执行其他控制指令,请稍后重试",
|
||||
"514117": "舱盖开启或关闭未到位,请重启机场后重试",
|
||||
"514118": "推杆展开或闭合未到位,请重启机场后重试",
|
||||
"514120": "机场与飞行器断连,请重启机场后重试或重新对频",
|
||||
"514121": "机场急停按钮被按下,请释放急停按钮",
|
||||
"514122": "获取飞行器充电状态失败,请重启机场后重试",
|
||||
"514123": "飞行器电池电量过低无法开机",
|
||||
"514124": "获取飞行器电池信息失败,无法执行飞行任务,请重启机场后重试",
|
||||
"514125": "飞行器电池电量已接近满电状态,无法开始充电,请使用至95%以下再进行充电",
|
||||
"514134": "雨量过大,机场无法执行飞行任务,请稍后重试",
|
||||
"514135": "风速过大,机场无法执行飞行任务,请稍后重试",
|
||||
"514136": "机场供电断开,机场无法执行飞行任务,请恢复机场供电后重试",
|
||||
"514137": "环境温度过低于-20℃ (-4°F),机场无法执行飞行任务,请稍后重试",
|
||||
"514138": "飞行器电池正在保养中,机场无法执行飞行任务,请等待保养结束后重试",
|
||||
"514139": "飞行器电池无法执行保养指令,飞行器电池无需保养",
|
||||
"514140": "飞行器电池无法执行保养指令,飞行器电池无需保养",
|
||||
"514141": "机场系统运行异常,请重启机场后重试",
|
||||
"514142": "飞行器起飞前,机场推杆与飞行器无法连接,请检查飞行器是否在舱内,推杆闭合时是否被卡住,充电连接器是否脏污或损坏",
|
||||
"514143": "推杆未闭合或闭合不到位,请稍后重试或重启机场后重试",
|
||||
"514144": "舱盖未关闭或关闭不到位,请稍后重试或重启机场后重试",
|
||||
"514145": "机场处于现场调试中,无法执行当前操作或执行飞行任务,请断开遥控器和机场的数据线连接后重试",
|
||||
"514146": "机场处于远程调试中,无法执行飞行任务,请退出远程调试后重试",
|
||||
"514147": "设备升级中,无法进行远程调试或执行飞行任务,请等待升级完成后重试",
|
||||
"514148": "机场已经在作业中,无法进行远程调试或再次执行飞行任务,请等待当前任务执行完成后重试",
|
||||
"514149": "机场系统运行异常,无法执行飞行任务,请重启机场后重试",
|
||||
"514150": "设备重启中,无法执行飞行任务,请等待重启完成后重试",
|
||||
"514151": "设备升级中,无法执行设备重启指令,请等待升级完成后重试",
|
||||
"514153": "机场已退出远程调试模式,无法执行当前操作",
|
||||
"514154": "获取内循环出风口温度失败,请稍后再试",
|
||||
"514156": "飞机不在舱内,请立即检查飞行器是否已安全降落并将飞行器放回至机场",
|
||||
"514157": "执行开机失败,无线充电线圈业务繁忙,请重启机场后再试复",
|
||||
"514158": "无法起飞,机场 RTK 业务异常,请重启机场后再试",
|
||||
"514159": "任务失败,降落机场检测到飞行器,请确保降落机场没有飞行器后再试",
|
||||
"514162": "飞行器和机场连接失败,请关闭机场舱盖或重启机场后再试",
|
||||
"514163": "电池功能异常,请确保飞行器电池插入到位或重启飞行器后再试",
|
||||
"514164": "设备重启失败,请稍后重试,如果仍报错请联系大疆售后",
|
||||
"514165": "设备重启失败,请稍后重试,如果仍报错请联系大疆售后",
|
||||
"514170": "机场系统初始化中,无法执行当前操作或指令,请等待机场系统初始化完成后重试",
|
||||
"514171": "云端下发给机场的命令不符合格式要求,机场无法执行",
|
||||
"514172": "飞行器无法关机,蓝牙连接状态为未连接,请尝试重启飞行器和机场,或去现场重新对频飞行器与机场后再试",
|
||||
"514173": "由于天气原因(环境温度低于5度并且降雨大于等于中雨),可能导致桨叶结冰影响作业安全,暂无法执行任务",
|
||||
"514174": "飞行器充电失败,机场舱盖开启或关闭未到位,请关闭舱盖后再试",
|
||||
"514180": "停止空调制冷或停止空调制热失败,请稍后重试",
|
||||
"514181": "开启空调制冷失败,请稍后重试",
|
||||
"514182": "开启空调制热失败,请稍后重试",
|
||||
"514183": "开启空调除湿失败,请稍后重试",
|
||||
"514184": "当前温度低于 0 ℃(32°F),无法开启空调制冷",
|
||||
"514185": "当前温度高于 45 ℃(115°F),无法开启空调制热",
|
||||
"514300": "网关异常",
|
||||
"514301": "请求超时,连接断开",
|
||||
"514302": "网络证书异常,连接失败",
|
||||
"514303": "网络异常,连接断开",
|
||||
"514304": "请求被拒,连接失败"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
import { clientReizePublish, clientReizeSubscribe } from '@/utils/mqtt';
|
||||
import { airPortStore } from '@/store/modules/airport';
|
||||
|
||||
const airPortStoreVal = airPortStore();
|
||||
|
||||
export const return_home_status = {
|
||||
canceled: '取消或终止',
|
||||
failed: '失败',
|
||||
in_progress: '执行中',
|
||||
ok: '执行成功',
|
||||
paused: '暂停',
|
||||
rejected: '拒绝',
|
||||
sent: '已下发',
|
||||
timeout: '超时',
|
||||
};
|
||||
export const eventsTopicReize = (data) => {
|
||||
// 发送消息
|
||||
clientReizePublish('thing/product/' + airPortStoreVal.getGateway + '/events', data);
|
||||
};
|
||||
export const events_replyTopicReize = () => {
|
||||
// 订阅消息
|
||||
clientReizeSubscribe('thing/product/' + airPortStoreVal.getGateway + '/events_reply');
|
||||
};
|
||||
|
||||
export const servicesTopicReize = (data) => {
|
||||
// 发送消息
|
||||
clientReizePublish('thing/product/' + airPortStoreVal.getGateway + '/services', data);
|
||||
};
|
||||
export const services_replyTopicReize = () => {
|
||||
// 订阅消息
|
||||
clientReizeSubscribe('thing/product/' + airPortStoreVal.getGateway + '/services_reply');
|
||||
};
|
||||
export const drcDownTopicReize = (data) => {
|
||||
// 发送消息thing/product/{gateway_sn}/drc/down
|
||||
clientReizePublish('thing/product/' + airPortStoreVal.getGateway + '/drc/down', data);
|
||||
};
|
||||
export const eventsTopicSubscribeReize = () => {
|
||||
// 发送消息
|
||||
clientReizeSubscribe('thing/product/' + airPortStoreVal.getGateway + '/events');
|
||||
};
|
||||
|
|
@ -0,0 +1,73 @@
|
|||
import { getClient, createConnection, clientPublish, clientSubscribe } from '@/utils/mqtt';
|
||||
import { airPortStore } from '@/store/modules/airport';
|
||||
import errorCode from './error_code.json';
|
||||
|
||||
const airPortStoreVal = airPortStore();
|
||||
export const debug_mode_openOptions = {
|
||||
canceled: '取消或终止',
|
||||
failed: '失败',
|
||||
in_progress: '执行中',
|
||||
ok: '执行成功',
|
||||
paused: '暂停',
|
||||
rejected: '拒绝',
|
||||
sent: '已下发',
|
||||
timeout: '超时',
|
||||
};
|
||||
export const cover_stateOptions = { '0': '关闭', '1': '打开', '2': '半开', '3': '舱盖状态异常' };
|
||||
export const cover_opensStatus = {
|
||||
canceled: '取消或终止',
|
||||
failed: '失败',
|
||||
in_progress: '执行中',
|
||||
ok: '执行成功',
|
||||
paused: '暂停',
|
||||
rejected: '拒绝',
|
||||
sent: '已下发',
|
||||
timeout: '超时',
|
||||
};
|
||||
|
||||
export const errorName = (code) => {
|
||||
const error_code = errorCode.error_code;
|
||||
if (error_code[code]) {
|
||||
return error_code[code];
|
||||
} else {
|
||||
return '错误码' + code;
|
||||
}
|
||||
};
|
||||
export const servicesTopic = (data) => {
|
||||
console.log(airPortStoreVal.getGateway);
|
||||
// 发送消息
|
||||
clientPublish('thing/product/' + airPortStoreVal.getGateway + '/services', data);
|
||||
};
|
||||
export const services_replyTopic = () => {
|
||||
// 订阅消息
|
||||
clientSubscribe('thing/product/' + airPortStoreVal.getGateway + '/services_reply');
|
||||
};
|
||||
export const eventsTopic = (data) => {
|
||||
// 发送消息
|
||||
clientPublish('thing/product/' + airPortStoreVal.getGateway + '/events', data);
|
||||
};
|
||||
export const events_replyTopic = () => {
|
||||
// 订阅消息
|
||||
clientSubscribe('thing/product/' + airPortStoreVal.getGateway + '/events_reply');
|
||||
};
|
||||
export const drcDownTopic = (data) => {
|
||||
// 发送消息thing/product/{gateway_sn}/drc/down
|
||||
clientPublish('thing/product/' + airPortStoreVal.getGateway + '/drc/down', data);
|
||||
};
|
||||
|
||||
export const eventsTopicSubscribe = () => {
|
||||
// 发送消息
|
||||
clientSubscribe('thing/product/' + airPortStoreVal.getGateway + '/events');
|
||||
};
|
||||
export const drcUpTopic = () => {
|
||||
clientSubscribe('thing/product/' + airPortStoreVal.getGateway + '/drc/up');
|
||||
};
|
||||
|
||||
export const setTopic = (data) => {
|
||||
// 发送消息
|
||||
clientPublish('thing/product/' + airPortStoreVal.getGateway + '/property/set', data);
|
||||
};
|
||||
export const set_replyTopic = () => {
|
||||
// 订阅消息
|
||||
clientSubscribe('thing/product/' + airPortStoreVal.getGateway + '/services_reply');
|
||||
};
|
||||
|
|
@ -162,3 +162,8 @@ export const getAssetsImg = (url: string) => {
|
|||
const data = url.split('@/')[1];
|
||||
return new URL(`../${data}`, import.meta.url).href;
|
||||
};
|
||||
// 时间戳转时间
|
||||
export const timestampToFormattedDate = (timestamp) => {
|
||||
const date = new Date(timestamp);
|
||||
return `${date.getFullYear()}-${('0' + (date.getMonth() + 1)).slice(-2)}-${('0' + date.getDate()).slice(-2)} ${('0' + date.getHours()).slice(-2)}:${('0' + date.getMinutes()).slice(-2)}:${('0' + date.getSeconds()).slice(-2)}`;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -0,0 +1,221 @@
|
|||
import mqtt from 'mqtt';
|
||||
import { useMessage } from '@/hooks/web/useMessage';
|
||||
import { getRedisUser, addOrUpdateRedisUser } from '@/api/demo/airportMaintenance';
|
||||
import { useUserStore } from '@/store/modules/user';
|
||||
import { timestampToFormattedDate } from '@/utils/index';
|
||||
|
||||
const userStore = useUserStore();
|
||||
const userInfo = userStore.getUserInfo;
|
||||
|
||||
const { createMessage } = useMessage();
|
||||
const seizeClientId = 'mqtt_client_1581F8HGX254V00A0BUY_seize';
|
||||
const connection = {
|
||||
protocol: 'ws',
|
||||
host: '175.27.168.120',
|
||||
// server less服务器只有两种协议:mqtts: 8883; wss: 8084
|
||||
port: 6010,
|
||||
endpoint: '/mqtt',
|
||||
// for more options, please refer to https://github.com/mqttjs/MQTT.js#mqttclientstreambuilder-options
|
||||
clean: true,
|
||||
connectTimeout: 30 * 1000, // ms
|
||||
reconnectPeriod: 4000, // ms
|
||||
clientId: '',
|
||||
// clientId: 'mqtt_client_1581F8HGX254V00A0BUY',
|
||||
// auth
|
||||
username: 'sdhc',
|
||||
password: '',
|
||||
};
|
||||
|
||||
let client: any = {
|
||||
connected: false,
|
||||
};
|
||||
let retryTimes = 0;
|
||||
const initData = () => {
|
||||
client = {
|
||||
connected: false,
|
||||
};
|
||||
retryTimes = 0;
|
||||
};
|
||||
// 重新连接
|
||||
const handleOnReConnect = () => {
|
||||
retryTimes += 1;
|
||||
if (retryTimes > 5) {
|
||||
try {
|
||||
client.end();
|
||||
initData();
|
||||
createMessage.error('连接的最大重连次数限制,停止重试');
|
||||
} catch (error) {
|
||||
createMessage.error(error.toString());
|
||||
}
|
||||
}
|
||||
};
|
||||
// 创建连接函数
|
||||
const createConnection = (callback?) => {
|
||||
console.log('创建连接');
|
||||
// 连接mqtt的时候,先用GetRedisUser查一下有没有,
|
||||
// 然后AddOrUpdateRedisUser更新或添加,
|
||||
// 控制的时候先查一下有没有锁定的用户GetLockedClients
|
||||
try {
|
||||
getRedisUser(userInfo.id).then((res) => {
|
||||
console.log(res);
|
||||
if (res) {
|
||||
connection.clientId = res.clientId;
|
||||
} else {
|
||||
const clientId = 'mqttx_' + Math.random().toString(16).substring(2, 8);
|
||||
connection.clientId = clientId;
|
||||
const querys = {
|
||||
clientId: clientId,
|
||||
userId: userInfo.id,
|
||||
userName: userInfo.name,
|
||||
isLock: false,
|
||||
connectTime: timestampToFormattedDate(new Date().getTime()),
|
||||
};
|
||||
addOrUpdateRedisUser(querys);
|
||||
}
|
||||
const { protocol, host, port, endpoint, ...options } = connection;
|
||||
const connectUrl = `${protocol}://${host}:${port}${endpoint}`;
|
||||
client = mqtt.connect(connectUrl, options);
|
||||
client.on('connect', () => {
|
||||
if (callback) {
|
||||
callback();
|
||||
}
|
||||
});
|
||||
});
|
||||
const clientId = 'mqttx_' + Math.random().toString(16).substring(2, 8);
|
||||
connection.clientId = clientId;
|
||||
} catch (error) {
|
||||
console.log('mqtt.connect error', error);
|
||||
}
|
||||
};
|
||||
const getClient = () => {
|
||||
// if (!client || !client.connected) {
|
||||
// createConnection();
|
||||
// }
|
||||
return client;
|
||||
};
|
||||
// 断开连接
|
||||
const destroyConnection = () => {
|
||||
if (client.connected) {
|
||||
try {
|
||||
client.end(false, () => {
|
||||
initData();
|
||||
console.log('Successfully disconnected!');
|
||||
});
|
||||
} catch (error) {
|
||||
console.log('Disconnect failed', error.toString());
|
||||
}
|
||||
}
|
||||
};
|
||||
// 订阅事件
|
||||
const clientSubscribe = (topic: string, options?: any) => {
|
||||
// if (!client || !client.connected) {
|
||||
// createConnection();
|
||||
// }
|
||||
getClient().subscribe(topic, { qos: 0 }, (error, res) => {});
|
||||
};
|
||||
// 发送消息
|
||||
const clientPublish = (topic: string, querys: any) => {
|
||||
// if (!client || !client.connected) {
|
||||
// createConnection();
|
||||
// }
|
||||
getClient().publish(topic, JSON.stringify(querys), { qos: 0 }, (err) => {
|
||||
// if(err == undefined){
|
||||
// createMessage.error('指令执行失败,请检查设备连接状态');
|
||||
// }
|
||||
if (err) {
|
||||
console.error('Publish error:', err);
|
||||
}
|
||||
});
|
||||
};
|
||||
// 获取连接状态
|
||||
const getConnectStatus = () => {
|
||||
if (!client.connected) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
// on 事件
|
||||
// connect 连接
|
||||
// reconnect 重新连接
|
||||
// error 错误
|
||||
// message 监听消息
|
||||
|
||||
// end 事件 停止连接
|
||||
// publish 事件 发送
|
||||
// subscribe 事件 订阅
|
||||
// unsubscribe 事件 取消订阅
|
||||
|
||||
// 抢夺负载权、飞行控制权的时候使用
|
||||
let client_seize: any = {
|
||||
connected: false,
|
||||
};
|
||||
const createSeizeConnection = () => {
|
||||
const seizeConnection = connection;
|
||||
seizeConnection.clientId = seizeClientId;
|
||||
try {
|
||||
const { protocol, host, port, endpoint, ...options } = seizeConnection;
|
||||
const connectUrl = `${protocol}://${host}:${port}${endpoint}`;
|
||||
client_seize = mqtt.connect(connectUrl, options);
|
||||
if (client.on) {
|
||||
}
|
||||
} catch (error) {
|
||||
console.log('mqtt.connect error', error);
|
||||
}
|
||||
};
|
||||
const destroySeizeConnection = () => {
|
||||
if (client_seize.connected) {
|
||||
try {
|
||||
client_seize.end(false, () => {
|
||||
client_seize = {
|
||||
connected: false,
|
||||
};
|
||||
console.log('Successfully disconnected!');
|
||||
});
|
||||
} catch (error) {
|
||||
console.log('Disconnect failed', error.toString());
|
||||
}
|
||||
}
|
||||
};
|
||||
const getReizeClient = () => {
|
||||
// if (!client_seize || !client_seize.connected) {
|
||||
// createSeizeConnection();
|
||||
// }
|
||||
return client_seize;
|
||||
};
|
||||
// 订阅事件
|
||||
const clientReizeSubscribe = (topic: string, options?: any) => {
|
||||
// if (!client_seize || !client_seize.connected) {
|
||||
// createSeizeConnection();
|
||||
// }
|
||||
getReizeClient().subscribe(topic, { qos: 0 }, (error, res) => {
|
||||
console.log('订阅');
|
||||
console.log(error, res);
|
||||
});
|
||||
};
|
||||
// 发送消息
|
||||
const clientReizePublish = (topic: string, querys: any) => {
|
||||
// if (!client_seize || !client_seize.connected) {
|
||||
// createSeizeConnection();
|
||||
// }
|
||||
getReizeClient().publish(topic, JSON.stringify(querys), { qos: 0 }, (err) => {
|
||||
if (err) {
|
||||
console.error('Publish error:', err);
|
||||
}
|
||||
});
|
||||
};
|
||||
export {
|
||||
connection,
|
||||
seizeClientId,
|
||||
// 连接
|
||||
createConnection,
|
||||
destroyConnection,
|
||||
getClient,
|
||||
clientSubscribe,
|
||||
clientPublish,
|
||||
createSeizeConnection,
|
||||
destroySeizeConnection,
|
||||
getReizeClient,
|
||||
clientReizeSubscribe,
|
||||
clientReizePublish,
|
||||
getConnectStatus,
|
||||
};
|
||||
|
|
@ -40,3 +40,32 @@ export function buildShortUUID(prefix = ''): string {
|
|||
unique++;
|
||||
return prefix + '_' + random + unique + String(time);
|
||||
}
|
||||
export function uuid(len, radix) {
|
||||
const chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split('');
|
||||
let uuid = [],
|
||||
i;
|
||||
radix = radix || chars.length;
|
||||
|
||||
if (len) {
|
||||
// Compact form
|
||||
for (i = 0; i < len; i++) uuid[i] = chars[0 | (Math.random() * radix)];
|
||||
} else {
|
||||
// rfc4122, version 4 form
|
||||
let r;
|
||||
|
||||
// rfc4122 requires these characters
|
||||
uuid[8] = uuid[13] = uuid[18] = uuid[23] = '-';
|
||||
uuid[14] = '4';
|
||||
|
||||
// Fill in random data. At i==19 set the high bits of clock sequence as
|
||||
// per rfc4122, sec. 4.1.5
|
||||
for (i = 0; i < 36; i++) {
|
||||
if (!uuid[i]) {
|
||||
r = 0 | (Math.random() * 16);
|
||||
uuid[i] = chars[i == 19 ? (r & 0x3) | 0x8 : r];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return uuid.join('');
|
||||
}
|
||||
|
|
@ -163,6 +163,7 @@
|
|||
|
||||
// 双击添加
|
||||
const dblclickHandle = async (item: ConfigType) => {
|
||||
console.log('双击添加', item);
|
||||
if (item.disabled) return;
|
||||
// 保存的分组,进行使用
|
||||
if (item.key == 'GroupItem') {
|
||||
|
|
@ -230,6 +231,7 @@
|
|||
componentInstall(item.conKey, fetchConfigComponent(item));
|
||||
// 创建新图表组件
|
||||
let newComponent: CreateComponentType = await createComponent(item);
|
||||
console.log(newComponent);
|
||||
if (item.redirectComponent) {
|
||||
item.dataset && (newComponent.option.dataset = item.dataset);
|
||||
newComponent.chartConfig.title = item.title;
|
||||
|
|
|
|||
|
|
@ -58,32 +58,36 @@ const packagesListObj = {
|
|||
},
|
||||
[PackagesCategoryEnum.ZHIGAN]: {
|
||||
icon: renderIcon(AirPlaneOutlineIcon),
|
||||
label: PackagesCategoryName.ZHIGAN
|
||||
label: PackagesCategoryName.ZHIGAN,
|
||||
},
|
||||
[PackagesCategoryEnum.ZHILAN]: {
|
||||
icon: renderIcon(AirPlaneOutlineIcon),
|
||||
label: PackagesCategoryName.ZHILAN
|
||||
label: PackagesCategoryName.ZHILAN,
|
||||
},
|
||||
[PackagesCategoryEnum.ZHICHU]: {
|
||||
icon: renderIcon(AirPlaneOutlineIcon),
|
||||
label: PackagesCategoryName.ZHICHU
|
||||
label: PackagesCategoryName.ZHICHU,
|
||||
},
|
||||
[PackagesCategoryEnum.ZHIKU]: {
|
||||
icon: renderIcon(AirPlaneOutlineIcon),
|
||||
label: PackagesCategoryName.ZHIKU
|
||||
label: PackagesCategoryName.ZHIKU,
|
||||
},
|
||||
[PackagesCategoryEnum.TASKS]: {
|
||||
icon: renderIcon(AirPlaneOutlineIcon),
|
||||
label: PackagesCategoryName.TASKS
|
||||
label: PackagesCategoryName.TASKS,
|
||||
},
|
||||
[PackagesCategoryEnum.EQUIPMENT]: {
|
||||
icon: renderIcon(AirPlaneOutlineIcon),
|
||||
label: PackagesCategoryName.EQUIPMENT
|
||||
label: PackagesCategoryName.EQUIPMENT,
|
||||
},
|
||||
[PackagesCategoryEnum.XUNCHAGUIJI]: {
|
||||
icon: renderIcon(AirPlaneOutlineIcon),
|
||||
label: PackagesCategoryName.XUNCHAGUIJI
|
||||
}
|
||||
label: PackagesCategoryName.XUNCHAGUIJI,
|
||||
},
|
||||
[PackagesCategoryEnum.UAVS]: {
|
||||
icon: renderIcon(AirPlaneOutlineIcon),
|
||||
label: PackagesCategoryName.UAVS,
|
||||
},
|
||||
};
|
||||
|
||||
export const useAsideHook = () => {
|
||||
|
|
|
|||