提交 40b4904b 作者: 翁进城

feat; 无人机应用基本完成

上级 2b196ef0
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
"jspack": "^0.0.4", "jspack": "^0.0.4",
"moment": "^2.30.1", "moment": "^2.30.1",
"mqtt": "^4.3.6", "mqtt": "^4.3.6",
"nanoid": "^5.0.7",
"prismjs": "^1.29.0", "prismjs": "^1.29.0",
"recorder-core": "^1.2.23020100", "recorder-core": "^1.2.23020100",
"terraformer-wkt-parser": "^1.2.1", "terraformer-wkt-parser": "^1.2.1",
......
...@@ -112,7 +112,7 @@ class flightTaskAPI { ...@@ -112,7 +112,7 @@ class flightTaskAPI {
} }
// 新增航线 // 新增航线
static addFlight(data) { static createTask(data) {
return request({ return request({
url: `/tmj/task/createTask`, url: `/tmj/task/createTask`,
method: 'post', method: 'post',
...@@ -120,6 +120,19 @@ class flightTaskAPI { ...@@ -120,6 +120,19 @@ class flightTaskAPI {
}); });
} }
/**
* 新增航线
* @param {*} data
* @returns
*/
static addFlight(data) {
return request({
url: '/dms/route/add',
method: 'post',
data
});
}
// 编辑航线 // 编辑航线
static changeFlight(data) { static changeFlight(data) {
return request({ return request({
......
...@@ -203,6 +203,21 @@ class Control_API { ...@@ -203,6 +203,21 @@ class Control_API {
params, params,
}); });
} }
// 接管无人机
static setUavControlOn(params) {
return request({
url: `/dms/uav/takeOver/${params.id}`,
method: 'get',
params
});
}
// 解除无人机控制
static setUavControlOff(id) {
return request({
url: `/dms/uav/cancelTakeOver/${id}`,
method: 'delete'
});
}
} }
export default Control_API; export default Control_API;
...@@ -92,7 +92,7 @@ export default { ...@@ -92,7 +92,7 @@ export default {
`layer-container`, `layer-container`,
viewerOptions viewerOptions
); );
this.$store.commit('MMCFlightControlCenter/uavApplications/setState', { this.$store.commit('MMCFlightControlCenter/setState', {
key: 'cesiumViewer', key: 'cesiumViewer',
value: this.viewer value: this.viewer
}) })
......
<template>
<div class="cpt-nest-list-item wih100">
<div class="nest-group_box">
<div class="group-title_box">
<div class="title-box">
<span :title="data.name" class="title">{{ data.name }}</span>
</div>
<div class="line-box w210">
(
<span class="cf">{{ data.online + data.offline }}</span>
<span class="healthy--un ml5" style="color: #31db24">{{ data.online }} 架在线</span>
<span>/</span>
<span class="healthy--total" style="color: #cad8d9">{{ data.offline }} 离线</span>)
</div>
</div>
</div>
<div class="nest-children" :class="{ collapse: data.collapse }">
<template v-if="data && data.nestList && data.nestList.length">
<div class="nest-device-list">
<div
v-for="device in data.nestList"
:key="`device_${device.id}`"
class="nest-device-item"
:class="{ online: device.online === 1 }"
>
<!-- 最前面的选项框 -->
<div class="title-box">
<el-tooltip
:content="device.online === 1 ? '在线' : '离线'"
placement="top"
:enterable="false"
>
<el-checkbox
:disabled="device.online !== 1"
:value="device.changestatus"
@change="(e) => handClick(e, device)"
></el-checkbox>
</el-tooltip>
<span :title="device.name" class="title">{{ device.name }}</span>
<span class="li" v-if="device.online != 1">(离线)</span>
<span class="zai" v-else>(在线)</span>
<span
:title="device.comment || '异常'"
v-if="device.state == 2"
style="color: red"
class="status-icon iconfont icon-yichang1"
></span>
<span
:title="device.comment || '维修'"
v-if="device.state == 3"
class="status-icon iconfont icon-weixiu"
></span>
<span
:title="device.comment || '保养'"
v-if="device.state == 4"
class="status-icon iconfont icon-baoyang"
></span>
</div>
<div class="icon-box">
<el-popover
v-if="device.warnList && device.warnList.length > 0"
placement="right"
width="400"
trigger="hover"
>
<div style="display: flex; flex-direction: column">
<div
style="line-height: 20px; color: #fff; padding: 12px"
v-for="(warn, index) in device.warnList"
:key="index"
>{{ warn.content }}</div>
</div>
<span slot="reference" style="margin-right: 12px" class="iconfont icon-jiankang"></span>
</el-popover>
<span @click="itemLocation(device)" class="iconfont fr icon-dingwei1"></span>
<span class="type fr">{{ typeName(device.status) }}</span>
</div>
</div>
</div>
</template>
<div class="nest-child_group_box" v-if="data.child && data.child.length">
<Item v-for="item in data.child" :data="item" :key="`device_child_${item.id}`" />
</div>
</div>
</div>
</template>
<script>
export default {
name: "Item",
props: {
data: {
type: Object,
default: () => ({}),
},
},
data() {
return {
device: {},
};
},
computed: {
curr() {
return this.current();
},
},
methods: {
typeName(val) {
let name = "";
if (val == 6) {
name = "充电中";
} else if (val == 5) {
name = "飞行中";
} else if (val == 2 || val == 3 || val == 4) {
name = "出仓中";
} else if (val == 1) {
name = "回收中";
} else if (val == 0) {
name = "待机中";
}
return name;
},
handClick(e, device) {
this.itemClick(e, device);
},
},
inject: ["itemClick", "itemLocation"],
};
</script>
<style lang="scss" scoped>
.cpt-nest-list-item {
.nest-group_box {
width: 100%;
.group-title_box {
width: 100%;
display: flex;
align-items: center;
justify-content: space-between;
box-sizing: border-box;
height: 40px;
.title-box {
width: calc(100% - 80px);
display: flex;
align-items: center;
white-space: nowrap;
overflow: hidden;
.iconfont {
color: #ccedff;
transform: rotate(90deg);
transition: 0.3s;
cursor: pointer;
&.collapse {
transform: rotate(0deg);
}
}
.title {
font-family: Microsoft YaHei;
font-size: 14px;
color: #ccedff;
font-weight: 400;
margin-left: 5px;
width: 100%;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
}
.line-box {
width: 80px;
flex-shrink: 0;
font-family: Arial, Helvetica, sans-serif;
font-size: 14px;
color: #ccedff;
line-height: 19px;
font-weight: 400;
text-align: right;
margin: 0 44px 0 0;
}
}
}
.nest-children {
overflow: hidden;
&.collapse {
height: 0;
}
.nest-device-list {
.nest-device-item {
height: 30px;
line-height: 30px;
box-sizing: border-box;
padding-left: 20px;
cursor: pointer;
display: flex;
align-items: center;
justify-content: space-between;
.iconfont {
font-size: 22px;
color: #9baaac;
}
&.online {
.title-box {
.iconfont {
// color: #fff;
}
.title {
color: #fff;
}
}
}
.title-box::v-deep {
height: 100%;
white-space: nowrap;
.el-checkbox {
&.is-checked {
.el-checkbox__input {
.el-checkbox__inner {
border-color: #08c2d1;
&::after {
border-color: #08c2d1;
}
}
}
}
.el-checkbox__input {
.el-checkbox__inner {
border-radius: 0;
width: 18px;
height: 18px;
background: #000000;
// border-color: #08c2d1;
border-color: #fff;
box-sizing: border-box;
&::after {
height: 10px;
left: 5px;
top: 1px;
width: 5px;
}
}
}
}
.iconfont {
font-size: 20px;
color: #ccedff;
}
.title {
font-family: MicrosoftYaHei;
font-size: 14px;
color: #9baaac;
font-weight: 400;
margin-left: 8px;
}
.status-icon {
margin-left: 12px;
font-size: 14px;
color: RGBA(251, 192, 1, 1);
}
}
.icon-box {
.icon-jiankang {
font-weight: bold;
color: #d54a15;
&.healthy {
color: #15d589;
}
}
}
}
}
.nest-child_group_box {
box-sizing: border-box;
padding-left: 20px;
}
}
}
.li {
font-size: 16px;
color: #9baaac;
font-weight: 400;
}
.zai {
color: #31db24;
font-weight: 400;
font-size: 16px;
}
.type {
font-weight: 400;
font-size: 10px;
height: 22px;
line-height: 22px;
transform: scale(0.9);
border: 1px solid #c0aaaa;
padding: 0 4px;
border-radius: 4px 4px;
color: #fff;
background-color: #224563;
}
.el-checkbox__inner::v-deep {
background: transparent !important;
}
</style>
<style>
.el-popover .popper__arrow::after {
border-bottom-color: transparent !important;
}
</style>
<!-- 飞控中心机库列表 -->
<template>
<div style="height: 100%">
<div class="uav-list-header">
<div>
<img
class="uav-list-header__icon"
src="./assets/images/uav_list_header.png"
/>
<span class="uav-list-header__text">机库列表</span>
</div>
<div class="uav-list-header__count">
{{ count.sumCount }}架 /
<span class="online">{{ count.onlineCount }}在线</span> /
{{ count.offlineCount }}离线
</div>
</div>
<div class="cpt-observe-nest-list">
<div class="ctx-box pl5">
<div class="list-box pr14">
<template v-if="list && list.length">
<Item v-for="item in list" :key="item.id" :data="item" />
</template>
</div>
</div>
</div>
</div>
<!-- </Dialog> -->
</template>
<script>
import Item from "./components/item";
export default {
props: {
value: {
type: Object,
default: () => ({}),
},
asyncList: {
type: Function,
default: () => () => {},
},
list: {
type: Array,
default: () => [],
},
},
components: { Item },
data() {
return {
name: null,
curr_value: null,
};
},
computed: {
count() {
if (this.list.length == 0) {
return {
onlineCount: 0,
offlineCount: 0,
sumCount: 0,
};
} else {
return {
onlineCount: this.list[0].onLineCount,
offlineCount: this.list[0].offLineCount,
sumCount: this.list[0].onLineCount + this.list[0].offLineCount,
};
}
},
},
watch: {
value: {
handler(value) {
this.curr_value = value;
},
immediate: true,
deep: true,
},
},
mounted() {
this.asyncList();
},
provide() {
},
};
</script>
<style lang="scss" scoped>
.healthy {
box-sizing: border-box;
padding: 0 5px;
display: flex;
align-items: center;
backdrop-filter: blur(3px);
font-size: 16px;
font-weight: bold;
height: 100%;
.healthy--total {
color: #cad8d9;
}
.healthy--un {
color: #d54a15;
}
}
.nestlist {
background: rgba(4, 18, 50, 0.5);
}
.cpt-observe-nest-list {
display: flex;
flex-direction: column;
height: 87vh;
background: rgba(12, 34, 73, 0.7);
.search-box {
flex-shrink: 0;
display: flex;
height: 36px;
padding: 0 10px;
background: #000000;
border: 1px solid #3dcdff;
border-radius: 2px;
box-sizing: border-box;
::v-deep .el-input {
height: 36px;
input {
height: 36px;
background-color: transparent;
border: none;
padding: 0;
font-family: Microsoft YaHei;
font-size: 16px;
color: #08c2d1;
font-weight: 400;
}
.el-input__suffix {
display: flex;
align-items: center;
}
}
.search-icon-box {
display: flex;
align-items: center;
cursor: pointer;
.iconfont {
font-size: 24px;
color: #08ffff;
}
&:hover {
.iconfont {
opacity: 0.8;
}
}
}
}
.ctx-box {
flex: 1;
overflow: auto;
margin-bottom: 30px;
height: 100%;
/* backdrop-filter: blur(3px); */
position: relative;
top: 0px;
}
}
.jianj {
display: flex;
align-items: center;
height: 100%;
}
.jl {
margin: 0 0 0 5px;
color: #70daf9 !important;
font-weight: 700 !important;
}
.uav-list-header {
box-sizing: border-box;
display: flex;
justify-content: space-between;
align-items: center;
// width: 100%;
height: 33px;
background: linear-gradient(
180deg,
#9198ff 0%,
rgba(45, 81, 153, 0.45) 40%,
#05091a 100%
);
box-shadow: inset 0px 0px 10px 2px #3f9dff;
border-radius: 10px 10px 0px 0px;
border: 1px solid #427dff;
.uav-list-header__text {
vertical-align: bottom;
font-size: 20px;
font-family: YouSheBiaoTiHei;
color: #14faff;
line-height: 26px;
text-shadow: 0px 1px 1px rgba(2, 32, 56, 0.2);
background: linear-gradient(
135deg,
#f7b67d 38%,
#f9eacb 58%,
#f5d2a6 79%,
#f59743 100%
);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
.uav-list-header__icon {
width: 26px;
margin-left: 9px;
}
.uav-list-header__count {
color: #fff;
font-weight: 500;
margin-right: 16px;
font-size: 14px;
.online {
font-size: 16px;
font-weight: 900;
color: #31db24;
}
}
}
</style>
<template>
<div>
<List></List>
</div>
</template>
<script>
import List from './components/list';
export default {
name: 'Hangar',
components: {
List
}
}
</script>
<style>
</style>
\ No newline at end of file
...@@ -198,7 +198,7 @@ ...@@ -198,7 +198,7 @@
</template> </template>
<script> <script>
import { mapState } from "vuex"; import { mapState, mapActions } from "vuex";
import { flightTaskAPI, Control_API } from "../../../../../../api"; import { flightTaskAPI, Control_API } from "../../../../../../api";
export default { export default {
...@@ -216,6 +216,9 @@ export default { ...@@ -216,6 +216,9 @@ export default {
]), ]),
}, },
methods: { methods: {
...mapActions("MMCFlightControlCenter/uavApplications", [
"isTakeOver",
]),
// 无人机接管更新状态 // 无人机接管更新状态
async updateTakeOver() { async updateTakeOver() {
await Control_API.updateTakeOver(this.uav.id); await Control_API.updateTakeOver(this.uav.id);
...@@ -224,15 +227,13 @@ export default { ...@@ -224,15 +227,13 @@ export default {
onStartTask() { onStartTask() {
this.bus.$emit('startTask'); this.bus.$emit('startTask');
}, },
fly_control_unlock(key) {
const seed = Date.now();
this.$store.commit("MMCFlightControlCenter/uavApplications/setState", {
key,
value: seed,
});
},
// 一键返航 // 一键返航
onReturnFlight() { async onReturnFlight() {
// 判断是否已接管
if (!(await this.isTakeOver())) {
this.$message.warning("请先接管无人机");
return;
}
this.$confirm("请确认是否进行一键返航操作?", "安全确认", { this.$confirm("请确认是否进行一键返航操作?", "安全确认", {
cancelButtonText: "取消", cancelButtonText: "取消",
confirmButtonText: "确定", confirmButtonText: "确定",
...@@ -252,7 +253,12 @@ export default { ...@@ -252,7 +253,12 @@ export default {
}); });
}, },
// 任务结束 // 任务结束
onTaskEnd() { async onTaskEnd() {
// 判断是否已接管
if (!(await this.isTakeOver())) {
this.$message.warning("请先接管无人机");
return;
}
this.$confirm("请确认是否进行任务结束操作?", "安全确认", { this.$confirm("请确认是否进行任务结束操作?", "安全确认", {
cancelButtonText: "取消", cancelButtonText: "取消",
confirmButtonText: "确定", confirmButtonText: "确定",
...@@ -271,7 +277,12 @@ export default { ...@@ -271,7 +277,12 @@ export default {
/** /**
* 手动模式 * 手动模式
*/ */
onModeManual() { async onModeManual() {
// 判断是否已接管
if (!(await this.isTakeOver())) {
this.$message.warning("请先接管无人机");
return;
}
this.$store.dispatch( this.$store.dispatch(
"MMCFlightControlCenter/uavApplications/modeManual", "MMCFlightControlCenter/uavApplications/modeManual",
{ {
...@@ -284,7 +295,12 @@ export default { ...@@ -284,7 +295,12 @@ export default {
/** /**
* 自动模式 * 自动模式
*/ */
onModeAuto() { async onModeAuto() {
// 判断是否已接管
if (!(await this.isTakeOver())) {
this.$message.warning("请先接管无人机");
return;
}
this.$store.dispatch( this.$store.dispatch(
"MMCFlightControlCenter/uavApplications/modeAuto", "MMCFlightControlCenter/uavApplications/modeAuto",
{ {
...@@ -297,7 +313,12 @@ export default { ...@@ -297,7 +313,12 @@ export default {
/** /**
* 键盘模式 * 键盘模式
*/ */
onModeKeyboard(){ async onModeKeyboard(){
// 判断是否已接管
if (!(await this.isTakeOver())) {
this.$message.warning("请先接管无人机");
return;
}
this.$store.dispatch( this.$store.dispatch(
"MMCFlightControlCenter/uavApplications/modeKeyboard", "MMCFlightControlCenter/uavApplications/modeKeyboard",
{ {
......
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
<div class="tb-hd last-tb-hd">操作</div> <div class="tb-hd last-tb-hd">操作</div>
</div> </div>
<div class="tb-bd-box"> <div class="tb-bd-box">
<div class="tb-tr" v-for="item in airwayList" :key="item.id"> <div class="tb-tr" v-for="item in airwayData.records" :key="item.id">
<div class="td">{{ item.id || "暂无" }}</div> <div class="td">{{ item.id || "暂无" }}</div>
<div class="td"> <div class="td">
<div>{{ item.name || "暂无" }}</div> <div>{{ item.name || "暂无" }}</div>
...@@ -55,11 +55,20 @@ ...@@ -55,11 +55,20 @@
</div> </div>
</div> </div>
</div> </div>
<el-pagination
layout="prev, pager, next"
:total="airwayData.total"
:pageSize="airwayData.size"
:currentPage.sync="airwayData.current"
@current-change="getAirway"
></el-pagination>
</div> </div>
</template> </template>
<script> <script>
import { mapState } from "vuex"; import { mapState } from "vuex";
import { Control_API } from "../../../../../../../../../../api";
let point_index = null; let point_index = null;
let isEditting = false; let isEditting = false;
let airline_entitys = []; let airline_entitys = [];
...@@ -68,12 +77,21 @@ export default { ...@@ -68,12 +77,21 @@ export default {
data() { data() {
return { return {
keyword: null, keyword: null,
airwayData: {
current: 1,
records: [],
searchCount: true,
size: 10,
total: 0,
},
}; };
}, },
computed: { computed: {
...mapState("MMCFlightControlCenter", ["airwayList"]), // ...mapState("MMCFlightControlCenter", ["airwayList"]),
},
mounted() {
this.getAirway();
}, },
mounted() {},
methods: { methods: {
async changeLine(item) { async changeLine(item) {
try { try {
...@@ -91,6 +109,21 @@ export default { ...@@ -91,6 +109,21 @@ export default {
close() { close() {
this.$emit("close"); this.$emit("close");
}, },
async getAirway() {
let res = await Control_API.getUavRouteList({
page: this.airwayData.current,
pageSize: this.airwayData.size,
});
if (res?.code === 200) {
this.airwayData = res.data || {
current: 1,
records: [],
searchCount: true,
size: 10,
total: 0,
};
}
},
}, },
}; };
</script> </script>
...@@ -259,7 +292,6 @@ export default { ...@@ -259,7 +292,6 @@ export default {
// overflow-x: scroll; // overflow-x: scroll;
// overflow-y: hidden; // overflow-y: hidden;
padding: 0 !important; padding: 0 !important;
margin: 0 0 27px 0;
.tb-hd-box { .tb-hd-box {
display: flex; display: flex;
background: #081a3a; background: #081a3a;
...@@ -285,7 +317,6 @@ export default { ...@@ -285,7 +317,6 @@ export default {
.tb-bd-box { .tb-bd-box {
width: 570px; width: 570px;
max-height: 280px; max-height: 280px;
margin-bottom: 24px;
overflow: hidden; overflow: hidden;
overflow-y: auto; overflow-y: auto;
.tb-tr { .tb-tr {
...@@ -584,4 +615,22 @@ export default { ...@@ -584,4 +615,22 @@ export default {
.el-tooltip__popper::v-deep .is-dark { .el-tooltip__popper::v-deep .is-dark {
z-index: -100; z-index: -100;
} }
.el-pagination::v-deep {
text-align: center;
.btn-prev,
.btn-next {
color: #fff;
background-color: transparent;
}
.el-pager {
color: #fff;
li {
background-color: transparent;
}
}
}
</style> </style>
\ No newline at end of file
...@@ -61,9 +61,11 @@ ...@@ -61,9 +61,11 @@
</template> </template>
<script> <script>
import LineList from "./components/lineList"; import LineList from "./components/lineList";
import methods from "./methods"; import { Utils } from "../../../../../../../../lib/cesium";
import { mapState } from "vuex"; import { mapState, mapActions } from "vuex";
import Vue from "vue";
const airwayEntities = []; // 航线实体
let point_entity = null;
export default { export default {
name: "taskList", name: "taskList",
...@@ -90,7 +92,7 @@ export default { ...@@ -90,7 +92,7 @@ export default {
}; };
}, },
computed: { computed: {
...mapState("MMCFlightControlCenter", ["taskList"]), ...mapState("MMCFlightControlCenter", ["taskList", "cesiumViewer"]),
...mapState("MMCFlightControlCenter/uavApplications", ["uav"]), ...mapState("MMCFlightControlCenter/uavApplications", ["uav"]),
taskListAll() { taskListAll() {
return [{ name: "选择航线自动生成任务", id: -1 }, ...this.taskList]; return [{ name: "选择航线自动生成任务", id: -1 }, ...this.taskList];
...@@ -111,11 +113,26 @@ export default { ...@@ -111,11 +113,26 @@ export default {
return find; return find;
}, },
}, },
watch: {}, watch: {
selectedAirway() {
this.clearAirwayEntities();
if (this.selectedAirway.id !== -1) {
try {
this.createAirwayEntities(JSON.parse(this.selectedAirway.content));
} catch (e) {
console.log("绘制航线失败", e);
}
}
},
},
async created() { async created() {
this.bus.$on("startTask", this.onStartTask); this.bus.$on("startTask", this.onStartTask);
}, },
beforeDestroy() {
this.clearAirwayEntities();
},
methods: { methods: {
...mapActions("MMCFlightControlCenter/uavApplications", ["isTakeOver"]),
/** /**
* 更改航线事件 * 更改航线事件
*/ */
...@@ -126,6 +143,13 @@ export default { ...@@ -126,6 +143,13 @@ export default {
* 一键任务事件 * 一键任务事件
*/ */
async onStartTask() { async onStartTask() {
// 判断是否已接管
if (!(await this.isTakeOver())) {
this.$message.warning("请先接管无人机");
return;
}
// 判断是否选择了航线
if (this.selectedAirway.id === -1) { if (this.selectedAirway.id === -1) {
this.$message.warning("请选择航线"); this.$message.warning("请选择航线");
return; return;
...@@ -172,6 +196,139 @@ export default { ...@@ -172,6 +196,139 @@ export default {
id: -1, id: -1,
}; };
}, },
// 两点距离
create_label(before, after) {
const before_wgs84 = Utils.transformCartesian2WGS84(before);
const after_wgs84 = Utils.transformCartesian2WGS84(after);
const center_lng = (before_wgs84.lng + after_wgs84.lng) / 2;
const cetner_lat = (before_wgs84.lat + after_wgs84.lat) / 2;
const alt = (after_wgs84.alt + before_wgs84.alt) / 2;
const position = Utils.transformWGS842Cartesian({
lng: center_lng,
lat: cetner_lat,
alt: alt,
});
const text = `${Cesium.Cartesian3.distance(before, after).toFixed(2)} m`;
let label_entity = this.cesiumViewer.entities.add({
id: `label_${before}`,
position: position,
label: {
text: text,
scale: 0.5,
font: "bold 30px Microsoft YaHei",
fillColor: Cesium.Color.fromCssColorString("#fff"),
horizontalOrigin: Cesium.VerticalOrigin.CENTER,
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
disableDepthTestDistance: Number.POSITIVE_INFINITY,
showBackground: true,
backgroundPadding: new Cesium.Cartesian2(10, 10),
},
});
airwayEntities.push(label_entity);
},
// 清除航线
clearAirwayEntities() {
airwayEntities.forEach((item) => {
this.cesiumViewer.entities.remove(item);
});
},
createAirwayEntities(polyline) {
let pointPositions = [];
const label_arr = [];
polyline.content.forEach((item, index) => {
item.longitude = Number(item.longitude);
item.latitude = Number(item.latitude);
item.alt = Number(item.alt);
pointPositions.push(item.longitude, item.latitude, item.alt);
label_arr.push(
Cesium.Cartesian3.fromDegrees(
item.longitude,
item.latitude,
item.alt
)
);
point_entity = this.cesiumViewer.entities.add({
position: Cesium.Cartesian3.fromDegrees(
item.longitude,
item.latitude,
item.alt
),
name: "show_airline_point",
point: {
pixelSize: 20,
color: Cesium.Color.RED,
color: Cesium.Color.fromCssColorString("#1890FF"),
// fillColor: Cesium.Color.RED,
outlineWidth: 2,
outlineColor: Cesium.Color.fromCssColorString("#FFF"),
// heightReference: Cesium.HeightReference.RELATIVE_TO_GROUND,
},
label: {
// text: String(item.altitude) + 'm',
text: String(index + 1),
scale: 0.5,
font: "bold 24px Microsoft YaHei",
// fillColor: Cesium.Color.BLUE,
fillColor: Cesium.Color.fromCssColorString("#fff"),
horizontalOrigin: Cesium.VerticalOrigin.CENTER,
verticalOrigin: Cesium.VerticalOrigin.CENTER,
disableDepthTestDistance: Number.POSITIVE_INFINITY,
outlineWidth: 0,
// showBackground: true,
// backgroundColor: Cesium.Color.fromCssColorString("#1890FF")
// pixelOffset: new Cesium.Cartesian2(25, -10),
// backgroundPadding: new Cesium.Cartesian2(10, 10)
},
id: JSON.stringify({
...item,
type: "flight_point",
index: index,
}),
});
airwayEntities.push(point_entity);
if (label_arr.length > 1 && !this.isEditting) {
const before = label_arr[label_arr.length - 2];
const after = label_arr[label_arr.length - 1];
this.create_label(before, after);
}
});
pointPositions =
Cesium.Cartesian3.fromDegreesArrayHeights(pointPositions);
const redLine = this.cesiumViewer.entities.add({
name: "Red line on terrain",
polyline: {
positions: new Cesium.CallbackProperty(() => {
return pointPositions;
}, false),
width: 4,
// clampToGround: true,
// zIndex: -99,
material: Cesium.Color.fromCssColorString("#1890FF"),
// material: ({
// // material: Cesium.Color.fromCssColorString('#1890FF'),
// color: Cesium.Color.RED,
// outlineWidth: 2,
// outlineColor: Cesium.Color.fromCssColorString('#FFF')
// })
// // clampToGround: true,
// material: new Cesium.PolylineOutlineMaterialProperty({
// color: Cesium.Color.fromCssColorString('#1890FF'),
// // outlineWidth: 2,
// // outlineColor: Cesium.Color.fromCssColorString('#FFF'),
// }),
},
});
this.cesiumViewer.flyTo(redLine);
airwayEntities.push(redLine);
},
}, },
}; };
</script> </script>
......
<template>
<div>
<div class="police" v-interact>
<div class="police_head">
<div class="police_name">
<div class="police_icon"></div>
<div class="police_font">警灯</div>
</div>
<div class="police_font" @click="$emit('close')">关闭</div>
</div>
<div class="police_ceonter">
<!-- 警灯模式 -->
<div class="police_controls">
<div class="plice_fontTwo">警灯模式:</div>
<div>
<el-radio-group v-model="alarmLampMode" @change="onChangeALMode">
<el-radio :label="1">关闭</el-radio>
<el-radio :label="2">慢闪</el-radio>
<el-radio :label="3">快闪</el-radio>
<el-radio :label="4">交替闪</el-radio>
</el-radio-group>
</div>
</div>
<!-- 尾灯 -->
<div class="police_controls">
<div class="plice_fontTwo">尾灯:</div>
<div>
<el-radio-group v-model="tailLightSwitch" @change="onSwitchTL">
<el-radio :label="1"></el-radio>
<el-radio :label="2"></el-radio>
</el-radio-group>
</div>
</div>
<!-- 降落伞灯 -->
<div class="police_controls">
<div class="plice_fontTwo">降落伞灯:</div>
<div>
<el-radio-group v-model="parachuteLightSwitch" @change="onSwitchPL">
<el-radio :label="1"></el-radio>
<el-radio :label="2"></el-radio>
</el-radio-group>
</div>
</div>
<!-- 隐蔽模式 -->
<div class="police_controls">
<div class="plice_fontTwo">隐蔽模式:</div>
<div>
<el-radio-group v-model="covertSwitch" @change="onSwitchCovert">
<el-radio :label="1"></el-radio>
<el-radio :label="2"></el-radio>
</el-radio-group>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
name: "AlarmLamp",
props: {
uav: {
type: Object,
default: null,
},
},
data() {
return {
alarmLampMode: "", //警灯模式
tailLightSwitch: "", //尾灯开关
parachuteLightSwitch: "", //降落伞灯开头
covertSwitch: "", //隐蔽模式
};
},
methods: {
// 警灯控制
// xing:类型:1警灯,2尾灯,3降落伞灯,4隐蔽
// num:警灯模式下:1关闭,2慢闪,3快闪,4交替闪,其他模式为1打开,2关闭
onChangeALMode(e) {
let num = this.alarmLampMode;
let data = {
data: {
param1: 1,
param2: num,
},
type: 531,
};
let topic = `PX4/OBTAIN/${this.uav.hardId}`;
this.$store.dispatch("MMCMQTT/publish", {
topic,
data,
callback() {
console.log("发送成功");
},
});
},
// 尾灯判定
onSwitchTL() {
let num = this.tailLightSwitch;
let data = {
data: {
param1: 2,
param3: num,
},
type: 531,
};
let topic = `PX4/OBTAIN/${this.uav.hardId}`;
this.$store.dispatch("MMCMQTT/publish", {
topic,
data,
callback() {
console.log("发送成功");
},
});
},
// 降落伞灯
onSwitchPL() {
let num = this.parachuteLightSwitch;
let data = {
data: {
param1: 3,
param3: num,
},
type: 531,
};
let topic = `PX4/OBTAIN/${this.uav.hardId}`;
this.$store.dispatch("MMCMQTT/publish", {
topic,
data,
callback() {
console.log("发送成功");
},
});
},
// 隐蔽模式
onSwitchCovert() {
let num = this.covertSwitch;
let data = {
data: {
param1: 4,
param4: num,
},
type: 531,
};
let topic = `PX4/OBTAIN/${this.uav.hardId}`;
this.$store.dispatch("MMCMQTT/publish", {
topic,
data,
callback() {
console.log("发送成功");
},
});
},
},
};
</script>
<style lang="scss" scoped>
// 警灯弹框
.police {
width: 475px;
height: 200px;
background: rgba(0, 39, 121, 0.5);
border: 1px solid #43deff;
backdrop-filter: blur(2px);
pointer-events: auto;
position: absolute;
left: -490px;
bottom: -89px;
.police_head {
background: linear-gradient(
180deg,
#9198ff 0%,
rgba(45, 81, 153, 0.45) 40%,
#05091a 100%
);
width: 100%;
height: 30px;
border-bottom: 1px solid #70daf9;
display: flex;
justify-content: space-between;
padding: 0 10px 0 10px;
align-items: center;
box-sizing: border-box;
.police_name {
display: flex;
.police_icon {
width: 5px;
height: 15px;
background: #ffbd36;
margin: 0 10px 0 0;
}
}
}
.police_ceonter {
width: 100%;
height: calc(100% - 30px);
padding: 24px;
box-sizing: border-box;
.police_controls::v-deep {
display: flex;
margin: 0 0 15px 0;
.el-radio__label {
color: #fff;
}
}
}
}
.police_font {
font-weight: 700;
color: #2ddcfc;
cursor: pointer;
}
.plice_fontTwo {
width: 90px;
font-size: 18px;
font-weight: 700;
color: #fff;
}
</style>
\ No newline at end of file
...@@ -148,11 +148,10 @@ export default { ...@@ -148,11 +148,10 @@ export default {
...mapState("MMCFlightControlCenter/uavApplications", [ ...mapState("MMCFlightControlCenter/uavApplications", [
"uav", "uav",
"airlineEntity", "airlineEntity",
"cesiumViewer",
"userInfo", "userInfo",
"uavRealTimeData", "uavRealTimeData",
]), ]),
...mapState("MMCFlightControlCenter", ["userInfo"]), ...mapState("MMCFlightControlCenter", ["userInfo", "cesiumViewer"]),
}, },
watch: { watch: {
"uavRealTimeData.rcChannelState"(val) { "uavRealTimeData.rcChannelState"(val) {
...@@ -208,7 +207,12 @@ export default { ...@@ -208,7 +207,12 @@ export default {
/** /**
* 暂停飞行 * 暂停飞行
*/ */
onPauseFly() { async onPauseFly() {
// 判断是否已接管
if (!(await this.isTakeOver())) {
this.$message.warning("请先接管无人机");
return;
}
this.pauseFly({ this.pauseFly({
callback: () => { callback: () => {
this.$message.success("暂停飞行指令已发出"); this.$message.success("暂停飞行指令已发出");
...@@ -218,7 +222,12 @@ export default { ...@@ -218,7 +222,12 @@ export default {
/** /**
* 继续飞行 * 继续飞行
*/ */
onContinueFly() { async onContinueFly() {
// 判断是否已接管
if (!(await this.isTakeOver())) {
this.$message.warning("请先接管无人机");
return;
}
this.continueFly({ this.continueFly({
callback: () => { callback: () => {
this.$message.success("继续飞行指令已发出"); this.$message.success("继续飞行指令已发出");
...@@ -228,7 +237,12 @@ export default { ...@@ -228,7 +237,12 @@ export default {
/** /**
* 紧急迫降 * 紧急迫降
*/ */
onLand() { async onLand() {
// 判断是否已接管
if (!(await this.isTakeOver())) {
this.$message.warning("请先接管无人机");
return;
}
this.safetyNotice = false; this.safetyNotice = false;
this.land(); this.land();
}, },
...@@ -236,11 +250,13 @@ export default { ...@@ -236,11 +250,13 @@ export default {
* 内场控制 * 内场控制
*/ */
async onInfieldControl() { async onInfieldControl() {
// 判断是否已接管
if (!(await this.isTakeOver())) {
this.$message.warning("请先接管无人机");
return;
}
if (this.online === 0) if (this.online === 0)
return this.$message.warning("处于离线状态,不可操作!"); return this.$message.warning("处于离线状态,不可操作!");
if (await this.isTakeOver()) {
return this.$message.warning("请先接管!");
}
// 自动切换摇杆权限 // 自动切换摇杆权限
if (this.uavRealTimeData.rcState == 1) { if (this.uavRealTimeData.rcState == 1) {
this.$message.success("当前处于内场模式,请使用摇杆控制!"); this.$message.success("当前处于内场模式,请使用摇杆控制!");
...@@ -277,16 +293,17 @@ export default { ...@@ -277,16 +293,17 @@ export default {
* 指点飞行 * 指点飞行
*/ */
async guideFlight() { async guideFlight() {
// 判断是否已接管
if (!(await this.isTakeOver())) {
this.$message.warning("请先接管无人机");
return;
}
if (this.uav.online === 0) if (this.uav.online === 0)
return this.$message.warning("处于离线状态,不可操作!"); return this.$message.warning("处于离线状态,不可操作!");
if (!this.guideFlightDone) { if (!this.guideFlightDone) {
return this.$message.warning("指点飞行操作中!"); return this.$message.warning("指点飞行操作中!");
} }
if (await this.isTakeOver()) {
return this.$message.warning("请先接管!");
}
let viewer = this.cesiumViewer; let viewer = this.cesiumViewer;
// 指点飞行 wgs84 // 指点飞行 wgs84
this.guideFlightDone = false; this.guideFlightDone = false;
...@@ -320,7 +337,12 @@ export default { ...@@ -320,7 +337,12 @@ export default {
/** /**
* 指点飞行确定事件 * 指点飞行确定事件
*/ */
onGuideFlightConfirm() { async onGuideFlightConfirm() {
// 判断是否已接管
if (!(await this.isTakeOver())) {
this.$message.warning("请先接管无人机");
return;
}
console.log( console.log(
{ {
data: { data: {
......
...@@ -84,54 +84,6 @@ ...@@ -84,54 +84,6 @@
</div> </div>
<ViewLib v-if="showViewLib"></ViewLib> <ViewLib v-if="showViewLib"></ViewLib>
</div> </div>
<!-- 警灯控制 -->
<div v-if="showAlarmLamp == true">
<div class="police" v-interact>
<div class="police_head">
<div class="police_name">
<div class="police_icon"></div>
<div class="police_font">警灯</div>
</div>
<div class="police_font">关闭</div>
</div>
<div class="police_ceonter">
<!-- 警灯模式 -->
<div class="police_controls">
<div class="plice_fontTwo">警灯模式:</div>
<div>
<el-radio v-model="taillights" label="1" @change="police_kong(1, 1)">关闭</el-radio>
<el-radio v-model="taillights" label="2" @change="police_kong(1, 2)">慢闪</el-radio>
<el-radio v-model="taillights" label="3" @change="police_kong(1, 3)">快闪</el-radio>
<el-radio v-model="taillights" label="4" @change="police_kong(1, 4)">交替闪</el-radio>
</div>
</div>
<!-- 尾灯 -->
<div class="police_controls">
<div class="plice_fontTwo">尾灯:</div>
<div>
<el-radio v-model="weideng" label="1" @change="police_wei(2, 1)"></el-radio>
<el-radio v-model="weideng" label="2" @change="police_wei(2, 2)"></el-radio>
</div>
</div>
<!-- 降落伞灯 -->
<div class="police_controls">
<div class="plice_fontTwo">降落伞灯:</div>
<div>
<el-radio v-model="parachute" label="1" @change="police_jiang(3, 1)"></el-radio>
<el-radio v-model="parachute" label="2" @change="police_jiang(3, 2)"></el-radio>
</div>
</div>
<!-- 隐蔽模式 -->
<div class="police_controls">
<div class="plice_fontTwo">隐蔽模式:</div>
<div>
<el-radio v-model="take" label="1" @change="police_yin(4, 1)"></el-radio>
<el-radio v-model="take" label="2" @change="police_yin(4, 2)"></el-radio>
</div>
</div>
</div>
</div>
</div>
<ControlList <ControlList
@clearId="$emit('clearId')" @clearId="$emit('clearId')"
@closeIconShow="iconShow = false" @closeIconShow="iconShow = false"
...@@ -152,6 +104,7 @@ ...@@ -152,6 +104,7 @@
v-if="uav && uav.hardId" v-if="uav && uav.hardId"
ref="MountControllerRef" ref="MountControllerRef"
/> />
<AlarmLamp v-if="showAlarmLamp" :uav="uav" @close="showAlarmLamp = false" />
</div> </div>
</template> </template>
...@@ -163,7 +116,8 @@ import ControlList from "./components/controlList"; ...@@ -163,7 +116,8 @@ import ControlList from "./components/controlList";
import MountController from "./components/mountController"; import MountController from "./components/mountController";
import Mount from "./components/mount"; import Mount from "./components/mount";
import MMCGimbalP1 from "./components/PagerP1"; import MMCGimbalP1 from "./components/PagerP1";
import ViewLib from './components/viewLib'; import ViewLib from "./components/viewLib";
import AlarmLamp from "./components/alarmLamp";
export default { export default {
name: "ControlRight", name: "ControlRight",
...@@ -173,7 +127,8 @@ export default { ...@@ -173,7 +127,8 @@ export default {
MountController, MountController,
Mount, Mount,
MMCGimbalP1, MMCGimbalP1,
ViewLib ViewLib,
AlarmLamp,
}, },
data() { data() {
return { return {
...@@ -192,22 +147,28 @@ export default { ...@@ -192,22 +147,28 @@ export default {
]), ]),
}, },
methods: { methods: {
hideAll() { hideAll(key) {
this.showAlarmLamp = false; let arr = [
this.showHealth = false; "showAlarmLamp",
this.showMMCGimbalP1 = false; "showHealth",
this.showMount = false; "showMMCGimbalP1",
this.showControlList = false; "showMount",
this.showViewLib = false; "showControlList",
"showViewLib",
];
arr.forEach((key1) => {
if (key !== key1) {
this[key1] = false;
}
});
}, },
/** /**
* 切换展示 * 切换展示
*/ */
onSwitchShow(key) { onSwitchShow(key) {
this.hideAll(); this.hideAll(key);
this[key] = !this[key]; this[key] = !this[key];
}, },
}, },
}; };
</script> </script>
...@@ -217,6 +178,7 @@ export default { ...@@ -217,6 +178,7 @@ export default {
position: absolute; position: absolute;
top: 70px; top: 70px;
right: 30px; right: 30px;
z-index: 1;
.control-list { .control-list {
display: flex; display: flex;
......
<template> <template>
<!-- 清流融合 --> <!-- 清流融合 -->
<div> <div>
<div :class="{ 'full-video': isStatus }" ref="wrap"> <div ref="wrap">
<div :class="infoflag ? 'interact-wrap':'interact_wrap_full'" @dblclick="screen"> <div class="video-wrap" @dblclick="screen">
<div class="cpt_video" :class="big" @click="fn" v-if="flag" ref="video" v-interact> <div class="cpt_video" :class="big" @click="fn" v-if="flag" ref="video" v-interact>
<Obstacle v-if="!isStatus"></Obstacle> <Obstacle v-if="!isStatus"></Obstacle>
<div class="video"> <div class="video">
...@@ -211,7 +211,7 @@ ...@@ -211,7 +211,7 @@
</div> </div>
</div> </div>
<!-- 瞄准 --> <!-- 瞄准 -->
<div class="kedu" :style="backgroundStyle" v-if="ShowCenter"> <div class="kedu" :style="backgroundStyle" v-if="showCenter">
<div class="num"> <div class="num">
<div class="first">{{ num.one }}</div> <div class="first">{{ num.one }}</div>
<div class="first">{{ num.two }}</div> <div class="first">{{ num.two }}</div>
...@@ -382,20 +382,18 @@ ...@@ -382,20 +382,18 @@
</div> </div>
</div> </div>
</el-tooltip> </el-tooltip>
<div class="menu-item" @click="startLinePoint"> <div class="menu-item" @click="startLinePoint" content="航点动作">
<img src="./assets/images/point_small.svg" /> <img src="./assets/images/point_small.svg" />
<!-- <span class="dib f8">航点动作</span> -->
</div> </div>
</div> </div>
</div> </div>
<PointList <PointList
:uavRealTimeData="uavRealTimeData" :uavRealTimeData="uavRealTimeData"
:mountData="mountDatas" :mountData="mountDatas"
v-if="pointListFlag" v-if="showFlywayAction"
@close="$parent.pointListFlag = false" @close="showFlywayAction = false"
></PointList> ></PointList>
</div> </div>
<!-- <PointList :uavRealTimeData="uavRealTimeData" :mountData="mountData" v-if="pointListFlag"></PointList> -->
</div> </div>
<FaceAI v-if="faceAiShow" :uavId="pid" @closeface="faceAiShow = false" /> <FaceAI v-if="faceAiShow" :uavId="pid" @closeface="faceAiShow = false" />
<CarAI v-if="carAiShow" :uavId="device.hardId" :list="carList" @closecar="carAiShow = false" /> <CarAI v-if="carAiShow" :uavId="device.hardId" :list="carList" @closecar="carAiShow = false" />
...@@ -426,9 +424,6 @@ import PointList from "./components/pointList"; ...@@ -426,9 +424,6 @@ import PointList from "./components/pointList";
import videoModelChange from "./components/videoModelChange"; import videoModelChange from "./components/videoModelChange";
import methods from "./methods"; import methods from "./methods";
import fkutils from "./methods/utils"; import fkutils from "./methods/utils";
import Vue from "vue";
const Bus = new Vue();
export default { export default {
name: "Player", name: "Player",
...@@ -444,6 +439,7 @@ export default { ...@@ -444,6 +439,7 @@ export default {
SRSPlayer, SRSPlayer,
videoModelChange, videoModelChange,
}, },
inject: ['bus'],
props: { props: {
scheduleData: { scheduleData: {
type: Object, type: Object,
...@@ -466,14 +462,6 @@ export default { ...@@ -466,14 +462,6 @@ export default {
type: String, type: String,
default: () => "", default: () => "",
}, },
keyFlag: {
type: Boolean,
default: () => false,
},
pointListFlag: {
type: Boolean,
default: () => false,
},
}, },
data() { data() {
return { return {
...@@ -599,7 +587,7 @@ export default { ...@@ -599,7 +587,7 @@ export default {
AISetInterval: null, AISetInterval: null,
aiLable: "", aiLable: "",
aiFlag: false, aiFlag: false,
ShowCenter: false, showFlywayAction: false, //显示航点动作
}; };
}, },
computed: { computed: {
...@@ -676,7 +664,7 @@ export default { ...@@ -676,7 +664,7 @@ export default {
streamOptions() { streamOptions() {
let streamOptions = []; let streamOptions = [];
// this.streamSelect = "hlsUrl"; // this.streamSelect = "hlsUrl";
this.device.streamConfiguration.forEach((item1) => { this.device?.streamConfiguration?.forEach((item1) => {
item1.streamUrlMessage.forEach((item2) => { item1.streamUrlMessage.forEach((item2) => {
let brand = item1.videoSource?.toUpperCase() || ""; let brand = item1.videoSource?.toUpperCase() || "";
if (item2.streamType === "WEBRTC") { if (item2.streamType === "WEBRTC") {
...@@ -729,7 +717,7 @@ export default { ...@@ -729,7 +717,7 @@ export default {
}, },
watch: { watch: {
pointListFlag(val) { /* pointListFlag(val) {
if (val) { if (val) {
let width = this.$refs.video.clientWidth; let width = this.$refs.video.clientWidth;
let height = this.$refs.video.clientHeight; let height = this.$refs.video.clientHeight;
...@@ -746,7 +734,7 @@ export default { ...@@ -746,7 +734,7 @@ export default {
); );
this.big = "big_02"; this.big = "big_02";
} }
}, }, */
// 获取航点 // 获取航点
scheduleData(val) { scheduleData(val) {
console.log("获取航点", val); console.log("获取航点", val);
...@@ -838,7 +826,7 @@ export default { ...@@ -838,7 +826,7 @@ export default {
window.$uavPlayer = this; window.$uavPlayer = this;
// this.wrapCenter(); // this.wrapCenter();
//视屏截图 //视屏截图
Bus.$on("uav_take_photo", ({ callback }) => { this.bus.$on("uav_take_photo", ({ callback }) => {
let blob = this.screenShot(); let blob = this.screenShot();
callback && callback(blob); callback && callback(blob);
}); });
...@@ -867,11 +855,13 @@ export default { ...@@ -867,11 +855,13 @@ export default {
gps = this.uavRealTimeData.gps; gps = this.uavRealTimeData.gps;
} }
} }
if (this.uavRealTimeData && gps && gps.relativeAlt > 20) {
this.showFlywayAction = true;
/* if (this.uavRealTimeData && gps && gps.relativeAlt > 20) {
this.$emit("startLinePoint"); this.$emit("startLinePoint");
} else { } else {
this.$message.warning("当前高度不可创建航点动作!"); this.$message.warning("当前高度不可创建航点动作!");
} } */
}, },
setAll() { setAll() {
let data = { let data = {
...@@ -959,33 +949,6 @@ export default { ...@@ -959,33 +949,6 @@ export default {
}; };
this.$emit("fn", data); this.$emit("fn", data);
}, },
// entryCross(val){
// let data = {
// data: {
// messageID: 1036,
// data: {
// streamInputType: 1,
// "line-crossing-Entry": val.entryAll,
// "line-crossing-Exit": val.crossAll,
// "line-crossing-classId": "0;1;2;3",
// "line-crossing-enable": 1,
// classList: [
// {
// className: "person",
// classID: 0,
// },
// {
// className: "car",
// classID: 1,
// },
// ],
// },
// },
// type: 528,
// };
// console.log(data,"entry");
// this.$emit("fn", data);
// },
setAiMessage() { setAiMessage() {
let data = { let data = {
data: { data: {
...@@ -1087,7 +1050,7 @@ export default { ...@@ -1087,7 +1050,7 @@ export default {
this.$emit("fn", streamData); this.$emit("fn", streamData);
}, },
showCenterFn() { showCenterFn() {
this.ShowCenter = !this.ShowCenter; this.showCenter = !this.showCenter;
}, },
async VideoModelChange() { async VideoModelChange() {
let res = await API.FCKERNEL.checkUseOperate({ let res = await API.FCKERNEL.checkUseOperate({
...@@ -1115,14 +1078,7 @@ export default { ...@@ -1115,14 +1078,7 @@ export default {
} }
}, },
close(data) { close(data) {
this.$store.commit("MMCFlightControlCenter/uavApplications/setState", { this.$emit('close');
key: "showPlayer",
value: false,
});
// 播放器与数据面板同时关闭后,就断开数据无人机的数据连接
if (!this.showPanel) {
this.$store.dispatch("MMCFlightControlCenter/uavApplications/destroy");
}
}, },
screen() { screen() {
if (this.playerCom === "LiveNVRPlayer") { if (this.playerCom === "LiveNVRPlayer") {
...@@ -1401,13 +1357,20 @@ export default { ...@@ -1401,13 +1357,20 @@ export default {
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.video-wrap {
width: 718px;
height: 450px;
position: absolute;
left: 35%;
top: 20%;
}
.noStyle { .noStyle {
opacity: 0.3; opacity: 0.3;
} }
.cpt_video { .cpt_video {
border: 1px solid #fff; border: 1px solid #fff;
width: 718px; width: 100%;
height: 450px; height: 100%;
background: #333; background: #333;
.video { .video {
...@@ -1415,7 +1378,7 @@ export default { ...@@ -1415,7 +1378,7 @@ export default {
position: absolute; position: absolute;
top: 0; top: 0;
left: 0; left: 0;
z-index: 99; z-index: 1;
.name { .name {
position: absolute; position: absolute;
top: 0; top: 0;
...@@ -1864,9 +1827,9 @@ export default { ...@@ -1864,9 +1827,9 @@ export default {
.ai-list ::v-deep { .ai-list ::v-deep {
z-index: 1; z-index: 1;
position: absolute; position: absolute;
left: -114px; left: -124px;
top: 0; top: 0;
width: 111px; width: 120px;
display: flex; display: flex;
flex-wrap: wrap; flex-wrap: wrap;
justify-content: space-between; justify-content: space-between;
......
<template>
<div class="cpt-nest-dialog">
<div class="dialog-ctx" :style="containerStyle" :class="{ collapse,changeHeightStyle }">
<div v-if="showTitle" class="dialog-title">
{{ title }}
<div class="nav__left">
<slot name="nav__left"></slot>
</div>
<div class="nav__right " @click='handleClose'>
<slot name="nav__right"></slot>
</div>
</div>
<div class="dialog-bd">
<slot></slot>
</div>
<img v-if="isCollapse" @click="collapse = !collapse" src="./assets/images/collapse.png"
class="icon-collapse" />
<div class="wih100 h24 pa bottom0 nest-dialog_bottom cp pt5 tc" @click='changeHeight'>
<div class="w24 h24 dib " :class="changeHeightStyle ? 'xbStyle':'' "> <img src="./assets/images/xb.png" alt=""> </div>
</div>
</div>
</div>
</template>
<script>
export default {
props: {
title: {
type: String,
default: () => "",
},
showTitle: {
type: Boolean,
default: () => false,
},
containerStyle: {
type: Object,
default: () => ({}),
},
isCollapse: {
type: Boolean,
default: () => true,
},
isCollapse2: {
type: Boolean,
default: () => false,
}
},
data() {
return {
collapse: false,
changeHeightStyle: false
};
},
methods: {
changeHeight() {
this.changeHeightStyle = !this.changeHeightStyle
},
handleClose() {
this.$emit("close");
},
},
};
</script>
<style lang="scss" scoped>
.cpt-nest-dialog {
position: absolute;
width: 100%;
z-index: 99;
.nest-dialog_bottom {
background: rgba(13, 82, 143, 0.60);
}
.changeHeightStyle {
height: 637px !important;
}
.xbStyle{
transform:rotateX(141deg) ;
}
.dialog-ctx {
position: absolute;
width: 476px;
height: 648px;
background: rgba(9, 32, 87, 0.70);
border: 1px solid #70DAF9;
background-position: center;
background-repeat: no-repeat;
background-size: 100% 100%;
top: 90px;
left: 116px;
box-sizing: border-box;
display: flex;
flex-direction: column;
transform: translateY(0);
transition: 0.3s;
&.collapse {
transform: translateX(-100%);
}
.dialog-title {
width: 100%;
height: 32px;
line-height: 32px;
background-image: linear-gradient(180deg, #9198FF 0%, rgba(45, 81, 153, 0.22) 40%, #05091A 100%);
border: 1px solid #70DAF9;
box-shadow: inset 0 0 10px 2px #3F9DFF;
flex-shrink: 0;
margin: 0 auto;
background-size: 100% 100%;
color: #fff;
text-align: center;
font-family: Microsoft YaHei;
font-weight: bold;
font-size: 16px;
color: #92d9ff;
letter-spacing: 0;
text-align: center;
font-weight: 700;
position: relative;
.nav__right {
position: absolute;
right: 0;
top: 0;
bottom: 0;
}
}
.dialog-bd {
flex: 1;
box-sizing: border-box;
overflow: auto;
}
.icon-close {
position: absolute;
top: 15px;
right: 13px;
font-size: 18px;
color: #2edfff;
cursor: pointer;
&:hover {
opacity: 0.8;
}
}
.icon-collapse {
position: absolute;
right: -24px;
top: 50%;
transform: translateY(-50%);
height: 80px;
z-index: 1;
cursor: pointer;
}
}
}
</style>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<svg width="18px" height="18px" viewBox="0 0 18 18" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>编组 12备份</title>
<g id="页面-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="接管中" transform="translate(-1267.000000, -201.000000)">
<g id="编组-25" transform="translate(641.000000, 172.000000)">
<g transform="translate(0.000000, -60.000000)" id="编组-12备份">
<g transform="translate(626.000000, 89.000000)">
<rect id="矩形" x="0" y="0" width="18" height="18"></rect>
<g id="编组" transform="translate(0.000000, 1.000000)" fill="#00ffff" fill-rule="nonzero">
<path d="M17.850016,13.5103629 C17.5788626,12.8481305 16.9357273,12.4165056 16.2228035,12.4182979 C15.7931026,12.4195874 15.3790797,12.5805555 15.0605089,12.8701869 L13.163344,11.763059 L13.163344,7.47764569 L9.47399584,5.33870477 L9.47399584,3.50102313 C10.3177515,3.28747031 10.8817508,2.48954009 10.8042077,1.61907713 C10.7266645,0.748614175 10.0305891,0.0639190733 9.16248966,0.00420007209 C8.29439023,-0.0555189291 7.51186606,0.527459147 7.31687937,1.37917401 C7.12189267,2.23088887 7.57230367,3.09860323 8.37918928,3.42570831 L8.37918928,5.33117328 L4.71233711,7.47764569 L4.71233711,11.6500868 L2.98764183,12.6818998 C2.40679718,12.1116776 1.51039599,12.0210201 0.82802338,12.4634868 C0.113289308,12.9100641 -0.1850107,13.8034942 0.117159798,14.5925747 C0.419330296,15.3816552 1.23683126,15.8440536 2.06530479,15.6944927 C2.89243426,15.5317097 3.48747791,14.8012523 3.48255439,13.9547203 C3.48992794,13.8670091 3.48992794,13.7788297 3.48255439,13.6911184 L5.21474835,12.6894313 L8.96408594,14.8810926 L12.6234394,12.7496832 L14.5206042,13.8492795 C14.4924107,13.9703061 14.4773257,14.094039 14.4756122,14.2183222 C14.4708638,14.9381924 14.9007044,15.5892294 15.5627925,15.8649668 C16.2248806,16.1407041 16.9872866,15.9861975 17.4911185,15.4741788 C17.9949504,14.96216 18.1398132,14.1946555 17.8575147,13.5329573 L17.850016,13.5103629 Z M11.5136355,7.81656238 L8.94908859,9.32285881 L6.36204565,7.81656238 L8.92659257,6.31026596 L11.5136355,7.81656238 Z M12.0460414,8.77306061 L12.0460414,11.7856535 L9.47399584,13.2919499 L9.47399584,10.279357 L12.0460414,8.77306061 Z" id="形状"></path>
</g>
</g>
</g>
</g>
</g>
</g>
</svg>
\ No newline at end of file
...@@ -8,7 +8,11 @@ ...@@ -8,7 +8,11 @@
<img class="level-icon" src="./assets/images/uav_item2.svg" v-if="level === 2" /> <img class="level-icon" src="./assets/images/uav_item2.svg" v-if="level === 2" />
<img class="level-icon" src="./assets/images/uav_item3.svg" v-if="level === 3" /> <img class="level-icon" src="./assets/images/uav_item3.svg" v-if="level === 3" />
<div class="org-name" :title="data.name">{{ data.name }}</div> <div class="org-name" :title="data.name">{{ data.name }}</div>
<i class="refresh-icon el-icon-refresh-right" v-if="level === 1" @click.stop="$emit('refresh')" /> <i
class="refresh-icon el-icon-refresh-right"
v-if="level === 1"
@click.stop="$emit('refresh')"
/>
</div> </div>
<div class="online-info"> <div class="online-info">
(共 {{data.online + data.offline}} (共 {{data.online + data.offline}}
...@@ -21,19 +25,22 @@ ...@@ -21,19 +25,22 @@
</div> </div>
</div> </div>
<div class="uav-item-child-box" :class="{ collapse: data.collapse }"> <div class="uav-item-child-box" :class="{ collapse: data.collapse }">
<Item v-for="child in data.childs" :key="child.id" :data="child" :level="level+1" /> <Item v-for="child in data.childs" :key="child.id" :data="child" :level="level+1" @refresh="$emit('refresh')" />
<div <div
class="device-item-box" class="device-item-box"
:class="{ online: device.online == 1 }" :class="{ online: device.online == 1 }"
v-for="device in data.uavs" v-for="device in data.uavs"
:key="`device_${device.id}`" :key="`device_${device.id}`"
> >
<div class="device-name">
<div class="device-name" > <span
<span style="margin-right:10px" :class="device.online==1&&device.currentOperator==1? 'blue' : device.online==1&&device.currentOperator!=1 ?'yellow':'' " :title="device.name">{{device.name}}</span> style="margin-right:10px"
<span style="color:#31DB24 " class="dib" v-if=" device.online == 1 ">(在线)</span> :class="device.online==1&&device.currentOperator==1? 'blue' : device.online==1&&device.currentOperator!=1 ?'yellow':'' "
<span v-else class="dib">(离线)</span> :title="device.name"
<div class="symbol-icon-box"> >{{device.name}}</span>
<span style="color:#31DB24 " class="dib" v-if=" device.online == 1 ">(在线)</span>
<span v-else class="dib">(离线)</span>
<div class="symbol-icon-box">
<template v-if="device.modelName && device.modelName.includes('入云龙1')"> <template v-if="device.modelName && device.modelName.includes('入云龙1')">
<div class="uav_version status-icon cp"> <div class="uav_version status-icon cp">
<img src="./assets/images/I.svg" /> <img src="./assets/images/I.svg" />
...@@ -41,21 +48,21 @@ ...@@ -41,21 +48,21 @@
</template> </template>
<template v-if="device.modelName && device.modelName.includes('入云龙2')"> <template v-if="device.modelName && device.modelName.includes('入云龙2')">
<div class="uav_version status-icon cp"> <div class="uav_version status-icon cp">
<img src="./assets/images/I.svg"/> <img src="./assets/images/I.svg" />
<img src="./assets/images/I.svg"/> <img src="./assets/images/I.svg" />
</div> </div>
</template> </template>
<template v-if="device.modelName && device.modelName.includes('插翅虎')"> <template v-if="device.modelName && device.modelName.includes('插翅虎')">
<div class="uav_version status-icon cp"> <div class="uav_version status-icon cp">
<img src="./assets/images/cq.svg"/> <img src="./assets/images/cq.svg" />
</div> </div>
</template> </template>
</div> </div>
</div> </div>
<div class="device-fns"> <div class="device-fns">
<div <div
class="iconfont icon-luxiang_xianxing" class="iconfont icon-luxiang_xianxing"
:class="{ active: device.showPlayer }" :class="{ active: uav && device.id === uav.id && uav.showPlayer }"
title="视频" title="视频"
@click="showPlayer(device)" @click="showPlayer(device)"
></div> ></div>
...@@ -63,14 +70,16 @@ ...@@ -63,14 +70,16 @@
<div <div
v-if="device.online" v-if="device.online"
class="iconfont icon-kongzhi_xianxing" class="iconfont icon-kongzhi_xianxing"
:class="{ active: device.showPanel }" :class="{ active: uav && device.id === uav.id && uav.showPanel }"
title="控制面板" title="控制面板"
@click="showPanel(device)" @click="showPanel(device)"
></div> ></div>
<div <div
class="jieg" class="jieg"
:class="{ active: device.currentOperator === userInfo.id }"
title="接管无人机 " title="接管无人机 "
v-if="device.online" v-if="device.online"
@click="onTakeOver(device)"
></div> ></div>
</div> </div>
</div> </div>
...@@ -80,30 +89,91 @@ ...@@ -80,30 +89,91 @@
</template> </template>
<script> <script>
import { mapActions } from 'vuex' import { mapActions, mapState } from "vuex";
import { Control_API } from "../../../../../../../../api";
export default { export default {
name: "Item", name: "Item",
data() { data() {
return { return {};
}
}, },
props: { props: {
data: { data: {
type: Object, type: Object,
default: () => ({}) default: () => ({}),
}, },
level: { level: {
type: Number, type: Number,
default: -1 default: -1,
} },
}, },
computed: { computed: {
...mapState("MMCFlightControlCenter/uavApplications", ["uav"]),
...mapState("MMCFlightControlCenter", ["userInfo"]),
}, },
methods: { methods: {
...mapActions('MMCFlightControlCenter/uavApplications', ['showPlayer', 'showPanel']) ...mapActions("MMCFlightControlCenter/uavApplications", [
} "showPlayer",
"showPanel",
]),
/**
* 接管无人机
*/
async onTakeOver(uav) {
if (!uav.currentOperator) {
let res = await Control_API.setUavControlOn({
force: false,
id: uav.id,
uid: this.userInfo.id,
});
if (res.code === 200) {
this.$message.success(`请开始操作${uav.name}`);
this.$emit('refresh');
}
} else if (
// 判断当前接管人是不是自已, 是则提示退出接管, 不是则提示是否强制接管
uav.currentOperator === this.userInfo.id
) {
try {
await this.$confirm(`请确认是否退出接管${uav.name}?`, "安全确认", {
cancelButtonText: "取消",
confirmButtonText: "确定",
customClass: "uav_controlPane",
showClose: false,
});
let res = await Control_API.setUavControlOff(uav.id);
if (res.code === 200) {
this.$message.success(`已退出接管${uav.name}`);
this.$emit('refresh');
}
} catch (e) {
}
} else {
try {
await this.$confirm(
`${uav.name}已被接管, 请确认是否强制接管?`,
"安全确认",
{
cancelButtonText: "取消",
confirmButtonText: "确定",
customClass: "uav_controlPane",
showClose: false,
}
);
let res = await Control_API.setUavControlOn({
force: false,
id: uav.id,
uid: this.userInfo.id,
});
if (res.code === 200) {
this.$message.success(`请开始操作${uav.name}`);
this.$emit('refresh');
}
} catch (e) {
}
}
},
},
}; };
</script> </script>
...@@ -220,6 +290,9 @@ export default { ...@@ -220,6 +290,9 @@ export default {
height: 20px; height: 20px;
background: url("./assets/images/jieguan.svg") no-repeat; background: url("./assets/images/jieguan.svg") no-repeat;
background-size: 100% 100%; background-size: 100% 100%;
&.active {
background: url("./assets/images/jieguan_active.svg") no-repeat;
}
} }
.iconfont { .iconfont {
font-size: 24px; font-size: 24px;
...@@ -234,42 +307,41 @@ export default { ...@@ -234,42 +307,41 @@ export default {
} }
} }
} }
.goodsName_two{ .goodsName_two {
background-image: url("./assets/images/goodsName_two.svg"); background-image: url("./assets/images/goodsName_two.svg");
background-size: 100% 100%; background-size: 100% 100%;
} }
.goodsName_one{ .goodsName_one {
background-image: url("./assets/images/goodsName_one.svg"); background-image: url("./assets/images/goodsName_one.svg");
background-size: 100% 100%; background-size: 100% 100%;
} }
} }
.green{ .green {
color:#31DB24 color: #31db24;
} }
.red{ .red {
color:red color: red;
} }
.item_items{ .item_items {
align-items: center; align-items: center;
} }
.level-icon{ .level-icon {
width: 16px; width: 16px;
margin-right: 6px; margin-right: 6px;
} }
.refresh-icon{ .refresh-icon {
width: 16px; width: 16px;
margin-left: 34px; margin-left: 34px;
} }
.jcsb{ .jcsb {
justify-content: left; justify-content: left;
} }
.status-icon{ .status-icon {
margin-left: 12px; margin-left: 12px;
font-size: 14px; font-size: 14px;
color: RGBA(251, 192, 1, 1); color: RGBA(251, 192, 1, 1);
} }
.uav_version{ .uav_version {
margin-top: 1px; margin-top: 1px;
width: 14px; width: 14px;
height: 12px; height: 12px;
...@@ -279,7 +351,7 @@ export default { ...@@ -279,7 +351,7 @@ export default {
justify-content: center; justify-content: center;
align-items: center; align-items: center;
} }
.symbol-icon-box{ .symbol-icon-box {
display: flex; display: flex;
align-items: center; align-items: center;
......
<template>
<div class="uavSearch">
<el-input
:placeholder="placeholder"
:suffix-icon="icon"
v-model="input"
@input="searchFn"
clearable
>
</el-input>
</div>
</template>
<script>
export default {
data() {
return {
input: "",
};
},
props: {
placeholder: {
type: String,
default: "请输入内容",
},
icon: {
type: String,
default: "el-icon-search",
},
},
methods: {
searchFn() {
this.$emit("searchFn", this.input);
},
},
};
</script>
<style lang="scss" >
.uavSearch {
padding: 0 10px;
.el-input--suffix {
color: #6e9fbf;
.el-input__inner {
border: 1px solid #00b6ff;
box-shadow: 0 2px 4px 0 rgba(28, 94, 124, 0.5), inset 0 0 3px 0 #00b6ff;
background: transparent;
color: #6e9fbf;
border-radius: 6px;
height: 40px;
}
.el-icon-search:before {
color: #00f8f9;
}
}
}
</style>
\ No newline at end of file
...@@ -14,20 +14,12 @@ ...@@ -14,20 +14,12 @@
</div> </div>
</template> </template>
</div> </div>
<!-- </Dialog> -->
</template> </template>
<script> <script>
import Dialog from "./components/dialog";
import Item from "./components/item"; import Item from "./components/item";
export default { export default {
data() { components: { Item },
return {
components_start: true, //组件当前的状态
wsList: [],
num: 0,
};
},
props: { props: {
containerStyle: { containerStyle: {
type: String | Object, type: String | Object,
...@@ -38,7 +30,13 @@ export default { ...@@ -38,7 +30,13 @@ export default {
default: () => [], default: () => [],
}, },
}, },
components: { Dialog, Item }, data() {
return {
components_start: true, //组件当前的状态
wsList: [],
num: 0,
};
},
watch: { watch: {
list: { list: {
handler(val) { handler(val) {
...@@ -46,15 +44,10 @@ export default { ...@@ -46,15 +44,10 @@ export default {
}, },
}, },
}, },
methods: {},
mounted() { mounted() {
this.wsList = this.list; this.wsList = this.list;
}, },
provide() { methods: {
return {
fn: (...args) => this.$emit("fn", ...args),
};
}, },
}; };
</script> </script>
......
...@@ -41,7 +41,7 @@ ...@@ -41,7 +41,7 @@
height: '275px', height: '275px',
}" }"
:list="uavList" :list="uavList"
@refresh="onUavSearch" @refresh="initList"
/> />
<div></div> <div></div>
</div> </div>
...@@ -60,6 +60,7 @@ export default { ...@@ -60,6 +60,7 @@ export default {
return { return {
uavList: [], // 无人机列表 uavList: [], // 无人机列表
uavSearchContent: "", // 无人机搜索内容 uavSearchContent: "", // 无人机搜索内容
timeHandle: null, // 定时刷新句柄
}; };
}, },
computed: { computed: {
...@@ -77,8 +78,13 @@ export default { ...@@ -77,8 +78,13 @@ export default {
} }
}, },
mounted() { mounted() {
// this.uavList = data.data;
this.initList(); this.initList();
this.timeHandle = setInterval(() => {
this.initList();
}, 10000);
},
beforeDestroy(){
clearInterval(this.timeHandle);
}, },
methods: { methods: {
async initList() { async initList() {
......
...@@ -4,21 +4,15 @@ ...@@ -4,21 +4,15 @@
<Player <Player
class="player" class="player"
ref="player" ref="player"
v-if="showPlayer" v-if="showPlayer && uav"
:pointListFlag="pointListFlag" :pointListFlag="pointListFlag"
@getAiPopup="getAiPopup"
@imgUrl="getimgUrl" @imgUrl="getimgUrl"
@startLinePoint="startLinePoint" @startLinePoint="startLinePoint"
:scheduleData="scheduleData" :scheduleData="scheduleData"
:keyFlag="keyFlag"
:NXdata="NXdata" :NXdata="NXdata"
@changeLableName="(e) => (lineLableName = e)"
:lineLableName="lineLableName" :lineLableName="lineLableName"
:device="uav" :device="uav"
@AIDialog="(e, val) => getAIDialog(e, val)" @close="onPlayerClose"
@continue="continueReset"
:videoItem="videoItem"
:showCenter="showCenter"
/> />
<ControlPanel v-if="showPanel"></ControlPanel> <ControlPanel v-if="showPanel"></ControlPanel>
</div> </div>
...@@ -88,14 +82,6 @@ export default { ...@@ -88,14 +82,6 @@ export default {
mounted() {}, mounted() {},
beforeDestroy() {}, beforeDestroy() {},
methods: { methods: {
// 结束任务确认框,确定结束任务
async queding() {
this.$refs.ControlMenu.queding();
this.endRenwu = false;
},
getAiPopup(val) {
this.aiPopup = val;
},
startLinePoint() { startLinePoint() {
this.pointListFlag = !this.pointListFlag; this.pointListFlag = !this.pointListFlag;
if (this.pointListFlag) { if (this.pointListFlag) {
...@@ -105,32 +91,6 @@ export default { ...@@ -105,32 +91,6 @@ export default {
}, 1000); }, 1000);
} }
}, },
continueReset() {
setTimeout(() => {
this.resetSwim();
}, 3000);
},
getAIDialog(e, val) {
this.AIFlag = e;
this.aiTitle = val;
setTimeout(() => {
this.resetSwim();
}, 3000);
// this.$refs.P3.$refs.ItemA.text="盐城公安提醒您不私自下水游泳不擅自与他人结伴游泳不在无成年人带领的情况下游泳不到无安全设施无救援人员的水域游泳不到不熟悉的水域游泳不擅自下水施救"
// this.$refs.P3.$refs.ItemA.handleSendTTSText()
},
//检测
resetSwim() {
let data = {
data: "AUTO_MISSION",
type: 513,
};
this.uav_mqtt_fn(data);
this.AIFlag = false;
setTimeout(() => {
this.$refs["player"][0].setAll();
}, 1000);
},
getcanvas(val, item) { getcanvas(val, item) {
let data = null; let data = null;
if (item.jsonData) { if (item.jsonData) {
...@@ -390,33 +350,6 @@ export default { ...@@ -390,33 +350,6 @@ export default {
}); });
} }
}, },
closeVideo() {
this.$message.warning("无人机已离线!");
this.healthData = {};
this.uav.control.mounts = [];
// this.VideoTomapFlag = false
// this.uav_hide_control(this.uavId)
this.$emit("healthWaringShow", [], false);
this.uav_hide_video(this.uavId);
// this.controlMenuFlag = false
// this.ControlFlag = false
// this.uav_list()
},
getModeStatus(val) {
// console.log(val,"ModeStatus");
this.ModeStatus = val;
},
async addMessage() {
let res = await API.FCKERNEL.exceptionAdd(this.message);
},
showLine(val) {
this.showCenter = val;
},
auto() {
//定点-->航线
//摇杆手动-->自动
this.$refs.ControlMenu.changeAuto();
},
async getimgUrl(val, aiType, item) { async getimgUrl(val, aiType, item) {
this.aiType = aiType; this.aiType = aiType;
this.imgshow = true; this.imgshow = true;
...@@ -471,135 +404,20 @@ export default { ...@@ -471,135 +404,20 @@ export default {
} }
} }
}, },
async qzjg() { onPlayerClose(){
let res = await API.DEVICE.forceTakeOver({ this.$store.dispatch("MMCFlightControlCenter/uavApplications/showPlayer", this.uav);
deviceHardId: this.uav.NoticeData.deviceHardId, }
});
if (res.code == 200) {
this.$message.success(res.msg);
this.uav.NoticeFlag = false;
}
},
fly_take_off() {
// 等待航线上传成功在执行
this.$refs.TaskListRef.upload_complete();
// Bus.$emit("take_off");
},
getYd() {
this.controlMenuFlag = !this.controlMenuFlag;
if (this.collapseFlag == true) {
// 修改飞控 无人机 左边'任务库'的位置
Bus.$emit("ydh", false);
} else {
Bus.$emit("ydh", true);
}
},
collapseFlagfn() {
this.collapseFlag = !this.collapseFlag;
if (this.collapseFlag == true) {
// 修改飞控 无人机 左边'任务库'的位置
Bus.$emit("ydh", false);
} else {
Bus.$emit("ydh", true);
}
},
Lsdom(item) {
this.$emit("Lsdom", item);
},
clearIdFn() {
if (this.$refs["player"][0]) {
this.$refs["player"][0].clearInter();
}
if (this.$refs.TaskListRef) {
this.$refs.TaskListRef.close();
try {
let deviceHardId = this.uav.control.device.deviceHardId;
// this.uav_hide_airway(this.uav.control.device);
this.uav.online[deviceHardId].positions = [
this.uav.online[deviceHardId].position,
];
} catch (error) {}
}
},
videoItemFn(index) {
this.videoItem = index;
this.$store.commit("mapmanage/SET_MAP_IS_VIDEOITEM", index);
},
LoggerFn() {
this.loggerFlag = !this.loggerFlag;
// this.collapseFlag = false;
},
videoChange() {
this.videoFlag = !this.videoFlag;
},
showTakeOver() {
this.uav.TakeOverFlag = !this.uav.TakeOverFlag;
if (this.uav.TakeOverFlag) {
this.collapseFlag = true;
}
},
// 关闭航线创建列表
AirwayQuit() {
this.isAirwayEdit = false;
// 运行监测关闭
this.powerFlag = true;
this.Videoflag = true;
this.ControlFlag = true;
this.collapseFlag = false;
},
taskTypeFn(item) {
this.taskType = item;
},
// 创建航线
CraeteRoute() {
this.isAirwayEdit = true;
// // 运行监测关闭
this.powerFlag = false;
this.ControlFlag = false;
this.collapseFlag = true;
},
createTaskClick() {
this.CreateTaskFlag = !this.CreateTaskFlag;
this.controlMenuFlag = false;
},
async checkUseOperateFn(device) {
// 查看是否有控制权限
let res = await API.FCKERNEL.checkUseOperate({ deviceHardId: device });
if (res.code == 201) {
this.$message.warning(res.msg);
return false;
} else {
return true;
}
},
/**
* 无人机搜索
*/
onUavSearch() {
this.uav_list(
{
search: this.uavSearchContent,
},
false
);
},
//点击任务按钮
onChangeTask(open) {
if (open === undefined) {
this.controlMenuFlag = !this.controlMenuFlag;
} else {
this.controlMenuFlag = open;
}
},
}, },
}; };
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.player { .player {
position: absolute; /* position: absolute;
left: 50%; left: 50%;
top: 50%; top: 50%;
transform: translate(-50%, -50%); transform: translate(-50%, -50%);
width: 0;
height: 0; */
} }
</style> </style>
...@@ -5,15 +5,18 @@ ...@@ -5,15 +5,18 @@
<!-- 地图切换组件 --> <!-- 地图切换组件 -->
<mapImageSwitch></mapImageSwitch> <mapImageSwitch></mapImageSwitch>
<!-- 无人机应用 --> <!-- 无人机应用 -->
<uavApplications></uavApplications> <uavApplications v-if="scene === 0"></uavApplications>
<!-- 机库 -->
<hangar v-else></hangar>
</div> </div>
</template> </template>
<script> <script>
import cesiumLayout from "./components/cesium-layer"; import cesiumLayout from "./components/cesiumLayer";
import mapImageSwitch from "./components/mapImageSwitch"; import mapImageSwitch from "./components/mapImageSwitch";
import uavApplications from "./components/uavApplications"; import uavApplications from "./components/uavApplications";
import Vue from 'vue'; import hangar from "./components/hangar";
import Vue from "vue";
export default { export default {
name: "MMCFlightControlCenter", name: "MMCFlightControlCenter",
...@@ -21,6 +24,7 @@ export default { ...@@ -21,6 +24,7 @@ export default {
cesiumLayout, cesiumLayout,
mapImageSwitch, mapImageSwitch,
uavApplications, uavApplications,
hangar,
}, },
props: { props: {
devMode: { devMode: {
...@@ -66,11 +70,16 @@ export default { ...@@ -66,11 +70,16 @@ export default {
]; ];
}, },
}, },
// 场景 0: 无人机 1: 机库
scene: {
type: Number,
default: 0,
},
}, },
provide() { provide() {
return { return {
rootNode: this, //根节点实例 rootNode: this, //根节点实例
bus: new Vue() //bus总线 bus: new Vue(), //bus总线
}; };
}, },
watch: { watch: {
...@@ -83,29 +92,17 @@ export default { ...@@ -83,29 +92,17 @@ export default {
}); });
}, },
}, },
airwayList: {
immediate: true,
handler(newVal) {
this.$store.commit("MMCFlightControlCenter/setState", {
key: "airwayList",
value: newVal,
});
},
},
}, },
beforeCreate() { beforeCreate() {
if (!window.$mmc) { if (!window.$mmc) {
window.$mmc = {}; window.$mmc = {};
} }
window.$mmc.store = this.$store; window.$mmc.store = this.$store;
},
created() {
if (!window.$mmc) {
window.$mmc = {};
}
window.$mmc.state = () => { window.$mmc.state = () => {
return this.$store.state; return this.$store.state;
}; };
},
created() {
this.$store.commit("MMCFlightControlCenter/setState", { this.$store.commit("MMCFlightControlCenter/setState", {
key: "devMode", key: "devMode",
value: this.devMode, value: this.devMode,
...@@ -119,6 +116,9 @@ export default { ...@@ -119,6 +116,9 @@ export default {
value: this.userInfo, value: this.userInfo,
}); });
}, },
methods: {
},
}; };
</script> </script>
...@@ -311,6 +311,25 @@ export default { ...@@ -311,6 +311,25 @@ export default {
} }
} }
} }
.el-input-number {
.el-input-number__decrease,
.el-input-number__increase {
bottom: 1px;
background: #606266;
color: #f5f7fa;
border-radius: 0;
border: none;
}
.el-input-number__decrease {
left: 1px;
}
.el-input-number__increase {
right: -1px;
}
}
} }
.mmc { .mmc {
......
...@@ -6,6 +6,7 @@ export default { ...@@ -6,6 +6,7 @@ export default {
devMode: false, //开发模式, 使用开发环境接口 devMode: false, //开发模式, 使用开发环境接口
token: "", //登录token token: "", //登录token
userInfo: null, //用户信息 userInfo: null, //用户信息
cesiumViewer: null, // cesium的viewer实例
cesiumImagesLayers: { cesiumImagesLayers: {
//cesium的地图图层 //cesium的地图图层
street: { street: {
...@@ -41,19 +42,6 @@ export default { ...@@ -41,19 +42,6 @@ export default {
}, },
}, */ }, */
], ],
// 航线列表
airwayList: [
/* {
name: "航线名称1",
id: 1,
organizationName: "所属单位1",
status: 1, //空域状态 1: 可用 2: 待申请 3: 待审批 4: 通过 5: 驳回
isSafe: 1, //空域状态 1: 安全 2: 待确定
labelName: "航线标签1",
content:
'{"filename":"肇庆航线20240318","line":{"baseSpeed":3},"content":[{"uuid":"1nmI-Fo18IagbcVJsia7Q","latitude":23.178153411812204,"longitude":112.57807281336807,"alt":100,"yawAngle":0,"pitchAngle":0,"speed":3,"actions":[]},{"uuid":"9pTbBPlF8iIwbUNqusyHK","latitude":23.17783116525969,"longitude":112.57797543441967,"alt":100,"yawAngle":0,"pitchAngle":0,"speed":3,"actions":[]},{"uuid":"s91IhN22wuaeyG-UQs0XR","latitude":23.17786413506686,"longitude":112.57824336604547,"alt":100,"yawAngle":0,"pitchAngle":0,"speed":3,"actions":[]},{"uuid":"xS_JIl3wxQrhMPdpcjcSn","latitude":23.17820934975604,"longitude":112.5781357731637,"alt":100,"yawAngle":0,"pitchAngle":0,"speed":3,"actions":[]}],"baseSpeed":3,"gimbalYaw":0,"gimbalPitch":0,"alt":100}',
}, */
],
}, },
mutations: { mutations: {
/** /**
......
<template> <template>
<div> <div>
<el-form> <el-form>
<el-switch v-model="devMode" active-text="测试环境" inactive-text="正式环境" @change="onSwitch"></el-switch> <el-form-item label="环境">
<el-switch v-model="devMode" active-text="测试环境" inactive-text="正式环境" @change="onSwitch"></el-switch>
</el-form-item>
<el-form-item label="场景">
<el-switch v-model="scene" active-text="无人机" inactive-text="机库"></el-switch>
</el-form-item>
<el-form-item label="账号"> <el-form-item label="账号">
<el-input v-model="account"></el-input> <el-input v-model="account"></el-input>
</el-form-item> </el-form-item>
...@@ -23,6 +29,7 @@ ...@@ -23,6 +29,7 @@
:taskList="taskList" :taskList="taskList"
:airwayList="airwayList" :airwayList="airwayList"
@startTask="onStartTask" @startTask="onStartTask"
:scene="scene ? 0 : 1"
></MMCFlightControlCenter> ></MMCFlightControlCenter>
</div> </div>
</div> </div>
...@@ -36,7 +43,8 @@ export default { ...@@ -36,7 +43,8 @@ export default {
data() { data() {
return { return {
baseUrl: "https://test.tmj.mmcuav.cn", baseUrl: "https://test.tmj.mmcuav.cn",
devMode: false, devMode: true,
scene: false, // 场景类型 true: 无人机 false: 机库
account: "mmctest@admin", account: "mmctest@admin",
password: "test@Admin001", password: "test@Admin001",
userInfo: null, userInfo: null,
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论