提交 78a7e4a6 作者: 翁进城

fix: 1.修正仪表电池样式

2. 机库单独mqtt地址配置
3. 机库航线库样式
4. 机库一键任务
5. 机库视频增加刷新
上级 c0b7ad08
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -37,10 +37,12 @@ ...@@ -37,10 +37,12 @@
"@liveqing/liveplayer": "^2.7.10", "@liveqing/liveplayer": "^2.7.10",
"axios": "^1.3.4", "axios": "^1.3.4",
"dayjs": "^1.11.7", "dayjs": "^1.11.7",
"downloadjs": "^1.4.7",
"echarts": "^4.9.0", "echarts": "^4.9.0",
"element-ui": "^2.15.6", "element-ui": "^2.15.6",
"file-saver": "^2.0.5", "file-saver": "^2.0.5",
"global": "^4.4.0", "global": "^4.4.0",
"html2canvas": "^1.4.1",
"interactjs": "^1.10.17", "interactjs": "^1.10.17",
"jquery": "^3.7.1", "jquery": "^3.7.1",
"jspack": "^0.0.4", "jspack": "^0.0.4",
......
...@@ -106,14 +106,13 @@ export default { ...@@ -106,14 +106,13 @@ export default {
box-sizing: border-box; box-sizing: border-box;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: 20px; gap: 5px;
justify-content: center; justify-content: center;
.battery-inner { .battery-inner {
display: flex; display: flex;
align-items: center; align-items: center;
position: relative; position: relative;
margin: -38px 0px;
.dec { .dec {
flex-shrink: 0; flex-shrink: 0;
...@@ -174,7 +173,7 @@ export default { ...@@ -174,7 +173,7 @@ export default {
} }
.size-wrap { .size-wrap {
width: 68px; width: 55px;
height: 25px; height: 25px;
flex-shrink: 0; flex-shrink: 0;
position: relative; position: relative;
......
...@@ -156,10 +156,10 @@ export default { ...@@ -156,10 +156,10 @@ export default {
*/ */
async onStartTask() { async onStartTask() {
// 判断是否已接管 // 判断是否已接管
if (!(await this.isTakeOver())) { /* if (!(await this.isTakeOver())) {
this.$message.warning("请先接管无人机"); this.$message.warning("请先接管无人机");
return; return;
} } */
// 判断是否选择了航线 // 判断是否选择了航线
if (this.selectedAirway.id === -1) { if (this.selectedAirway.id === -1) {
...@@ -173,11 +173,11 @@ export default { ...@@ -173,11 +173,11 @@ export default {
customClass: "uav_controlPane", customClass: "uav_controlPane",
showClose: false, showClose: false,
}); });
this.$store.commit("MMCFlightControlCenter/uav/setState", { this.$store.commit("MMCFlightControlCenter/hangar/setState", {
key: "airlineData", key: "airlineData",
value: this.selectedAirway, value: this.selectedAirway,
}); });
this.$store.dispatch("MMCFlightControlCenter/uav/takeOff", { this.$store.dispatch("MMCFlightControlCenter/hangar/takeOff", {
callback: (status) => { callback: (status) => {
if (status) { if (status) {
this.$message.success("一键任务指令发送成功"); this.$message.success("一键任务指令发送成功");
......
<template> <template>
<div class="task-list"> <div class="task-list">
<div class="task-list-header"> <div class="task-list-header">
<div class="task-list-header__item" :class="{active: tabIndex === 0 && useTimedTask}" @click="tabIndex = 0"> <div
class="task-list-header__item"
:class="{active: tabIndex === 0 && useTimedTask}"
@click="tabIndex = 0"
>
<label>常态飞行</label> <label>常态飞行</label>
</div> </div>
<template v-if="useTimedTask"> <template v-if="useTimedTask">
...@@ -97,7 +101,7 @@ export default { ...@@ -97,7 +101,7 @@ export default {
text-shadow: 0px 1px 1px rgba(2, 32, 56, 0.2); text-shadow: 0px 1px 1px rgba(2, 32, 56, 0.2);
text-align: left; text-align: left;
font-style: normal; font-style: normal;
background: linear-gradient( background-image: -webkit-linear-gradient(
right, right,
#e3aa77, #e3aa77,
#f5cda9, #f5cda9,
......
...@@ -9,7 +9,8 @@ ...@@ -9,7 +9,8 @@
<span class="label">{{ label }}</span> <span class="label">{{ label }}</span>
<!-- <div class="el-icon-close close" @click="close"></div> --> <!-- <div class="el-icon-close close" @click="close"></div> -->
</div> </div>
<components :is="playerCom" ref="player" :url="url" :className="'fkLivePlayer'" /> <components :is="playerCom" ref="player" :url="url" :className="'fkLivePlayer'" v-if="showPlayer" />
<div class="iconfont icon-gengxin video-reset" v-hover @click="reset"></div>
<slot></slot> <slot></slot>
</div> </div>
</div> </div>
...@@ -46,6 +47,7 @@ export default { ...@@ -46,6 +47,7 @@ export default {
data() { data() {
return { return {
isFullScreen: false, //是否全屏 isFullScreen: false, //是否全屏
showPlayer: true,
}; };
}, },
computed: { computed: {
...@@ -152,6 +154,13 @@ export default { ...@@ -152,6 +154,13 @@ export default {
font-size: 12px; font-size: 12px;
} }
} }
.video-reset {
position: absolute;
right: 5px;
bottom: 5px;
color: #fff;
}
} }
@keyframes scrollTitle { @keyframes scrollTitle {
......
...@@ -82,6 +82,13 @@ export default { ...@@ -82,6 +82,13 @@ export default {
return streamOptions; return streamOptions;
}, },
}, },
watch: {
streamOptions(){
if(this.streamOptions.length > 0){
this.selectUrl = this.streamOptions[0].url;
}
}
},
mounted() { mounted() {
this.selectUrl = this.streamOptions[0]?.url || ""; this.selectUrl = this.streamOptions[0]?.url || "";
}, },
......
...@@ -189,11 +189,11 @@ export default { ...@@ -189,11 +189,11 @@ export default {
}); });
// 当前机库状态是否空闲 // 当前机库状态是否空闲
if ([0, 8].includes(this.hangarRealTimeData.processStatus)) { if ([0, 8].includes(this.hangarRealTimeData.processStatus)) {
this.$store.commit("MMCFlightControlCenter/uav/setState", { this.$store.commit("MMCFlightControlCenter/hangar/setState", {
key: "airlineData", key: "airlineData",
value: this.selectedAirway, value: this.selectedAirway,
}); });
this.$store.dispatch("MMCFlightControlCenter/uav/takeOff", { this.$store.dispatch("MMCFlightControlCenter/hangar/takeOff", {
uav: this.uav, uav: this.uav,
callback: (status) => { callback: (status) => {
if (status) { if (status) {
......
<template> <template>
<div class="task-list"> <div class="task-list">
<div class="task-list-header"> <div class="task-list-header">
<div class="task-list-header__item" :class="{active: tabIndex === 0 && useTimedTask}" @click="tabIndex = 0"> <div
class="task-list-header__item"
:class="{active: tabIndex === 0 && useTimedTask}"
@click="tabIndex = 0"
>
<label>常态飞行</label> <label>常态飞行</label>
</div> </div>
<template v-if="useTimedTask"> <template v-if="useTimedTask">
...@@ -97,7 +101,7 @@ export default { ...@@ -97,7 +101,7 @@ export default {
text-shadow: 0px 1px 1px rgba(2, 32, 56, 0.2); text-shadow: 0px 1px 1px rgba(2, 32, 56, 0.2);
text-align: left; text-align: left;
font-style: normal; font-style: normal;
background: linear-gradient( background-image: -webkit-linear-gradient(
right, right,
#e3aa77, #e3aa77,
#f5cda9, #f5cda9,
......
...@@ -33,7 +33,7 @@ ...@@ -33,7 +33,7 @@
<span class="line" :class="!productType ? 'w62' : 'w22'"></span> <span class="line" :class="!productType ? 'w62' : 'w22'"></span>
<span class="w10 mr4 h10 radius"></span>释放无人机 <span class="w10 mr4 h10 radius"></span>释放无人机
</div> </div>
<div class="default" :class="rktFn(uavMsg)"> <div class="default" :class="rktFn(hangarRealTimeData.msg)">
<span class="line" :class="!productType ? 'w62' : 'w22'"></span> <span class="line" :class="!productType ? 'w62' : 'w22'"></span>
<span class="w10 mr4 h10 radius"></span>无人机RTK定位 <span class="w10 mr4 h10 radius"></span>无人机RTK定位
</div> </div>
...@@ -50,7 +50,7 @@ ...@@ -50,7 +50,7 @@
<div class="type-box" :class="{ emerg: item.type == 1, ordinary: item.type == 8 }"> <div class="type-box" :class="{ emerg: item.type == 1, ordinary: item.type == 8 }">
<span class="type" v-if="item.type == 1">紧急</span> <span class="type" v-if="item.type == 1">紧急</span>
<span class="type" v-else-if="item.type == 8">普通</span> <span class="type" v-else-if="item.type == 8">普通</span>
<span class="type" v-else>未知</span> <span class="type" v-else>AUTO</span>
</div> </div>
<div class="text">{{ item.text }}</div> <div class="text">{{ item.text }}</div>
<div class="time">{{ item.time }}</div> <div class="time">{{ item.time }}</div>
...@@ -89,7 +89,10 @@ export default { ...@@ -89,7 +89,10 @@ export default {
}, },
}, },
computed: { computed: {
...mapState("MMCFlightControlCenter/hangar", ["hangar", "hangarRealTimeData"]), ...mapState("MMCFlightControlCenter/hangar", [
"hangar",
"hangarRealTimeData",
]),
...mapState("MMCFlightControlCenter/uav", ["uavRealTimeData"]), ...mapState("MMCFlightControlCenter/uav", ["uavRealTimeData"]),
hangarMsgList() { hangarMsgList() {
return this.hangarRealTimeData.msgList.slice().reverse(); return this.hangarRealTimeData.msgList.slice().reverse();
...@@ -254,30 +257,20 @@ export default { ...@@ -254,30 +257,20 @@ export default {
}, },
rktFn(data) { rktFn(data) {
if (this.productType) { if (this.productType) {
if (data.code == 1000 && this.folder == 2 && this.lifts == 2) { if (
return "end"; data?.locationCoordinate3D?.latitude !== 0 &&
} else if (this.folder == 2 && this.lifts == 2) { this.folder == 2 &&
if (data.code != 1000) { this.lifts == 2
return "current"; ) {
} else {
return "end"; return "end";
} }
} else {
return "default"; return "default";
}
} else {
if (data.code == 1000 && this.folder == 2) {
return "end";
} else if (this.folder == 2) {
if (data.code != 1000) {
return "current";
} else { } else {
if (data?.locationCoordinate3D?.latitude !== 0 && this.folder == 2) {
return "end"; return "end";
} }
} else {
return "default"; return "default";
} }
}
}, },
}, },
}; };
...@@ -329,11 +322,12 @@ export default { ...@@ -329,11 +322,12 @@ export default {
border-top: 0.2px dashed #afdcff; border-top: 0.2px dashed #afdcff;
} }
&.end { &.end,
color: #3388FF; .current {
color: #3388ff;
.radius { .radius {
background: #3388FF; background: #3388ff;
border: 0; border: 0;
} }
} }
...@@ -354,7 +348,7 @@ export default { ...@@ -354,7 +348,7 @@ export default {
.font { .font {
font-size: 20px; font-size: 20px;
font-family: YouSheBiaoTiHei; font-family: YouSheBiaoTiHei;
color: #ACACAC; color: #acacac;
line-height: 26px; line-height: 26px;
text-shadow: 0px 1px 1px rgba(2, 32, 56, 0.2); text-shadow: 0px 1px 1px rgba(2, 32, 56, 0.2);
background: linear-gradient( background: linear-gradient(
...@@ -385,14 +379,14 @@ export default { ...@@ -385,14 +379,14 @@ export default {
.iconfont { .iconfont {
font-size: 18px; font-size: 18px;
color: #3388FF; color: #3388ff;
margin-right: 4px; margin-right: 4px;
} }
.icon-text { .icon-text {
font-family: MicrosoftYaHeiUI; font-family: MicrosoftYaHeiUI;
font-size: 14px; font-size: 14px;
color: #ACACAC; color: #acacac;
font-weight: 400; font-weight: 400;
} }
} }
...@@ -519,7 +513,7 @@ export default { ...@@ -519,7 +513,7 @@ export default {
transform: rotate(270deg) !important; transform: rotate(270deg) !important;
} }
.close { .close {
color: #ACACAC; color: #acacac;
cursor: pointer; cursor: pointer;
margin: 0 10px 0 20px; margin: 0 10px 0 20px;
} }
......
...@@ -59,7 +59,7 @@ ...@@ -59,7 +59,7 @@
<div class="icon-box"> <div class="icon-box">
<span class="type fr" v-if="device.status">{{ typeName(device.status) }}</span> <span class="type fr" v-if="device.status">{{ typeName(device.status) }}</span>
<span @click="itemLocation(device)" class="iconfont fr icon-dingwei1"></span> <span @click="onLocation(device)" class="iconfont fr icon-dingwei1" v-hover></span>
</div> </div>
</div> </div>
</div> </div>
...@@ -85,10 +85,12 @@ export default { ...@@ -85,10 +85,12 @@ export default {
}, },
inject: ["rootNode"], inject: ["rootNode"],
data() { data() {
return {}; return {
locationEntity: null
};
}, },
computed: { computed: {
...mapState("MMCFlightControlCenter", ["listCollapse"]), ...mapState("MMCFlightControlCenter", ["listCollapse", "cesiumViewer"]),
...mapState("MMCFlightControlCenter/hangar", ["showPanel", "hangar"]), ...mapState("MMCFlightControlCenter/hangar", ["showPanel", "hangar"]),
...mapState("MMCFlightControlCenter/uav", ["uav"]), ...mapState("MMCFlightControlCenter/uav", ["uav"]),
}, },
...@@ -114,6 +116,7 @@ export default { ...@@ -114,6 +116,7 @@ export default {
} }
return name; return name;
}, },
// 机库选中
handClick(isCheck, device) { handClick(isCheck, device) {
console.log("checkbox", isCheck, device); console.log("checkbox", isCheck, device);
device.isCheck = isCheck; device.isCheck = isCheck;
...@@ -199,6 +202,38 @@ export default { ...@@ -199,6 +202,38 @@ export default {
} }
this.rootNode.$emit("hangarChange", { hangar: this.hangar }); //根节点发出机库更换事件 this.rootNode.$emit("hangarChange", { hangar: this.hangar }); //根节点发出机库更换事件
}, },
// 机库定位
onLocation(device) {
if (device.latitude && device.longitude) {
let viewer = this.cesiumViewer;
if (this.locationEntity) {
viewer.entities.remove(this.locationEntity);
}
this.locationEntity = viewer.entities.add({
position: Cesium.Cartesian3.fromDegrees(
Number(device.longitude),
Number(device.latitude)
),
billboard: {
image: require("../../assets/images/address.png"),
width: 30,
height: 40,
distanceDisplayCondition: new Cesium.DistanceDisplayCondition(0),
disableDepthTestDistance: Number.POSITIVE_INFINITY,
},
});
viewer.camera.flyTo({
destination: Cesium.Cartesian3.fromDegrees(
Number(device.longitude),
Number(device.latitude),
30000
),
maximumHeight: 10,
});
} else {
this.$message.warning("该机库没有经纬度");
}
},
}, },
}; };
</script> </script>
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
<template> <template>
<div class="list" :class="{ collapse: listCollapse }"> <div class="list" :class="{ collapse: listCollapse }">
<div class="list-header"> <div class="list-header">
<span class="list-header__text">机库列表</span> <span class="list-header__text">鹰巢列表</span>
<div class="list-header__count"> <div class="list-header__count">
{{ count.sumCount }}架 / {{ count.sumCount }}架 /
<span class="online">{{ count.onlineCount }}在线</span> <span class="online">{{ count.onlineCount }}在线</span>
...@@ -10,15 +10,27 @@ ...@@ -10,15 +10,27 @@
{{ count.offlineCount }}离线 {{ count.offlineCount }}离线
</div> </div>
</div> </div>
<div class="uav-search">
<el-input
class="uav-search__input"
clearable
placeholder="请输入无人机名称/机构名称"
v-model="searchContent"
v-on:keyup.enter.native="onUavSearch"
>
<i
slot="suffix"
class="el-input__icon el-icon-search"
style="color: rgba(123, 181, 213, 1)"
></i>
</el-input>
<el-button class="uav-search__btn" @click="onUavSearch" v-hover>搜索</el-button>
</div>
<div class="cpt-observe-nest-list"> <div class="cpt-observe-nest-list">
<div class="ctx-box pl5">
<div class="list-box pr14">
<template v-if="list && list.length"> <template v-if="list && list.length">
<Item v-for="item in list" :key="item.id" :data="item" /> <Item v-for="item in list" :key="item.id" :data="item" />
</template> </template>
</div> </div>
</div>
</div>
<!-- 未进入机库或者进入机库后列表是展开的情况下,才显示收纳按钮 --> <!-- 未进入机库或者进入机库后列表是展开的情况下,才显示收纳按钮 -->
<div <div
class="hangar-list_btn" class="hangar-list_btn"
...@@ -35,6 +47,7 @@ ...@@ -35,6 +47,7 @@
import { Control_API } from "../../../../api"; import { Control_API } from "../../../../api";
import Item from "./components/item"; import Item from "./components/item";
import { mapState } from "vuex"; import { mapState } from "vuex";
import mock from './mock';
export default { export default {
name: "List", name: "List",
...@@ -42,9 +55,10 @@ export default { ...@@ -42,9 +55,10 @@ export default {
components: { Item }, components: { Item },
data() { data() {
return { return {
list: [], list: mock/* [] */,
deviceType: 2, // 设备类型 2鹰巢 deviceType: 2, // 设备类型 2鹰巢
timeHandle: null, timeHandle: null,
searchContent: '',
}; };
}, },
...@@ -91,11 +105,17 @@ export default { ...@@ -91,11 +105,17 @@ export default {
methods: { methods: {
async getList() { async getList() {
let res = await Control_API.getUavTree({ let res = await Control_API.getUavTree({
name: "", serchKey: this.searchContent,
deviceType: this.deviceType, deviceType: this.deviceType,
}); });
this.list = res.data; this.list = res.data;
}, },
/**
* 无人机搜索
*/
onUavSearch() {
this.getList();
},
}, },
}; };
</script> </script>
...@@ -106,14 +126,14 @@ export default { ...@@ -106,14 +126,14 @@ export default {
flex-direction: column; flex-direction: column;
position: absolute; position: absolute;
width: 420px; width: 420px;
height: 85%; height: 100%;
left: 0; left: 0;
top: 60px; top: 0;
// height: 86vh; // height: 86vh;
z-index: 99; z-index: 99;
transition: 0.3s; transition: 0.3s;
border-radius: 5px 5px 0px 0px;
overflow: visible; overflow: visible;
background: #222222;
&.collapse { &.collapse {
transform: translateX(-100%); transform: translateX(-100%);
...@@ -146,126 +166,100 @@ export default { ...@@ -146,126 +166,100 @@ export default {
border-bottom: 9px solid #fff; border-bottom: 9px solid #fff;
} }
} }
}
.healthy { .uav-search::v-deep {
box-sizing: border-box; flex-shrink: 0;
padding: 0 5px; padding: 0 16px;
display: flex; display: flex;
justify-content: space-between;
align-items: center; align-items: center;
backdrop-filter: blur(3px);
font-size: 16px;
font-weight: bold;
height: 100%;
.healthy--total { .uav-search__input {
color: #cad8d9; width: 292px;
} height: 32px;
border-radius: 4px;
.healthy--un { .el-input__icon {
color: #d54a15; line-height: 32px;
color: #a8abb2 !important;
} }
}
.nestlist {
background: rgba(4, 18, 50, 0.5);
}
.cpt-observe-nest-list {
display: flex;
flex: 1;
flex-direction: column;
background: #222222;
overflow-y: auto;
.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 { input {
height: 36px; height: 32px;
background-color: transparent; background: #191919;
border: none; font-family: PingFangSC, PingFang SC;
padding: 0;
font-family: Microsoft YaHei;
font-size: 16px;
color: #08c2d1;
font-weight: 400; font-weight: 400;
font-size: 12px;
color: #fff;
border: 1px solid #4b4b4b;
&::placeholder {
font-size: 12px;
color: #a8abb2;
}
}
} }
.el-input__suffix { .uav-search__btn {
display: flex; display: flex;
justify-content: center;
align-items: center; align-items: center;
width: 80px;
height: 32px;
font-size: 14px;
color: #fff;
border-radius: 2px;
border: 0;
background: #3388ff;
} }
} }
}
.search-icon-box { .cpt-observe-nest-list {
display: flex; display: flex;
align-items: center; flex: 1;
cursor: pointer; flex-direction: column;
overflow-y: auto;
padding: 0 16px;
.iconfont { /* 滚动条整体样式 */
font-size: 24px; &::-webkit-scrollbar {
color: #08ffff; width: 10px; /* 滚动条宽度 */
} }
&:hover { /* 滚动条滑块样式 */
.iconfont { &::-webkit-scrollbar-thumb {
opacity: 0.8; background-color: #02173d; /* 滑块颜色 */
}
} }
/* 滚动条滑块悬停样式 */
&::-webkit-scrollbar-thumb:hover {
background-color: #112d5b; /* 悬停时滑块颜色 */
} }
&::-webkit-scrollbar-track-piece {
/* background-color: #182F5C; */
} }
.ctx-box { &::-webkit-scrollbar-track {
flex: 1; background-color: #182f5c;
overflow: auto;
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;
}
.list-header { .list-header {
box-sizing: border-box; box-sizing: border-box;
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
align-items: center; align-items: center;
// width: 100%; // width: 100%;
height: 33px; height: 54px;
background: #3c3c3c;
padding: 0 16px; padding: 0 16px;
.list-header__text { .list-header__text {
vertical-align: bottom;
font-family: PingFangSC, PingFang SC; font-family: PingFangSC, PingFang SC;
font-weight: 600; font-weight: 600;
font-size: 16px; font-size: 16px;
color: #ffffff; color: #ffffff;
} }
.list-header__icon {
width: 26px;
margin-left: 9px;
}
.list-header__count { .list-header__count {
color: #fff; color: #fff;
font-weight: 500; font-weight: 500;
......
export default [
{
id: 1,
name: 'test',
onLineCount: 1,
offLineCount: 0,
deviceDOList: [
{
id: 1,
isOnline: 1,
deviceId: 1,
name: 'test',
}
]
}
]
\ No newline at end of file
...@@ -5,6 +5,7 @@ export default { ...@@ -5,6 +5,7 @@ export default {
computed: { computed: {
...mapState("MMCFlightControlCenter/hangar", ["hangar"]), ...mapState("MMCFlightControlCenter/hangar", ["hangar"]),
...mapState("MMCFlightControlCenter/uav", ["uav"]), ...mapState("MMCFlightControlCenter/uav", ["uav"]),
...mapState("MMCFlightControlCenter", ['mqttUrlHangar']),
// mqtt实时数据 // mqtt实时数据
mqttDataSetHangar() { mqttDataSetHangar() {
return this.$store.state.MMCMQTT?.dataSet?.[this.hangar?.deviceId]; return this.$store.state.MMCMQTT?.dataSet?.[this.hangar?.deviceId];
...@@ -12,9 +13,6 @@ export default { ...@@ -12,9 +13,6 @@ export default {
mqttDataSetUav() { mqttDataSetUav() {
return this.$store.state.MMCMQTT?.dataSet?.[this.uav?.deviceId]; return this.$store.state.MMCMQTT?.dataSet?.[this.uav?.deviceId];
}, },
mqttUrl() {
return this.$store.state.MMCFlightControlCenter.mqttUrl;
},
}, },
watch: { watch: {
mqttDataSetHangar(newVal) { mqttDataSetHangar(newVal) {
...@@ -36,7 +34,7 @@ export default { ...@@ -36,7 +34,7 @@ export default {
try { try {
this.$store this.$store
.dispatch("MMCMQTT/init", { .dispatch("MMCMQTT/init", {
url: this.mqttUrl, url: this.mqttUrlHangar,
}) })
.then(() => { .then(() => {
console.log("mqtt连接成功"); console.log("mqtt连接成功");
......
...@@ -221,6 +221,7 @@ export default { ...@@ -221,6 +221,7 @@ export default {
return ret; return ret;
}); });
console.log('提交的动作', actions);
return { return {
altitude: val.altitude, altitude: val.altitude,
coordinate: { coordinate: {
......
...@@ -13,14 +13,14 @@ ...@@ -13,14 +13,14 @@
</div> </div>
<div class="ctx-box dialog-content"> <div class="ctx-box dialog-content">
<div class="head mt7"> <div class="head mt7">
<div class="text">CODE</div> <div class="text">消息等级</div>
<div class="text con">消息内容</div> <div class="text con">消息内容</div>
<div class="time">时间</div> <div class="time">时间</div>
</div> </div>
<div class="list-box mt7"> <div class="list-box mt7">
<div class="item-box" v-for="(item,index) in msgList" :key="index"> <div class="item-box" v-for="(item,index) in msgList" :key="index">
<div class="text-box"> <div class="text-box">
<span class="code">{{ item.code }}</span> <span class="grade">{{ item.grade }}</span>
<div class="text">{{ item.text }}</div> <div class="text">{{ item.text }}</div>
<div class="time">{{ item.time }}</div> <div class="time">{{ item.time }}</div>
</div> </div>
...@@ -143,6 +143,11 @@ export default { ...@@ -143,6 +143,11 @@ export default {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
padding: 0 16px; padding: 0 16px;
width: 100%;
&.dialog-content {
flex-wrap: initial;
}
.head { .head {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
...@@ -153,6 +158,7 @@ export default { ...@@ -153,6 +158,7 @@ export default {
letter-spacing: 1px; letter-spacing: 1px;
line-height: 22px; line-height: 22px;
font-weight: 700; font-weight: 700;
width: 100%;
.text, .text,
.time { .time {
width: 20%; width: 20%;
...@@ -181,7 +187,7 @@ export default { ...@@ -181,7 +187,7 @@ export default {
justify-content: space-between; justify-content: space-between;
align-items: center; align-items: center;
.code { .grade {
width: 20%; width: 20%;
height: 20px; height: 20px;
text-align: center; text-align: center;
......
...@@ -37,8 +37,34 @@ ...@@ -37,8 +37,34 @@
<a href="http://32.128.6.52:4500/11.11平台部署/ChromeStandaloneSetup64.exe">下载最新谷歌</a> <a href="http://32.128.6.52:4500/11.11平台部署/ChromeStandaloneSetup64.exe">下载最新谷歌</a>
</p>--> </p>-->
<div class="lists"> <div class="lists">
<!-- <div style="text-align: left">asfnjkfassfausfasn</div> --> <ul v-if="photoListDate" class="infinite-list" style="overflow:auto">
<li v-for="item in photoListDate" class="infinite-list-item">
<template v-if="item.imgList.length > 0">
<div class="list-item-date">
<div>{{item.date}}</div>
<el-button type="text" size="small" @click="photoListDate = null;">返回></el-button>
</div>
<div class="list-item-imgs">
<template v-for="(img, i) in item.imgList">
<MMCImage
class="list-item__img"
:key="i"
fit="cover"
:src="img || img"
:preview-src-list="item.imgList"
:initial-index="i"
@error="onImgError"
crossorigin
>
<div class="list-item__img-download" @click="onDownload(img)">下载</div>
</MMCImage>
</template>
</div>
</template>
</li>
</ul>
<ul <ul
v-else
class="infinite-list" class="infinite-list"
v-infinite-scroll="onLoadList" v-infinite-scroll="onLoadList"
style="overflow:auto" style="overflow:auto"
...@@ -46,13 +72,16 @@ ...@@ -46,13 +72,16 @@
:infinite-scroll-disabled="noMore" :infinite-scroll-disabled="noMore"
> >
<li v-for="item in photoList" class="infinite-list-item"> <li v-for="item in photoList" class="infinite-list-item">
<template v-if="item.imgList.length > 0">
<div class="list-item-date"> <div class="list-item-date">
<div>{{item.date}}</div> <div>{{item.date}}</div>
<el-button type="text" size="small" @click="photoListDate = [item]">更多></el-button>
</div> </div>
<div class="list-item-imgs"> <div class="list-item-imgs">
<template v-for="(img, i) in item.imgList">
<MMCImage <MMCImage
v-if="i < 3"
class="list-item__img" class="list-item__img"
v-for="(img, i) in item.imgList"
:key="i" :key="i"
fit="cover" fit="cover"
:src="img || img" :src="img || img"
...@@ -63,7 +92,9 @@ ...@@ -63,7 +92,9 @@
> >
<div class="list-item__img-download" @click="onDownload(img)">下载</div> <div class="list-item__img-download" @click="onDownload(img)">下载</div>
</MMCImage> </MMCImage>
</template>
</div> </div>
</template>
</li> </li>
</ul> </ul>
</div> </div>
...@@ -85,12 +116,15 @@ import { ...@@ -85,12 +116,15 @@ import {
} from "../../../../../../../../api"; } from "../../../../../../../../api";
import { mapState } from "vuex"; import { mapState } from "vuex";
import MMCImage from "../../../../../../../../components/image"; import MMCImage from "../../../../../../../../components/image";
import mock from "./mock";
import download from 'downloadjs';
export default { export default {
name: "ViewLib", name: "ViewLib",
components: { components: {
MMCImage, MMCImage,
}, },
inject: ["rootNode"],
data() { data() {
return { return {
checkList: [], // 多选结果 checkList: [], // 多选结果
...@@ -160,28 +194,30 @@ export default { ...@@ -160,28 +194,30 @@ export default {
// value: "车牌识别", // value: "车牌识别",
// }, // },
], //视图库类型 ], //视图库类型
fileType: '图片', //视图文件类型 0:图片;1:视频 fileType: "图片", //视图文件类型 0:图片;1:视频
fileType2: 0, //机载文件类型 fileType2: 0, //机载文件类型
photoList: [], //资源列表 photoList: mock /* [] */, //资源列表
photoListDate: null, //某日期的所有资源
moreShow: false, //显示更多, moreShow: false, //显示更多,
page: { page: {
pageNo: 0, pageNo: 0,
pageSize: 10, pageSize: 10,
}, },
noMore: false, //是否没有更多数据了 noMore: false, //是否没有更多数据了
}; };
}, },
computed: { computed: {
...mapState("MMCFlightControlCenter/uav", ["uav"]), ...mapState("MMCFlightControlCenter/uav", ["uav"]),
...mapState("MMCFlightControlCenter", ["baseUrl"]) ...mapState("MMCFlightControlCenter", ["baseUrl"]),
}, },
watch: { watch: {
fileType(){ fileType() {
this.init(); this.init();
} },
}, },
mounted() { mounted() {
this.init(); // this.init();
}, },
methods: { methods: {
async init() { async init() {
...@@ -193,7 +229,7 @@ export default { ...@@ -193,7 +229,7 @@ export default {
async getPage() { async getPage() {
let res = await ViewLibrary.page({ let res = await ViewLibrary.page({
...this.page, ...this.page,
fileType: this.fileType === '图片' ? 0 : 1, fileType: this.fileType === "图片" ? 0 : 1,
deviceId: this.uav.deviceId, deviceId: this.uav.deviceId,
type: parseInt(this.viewLibTab), type: parseInt(this.viewLibTab),
}); });
...@@ -202,8 +238,15 @@ export default { ...@@ -202,8 +238,15 @@ export default {
this.noMore = true; this.noMore = true;
} else { } else {
photoList.forEach((item) => { photoList.forEach((item) => {
item.imgList = item.viewLibraryRespVOS.map((item1) => { item.imgList = item.viewLibraryRespVOS
return this.aiType == 1 ? `${this.baseUrl}${item1.fileUrl}` : `${this.baseUrl}${item1.aiImageUrl}`; .filter((item1) => {
// 过滤掉对应筛选下没图片链接的数据
return this.aiType == 1 ? item1.fileUrl : item1.aiImageUrl;
})
.map((item1) => {
return this.aiType == 1
? `${item1.fileUrl}`
: `${item1.aiImageUrl}`;
}); });
}); });
this.photoList = this.photoList.concat(photoList); this.photoList = this.photoList.concat(photoList);
...@@ -236,7 +279,7 @@ export default { ...@@ -236,7 +279,7 @@ export default {
this.init(); this.init();
}, },
onDownload(url) { onDownload(url) {
window.open(url, "_self"); download(url);
}, },
/** /**
* 加载下一页数据 * 加载下一页数据
...@@ -444,6 +487,8 @@ export default { ...@@ -444,6 +487,8 @@ export default {
color: #878787; color: #878787;
line-height: 22px; line-height: 22px;
margin-bottom: 6px; margin-bottom: 6px;
display: flex;
justify-content: space-between;
} }
.list-item-imgs { .list-item-imgs {
......
export default [
{
date: '2024-8-13',
imgList: [
'http://gips3.baidu.com/it/u=3886271102,3123389489&fm=3028&app=3028&f=JPEG&fmt=auto?w=1280&h=960',
2,
3,
4,
5
]
}
]
\ No newline at end of file
...@@ -116,6 +116,30 @@ export default { ...@@ -116,6 +116,30 @@ export default {
}, */ }, */
]; ];
switch (type) { switch (type) {
// 车牌识别
case "plate": {
let formData = new FormData();
formData.append("image", blob, `下载.jpeg`);
formData.append("iscount", 1);
let res = await AI_API[type](formData);
results =
res?.data?.data?.map((item) => {
return {
x: item.ocRbox.x1,
y: item.ocRbox.y1,
width: item.ocRbox.x2 - item.ocRbox.x1,
height: item.ocRbox.y2 - item.ocRbox.y1,
label: item.label,
prob: 0,
};
}) || [];
if (results.length > 0) {
isSuccess = true;
}
break;
}
case "face": case "face":
/* { /* {
// 用的百度 // 用的百度
...@@ -137,8 +161,7 @@ export default { ...@@ -137,8 +161,7 @@ export default {
} }
} }
break; */ break; */
// 车牌识别
case "plate":
// 漏油识别结果 // 漏油识别结果
case "oilLeak": case "oilLeak":
{ {
...@@ -235,29 +258,12 @@ export default { ...@@ -235,29 +258,12 @@ export default {
break; break;
} }
let formData = new FormData();
formData.append("file", blob, `ai识别.jpeg`);
let uploadRes = await ViewLibrary.uploadFile(formData);
debugger
if (uploadRes.code === 0) {
let img = uploadRes.data;
ViewLibrary.create({
fileUrl: img,
fileType: 0,
detectorType: find.typeId,
deviceId: this.uav.deviceId,
aiData: JSON.stringify(results),
aiImageUrl: img,
});
}
if (isSuccess) { if (isSuccess) {
console("识别结果", results); console.log("识别结果", results);
this.$message.success("识别成功"); this.$message.success("识别成功");
// 将识别结果绘制到图片上 // 将识别结果绘制到图片上
let img = new Image(); let img = new Image();
img.onload = () => { img.onload = async () => {
let width = img.width; let width = img.width;
let height = img.height; let height = img.height;
console.log("图片宽度:", width, "高度:", height); console.log("图片宽度:", width, "高度:", height);
...@@ -269,6 +275,32 @@ export default { ...@@ -269,6 +275,32 @@ export default {
this.aiResultImg = canvas.toDataURL("image/svg"); this.aiResultImg = canvas.toDataURL("image/svg");
this.aiResultShow = true; this.aiResultShow = true;
// 识别结果上传到视图库 // 识别结果上传到视图库
canvas.toBlob(async (blob1) => {
console.log("识别结果", blob1);
let formData = new FormData();
formData.append("file", blob1, `ai识别.jpeg`);
let uploadRes = await ViewLibrary.uploadFile(formData);
if (uploadRes.code === 0) {
let formData1 = new FormData();
formData1.append("file", blob, `原图.jpeg`);
let uploadRes1 = await ViewLibrary.uploadFile(formData1);
if (uploadRes1.code === 0) {
let img = uploadRes.data;
let img1 = uploadRes1.data;
ViewLibrary.create({
fileUrl: img1,
fileType: 0,
detectorType: find.typeId,
deviceId: this.uav.deviceId,
aiData: JSON.stringify(results),
aiImageUrl: img,
});
}
}
});
}; };
img.src = base64; img.src = base64;
// img.src = testImg; // img.src = testImg;
...@@ -307,7 +339,7 @@ export default { ...@@ -307,7 +339,7 @@ export default {
ctx.textAlign = "left"; ctx.textAlign = "left";
// 绘制文字 // 绘制文字
ctx.fillText( ctx.fillText(
`${item.label}: ${item.prob}(相似度)`, `${item.label}${item.prob ? ": " + item.prob + "(相似度)" : ""}`,
item.x, item.x,
item.y - 20, item.y - 20,
250 250
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
<div class="cpt_video" @click="lensControl" v-if="showPlayer"> <div class="cpt_video" @click="lensControl" v-if="showPlayer">
<Obstacle v-if="!isStatus"></Obstacle> <Obstacle v-if="!isStatus"></Obstacle>
<div class="video"> <div class="video">
<div class="name" v-clipboard:copy="vUrl.vUrl">{{ device.name }}</div> <div class="name" v-clipboard:copy="vUrl.vUrl">{{ uav.name }}</div>
<!-- <div class="type" v-if="networkType">{{ networkType }}</div> --> <!-- <div class="type" v-if="networkType">{{ networkType }}</div> -->
<!-- <div class="types">{{ streamName }}</div> --> <!-- <div class="types">{{ streamName }}</div> -->
<div v-show="!isStatus" class="close" @click="close()">关闭</div> <div v-show="!isStatus" class="close" @click="close()">关闭</div>
...@@ -28,11 +28,11 @@ ...@@ -28,11 +28,11 @@
:LivePlayerInfor="false" :LivePlayerInfor="false"
:fpvUrl="fpvUrl" :fpvUrl="fpvUrl"
:data="vUrl" :data="vUrl"
:device="device" :device="uav"
:controls="false" :controls="false"
:className="'fkLivePlayer'" :className="'fkLivePlayer'"
:infoflag="infoflag" :infoflag="infoflag"
:deviceName="device.name" :deviceName="uav.name"
:raw_msg="raw_msg" :raw_msg="raw_msg"
:isInfoShow="isInfoShow" :isInfoShow="isInfoShow"
@close="infoflag = false" @close="infoflag = false"
...@@ -314,7 +314,7 @@ ...@@ -314,7 +314,7 @@
</div> </div>
<div class="right-menu"> <div class="right-menu">
<template v-if="device.network === 2"> <template v-if="uav.network === 2">
<el-tooltip content="拍照" placement="bottom"> <el-tooltip content="拍照" placement="bottom">
<div class="menu-item plate" @click="photojz"> <div class="menu-item plate" @click="photojz">
<img src="./assets/images/ai.png" /> <img src="./assets/images/ai.png" />
...@@ -344,26 +344,25 @@ ...@@ -344,26 +344,25 @@
</div> </div>
<PointList <PointList
:uavRealTimeData="uavRealTimeData" :uavRealTimeData="uavRealTimeData"
:mountData="mountDatas" :mountData="selectMount"
v-if="showFlywayAction" v-if="showFlywayAction"
@close="showFlywayAction = false" @close="showFlywayAction = false"
@dblclick.native.stop @dblclick.native.stop
></PointList> ></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.deviceId" :list="carList" @closecar="carAiShow = false" /> <CarAI v-if="carAiShow" :uavId="uav.deviceId" :list="carList" @closecar="carAiShow = false" />
<Traffic v-if="trafficShow" :trafficData="trafficData" @close="trafficShow = false" /> <Traffic v-if="trafficShow" :trafficData="trafficData" @close="trafficShow = false" />
<carTraffic <carTraffic
v-if="cartrafficShow" v-if="cartrafficShow"
:trafficData="cartrafficData" :trafficData="cartrafficData"
@close="cartrafficShow = false" @close="cartrafficShow = false"
/> />
</div> </div>
</template> </template>
<script> <script>
import { Control_API } from "../../../../api"; import { ViewLibrary } from "../../../../api";
import dayjs from "dayjs"; import dayjs from "dayjs";
import FaceAI from "./components/faceai"; import FaceAI from "./components/faceai";
import CarAI from "./components/carai"; import CarAI from "./components/carai";
...@@ -380,7 +379,7 @@ import PointList from "./components/pointList"; ...@@ -380,7 +379,7 @@ import PointList from "./components/pointList";
import videoModelChange from "./components/videoModelChange"; import videoModelChange from "./components/videoModelChange";
import fkutils from "./methods/utils"; import fkutils from "./methods/utils";
import { mapState } from "vuex"; import { mapState } from "vuex";
import AiList from './components/aiList'; import AiList from "./components/aiList";
export default { export default {
name: "Player", name: "Player",
...@@ -395,23 +394,10 @@ export default { ...@@ -395,23 +394,10 @@ export default {
Obstacle, Obstacle,
SRSPlayer, SRSPlayer,
videoModelChange, videoModelChange,
AiList AiList,
}, },
inject: ["bus"], inject: ["bus"],
props: { props: {},
mountDatas: {
type: Object,
default: () => ({}),
},
NXdata: {
type: Object,
default: () => {},
},
device: {
type: Object,
default: () => ({}),
},
},
data() { data() {
return { return {
backgroundStyle: { backgroundStyle: {
...@@ -471,11 +457,11 @@ export default { ...@@ -471,11 +457,11 @@ export default {
openOSD: true, // 是否开启OSD openOSD: true, // 是否开启OSD
showFlywayAction: false, //显示航点动作 showFlywayAction: false, //显示航点动作
showContinueFly: false, //显示继续飞行对话框 showContinueFly: false, //显示继续飞行对话框
continueFlyContent: '', //继续飞行对话框内容 continueFlyContent: "", //继续飞行对话框内容
}; };
}, },
computed: { computed: {
...mapState("MMCFlightControlCenter/uav", ["uav"]), ...mapState("MMCFlightControlCenter/uav", ["uav", "selectMount"]),
/** /**
* 播放器组件名 * 播放器组件名
*/ */
...@@ -507,7 +493,7 @@ export default { ...@@ -507,7 +493,7 @@ export default {
* @returns 专网 | 公网 * @returns 专网 | 公网
*/ */
networkType() { networkType() {
// console.log('网络判断', this.device.videos) // console.log('网络判断', this.uav.videos)
let name = "公网"; let name = "公网";
return name; return name;
...@@ -521,7 +507,7 @@ export default { ...@@ -521,7 +507,7 @@ export default {
*/ */
streamOptions() { streamOptions() {
let streamOptions = []; let streamOptions = [];
let streamConfiguration = this.device?.streamConfiguration.find( let streamConfiguration = this.uav?.streamConfiguration.find(
(item) => item.urlType === 0 (item) => item.urlType === 0
); );
...@@ -681,22 +667,12 @@ export default { ...@@ -681,22 +667,12 @@ export default {
this.showFlywayAction = true; this.showFlywayAction = true;
} }
}, },
async checkUseOperateFn(device) {
// 查看是否有控制权限
let res = await API.FCKERNEL.checkUseOperate({ deviceId: device });
if (res.code == 201) {
this.$message.warning(res.msg);
return false;
} else {
return true;
}
},
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({
deviceId: this.device.deviceId, deviceId: this.uav.deviceId,
}); });
if (res.code == 201) { if (res.code == 201) {
this.$message.warning(res.msg); this.$message.warning(res.msg);
...@@ -753,11 +729,11 @@ export default { ...@@ -753,11 +729,11 @@ export default {
}, },
//车流密度 //车流密度
async carFrame() { async carFrame() {
this.carFlow(this.device.deviceId); this.carFlow(this.uav.deviceId);
}, },
//人流密度 //人流密度
async frame() { async frame() {
this.flow(this.device.deviceId); this.flow(this.uav.deviceId);
}, },
/** /**
* 截图 * 截图
...@@ -816,38 +792,32 @@ export default { ...@@ -816,38 +792,32 @@ export default {
let blob = this.$refs.player.screenShot(); let blob = this.$refs.player.screenShot();
if (blob) { if (blob) {
console.log(blob, window.URL.createObjectURL(blob)); console.log(blob, window.URL.createObjectURL(blob));
const data = new FormData(); let formData = new FormData();
data.append("addtime", dayjs().format("YYYY-MM-DD HH:mm:ss")); formData.append("file", blob, `截图.jpeg`);
data.append("file", blob); let uploadRes = await ViewLibrary.uploadFile(formData);
data.append("deviceId", this.device.deviceId);
data.append("name", this.device.name); if (uploadRes.code === 0) {
data.append("imageType", 1); let res = await ViewLibrary.create({
data.append("sortie", this.flightSortie || ""); fileUrl: uploadRes.data,
if (this.device?.locationCoordinate3D?.longitude) { fileType: 0,
data.append( deviceId: this.uav.deviceId,
"longitude", });
this.device?.locationCoordinate3D?.longitude
);
data.append("latitude", this.device?.locationCoordinate3D?.latitude);
}
const res = await Control_API.addPhoto(data);
if (res.code === 0) { if (res.code === 0) {
this.$message.success("截屏成功"); this.$message.success("截屏成功");
} else { } else {
this.$message({ this.$message.error(res.msg || "截屏失败");
type: "error",
message: res.msg || "出错了",
duration: 1000,
});
} }
} else { } else {
this.$message.warning("截屏失败"); this.$message.error(uploadRes.msg || "截屏失败");
}
return;
} }
this.$message.warning("截屏失败");
}, },
// 人脸车牌识别 // 人脸车牌识别
handle(command) { handle(command) {
// this.getcanvas(command); // this.getcanvas(command);
this.getcanvasFaceCar(command, this.device.deviceId, this.device.id); this.getcanvasFaceCar(command, this.uav.deviceId, this.uav.id);
}, },
/** /**
* 居中 * 居中
...@@ -875,11 +845,11 @@ export default { ...@@ -875,11 +845,11 @@ export default {
*/ */
async lensControl(el) { async lensControl(el) {
// let mountData =this.$store.state.device.move_data // let mountData =this.$store.state.device.move_data
let { device, mountData } = this; let { mountData } = this;
// if mountStatus =1 代表启用 屏幕指点功能 // if mountStatus =1 代表启用 屏幕指点功能
if ( if (
mountData.mountStatus == 1 && mountData.mountStatus == 1 &&
device.deviceId == mountData.deviceId && this.uav.deviceId == mountData.deviceId &&
mountData.moveType == "wrj" mountData.moveType == "wrj"
) { ) {
let evt = window.event || el; let evt = window.event || el;
...@@ -917,8 +887,8 @@ export default { ...@@ -917,8 +887,8 @@ export default {
} }
let mounteList = { data: buffer, ...mountData }; let mounteList = { data: buffer, ...mountData };
if (buffer) { if (buffer) {
if (this.device.network === 2) { if (this.uav.network === 2) {
let topic = "PX4/OBTAIN/" + this.device.deviceId; let topic = "PX4/OBTAIN/" + this.uav.deviceId;
this.$store.dispatch("MMCMQTT/publish", { this.$store.dispatch("MMCMQTT/publish", {
topic: topic, topic: topic,
data: { data: {
...@@ -953,10 +923,10 @@ export default { ...@@ -953,10 +923,10 @@ export default {
/** /**
* ai截图事件 * ai截图事件
*/ */
onAiScreenShot({callback}){ onAiScreenShot({ callback }) {
let blob = this.$refs.player.screenShot(); let blob = this.$refs.player.screenShot();
callback(blob); callback(blob);
} },
}, },
}; };
</script> </script>
...@@ -1434,8 +1404,6 @@ export default { ...@@ -1434,8 +1404,6 @@ export default {
> img { > img {
width: 100%; width: 100%;
} }
} }
} }
</style> </style>
<!-- 飞控中心无人机应slot --> <!-- 飞控中心无人机应slot -->
<template> <template>
<div class="h700 list"> <div class="list">
<template v-if="wsList && wsList.length"> <template v-if="wsList && wsList.length">
<!-- <div class="all">全部</div> --> <!-- <div class="all">全部</div> -->
<div class="pl10 pb30 pr8"> <div class="pl10 pb30 pr8">
......
...@@ -4,7 +4,6 @@ ...@@ -4,7 +4,6 @@
<img style src="./assets/images/collapse.svg" /> <img style src="./assets/images/collapse.svg" />
</div> </div>
<div class="uav-list-header"> <div class="uav-list-header">
<img class="uav-list-header__icon" src="./assets/images/uav_list_header.png" />
<span class="uav-list-header__text">无人机列表</span> <span class="uav-list-header__text">无人机列表</span>
</div> </div>
<div class="uav-search"> <div class="uav-search">
...@@ -115,14 +114,13 @@ export default { ...@@ -115,14 +114,13 @@ export default {
flex-direction: column; flex-direction: column;
position: absolute; position: absolute;
width: 420px; width: 420px;
height: 85%; height: 100%;
left: 0; left: 0;
top: 60px; top: 0;
// height: 86vh; // height: 86vh;
z-index: 99; z-index: 99;
transition: 0.3s; transition: 0.3s;
background: #222222; background: #222222;
border-radius: 5px 5px 0px 0px;
// border: 1px solid #70daf9; // border: 1px solid #70daf9;
.uav-list_btn { .uav-list_btn {
position: absolute; position: absolute;
...@@ -153,44 +151,26 @@ export default { ...@@ -153,44 +151,26 @@ export default {
display: flex; display: flex;
align-items: center; align-items: center;
width: 100%; width: 100%;
height: 33px; height: 54px;
background: #3c3c3c; padding: 0 16px;
border-radius: 5px 5px 0px 0px;
.uav-list-header__text { .uav-list-header__text {
font-size: 20px; font-family: PingFangSC, PingFang SC;
font-family: YouSheBiaoTiHei; font-weight: 600;
color: #14faff; font-size: 16px;
line-height: 26px; color: #ffffff;
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;
} }
} }
::v-deep .uav-search { .uav-search::v-deep {
flex-shrink: 0; flex-shrink: 0;
padding: 0 24px; padding: 0 16px;
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
align-items: center; align-items: center;
// margin-bottom: 7px;
margin-top: 14px;
.uav-search__input { .uav-search__input {
width: 317px; width: 292px;
height: 32px; height: 32px;
border-radius: 4px; border-radius: 4px;
...@@ -219,11 +199,11 @@ export default { ...@@ -219,11 +199,11 @@ export default {
display: flex; display: flex;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
width: 79px; width: 80px;
height: 32px; height: 32px;
font-size: 14px; font-size: 14px;
color: #fff; color: #fff;
border-radius: 4px; border-radius: 2px;
border: 0; border: 0;
background: #3388ff; background: #3388ff;
} }
......
...@@ -5,8 +5,6 @@ ...@@ -5,8 +5,6 @@
class="player" class="player"
ref="player" ref="player"
v-if="showPlayer && uav" v-if="showPlayer && uav"
:device="uav"
:mountDatas="selectMount"
@close="onPlayerClose" @close="onPlayerClose"
/> />
<ControlPanel v-if="uav && showPanel"></ControlPanel> <ControlPanel v-if="uav && showPanel"></ControlPanel>
...@@ -43,7 +41,6 @@ export default { ...@@ -43,7 +41,6 @@ export default {
"uav", "uav",
"showPlayer", "showPlayer",
"showPanel", "showPanel",
"selectMount"
]), ]),
}, },
created() { created() {
......
...@@ -101,6 +101,10 @@ export default { ...@@ -101,6 +101,10 @@ export default {
key: "mqttUrl", key: "mqttUrl",
value: newVal.mqttUrl, value: newVal.mqttUrl,
}); });
this.$store.commit("MMCFlightControlCenter/setState", {
key: "mqttUrlHangar",
value: newVal.mqttUrlHangar
})
}, },
}, },
useSTLAirway: { useSTLAirway: {
......
import moment from "moment"; import moment from "moment";
import { TaskInfo } from "../api"; import { TaskInfo } from "../api";
let hangarRealTimeData = { function initHangarRealTimeData(){
return {
chargerPower: 0, //充电电源,0-未知,1-打开,2-关闭 chargerPower: 0, //充电电源,0-未知,1-打开,2-关闭
cover: 0, //舱盖,0-未知,1-关闭,2-打开,3-正在关闭,4-正在打开 cover: 0, //舱盖,0-未知,1-关闭,2-打开,3-正在关闭,4-正在打开
driverPower: 0, // 伺服电源,0-未知,1-打开,2-关闭 driverPower: 0, // 伺服电源,0-未知,1-打开,2-关闭
...@@ -42,12 +43,13 @@ let hangarRealTimeData = { ...@@ -42,12 +43,13 @@ let hangarRealTimeData = {
windDirection: 0, // 风向,单位:deg windDirection: 0, // 风向,单位:deg
windSpeed: 0, // 风速,单位 m/s windSpeed: 0, // 风速,单位 m/s
}, },
}; };
}
const state = { const state = {
hangar: null, // 选择中的机库信息 hangar: null, // 选择中的机库信息
showPanel: false, //显示数据面板 showPanel: false, //显示数据面板
hangarRealTimeData, // 实时数据 hangarRealTimeData: initHangarRealTimeData(), // 实时数据
airlineData: null, //航线数据 airlineData: null, //航线数据
}; };
...@@ -79,7 +81,9 @@ const actions = { ...@@ -79,7 +81,9 @@ const actions = {
if (type2063) { if (type2063) {
type2063.timestamp = data[2063].timestamp; type2063.timestamp = data[2063].timestamp;
let findMsg = msgList.find((item) => item.timestamp === type2063.timestamp); let findMsg = msgList.find(
(item) => item.timestamp === type2063.timestamp
);
if (!findMsg) { if (!findMsg) {
msgList.push({ msgList.push({
...type2063, ...type2063,
...@@ -87,13 +91,13 @@ const actions = { ...@@ -87,13 +91,13 @@ const actions = {
}); });
} }
} }
if(type3){ if (type3) {
let findMsg = msgList.find((item) => item.$time === type3.$time); let findMsg = msgList.find((item) => item.$time === type3.$time);
if (!findMsg) { if (!findMsg) {
msgList.push({ msgList.push({
...type3, ...type3,
time: moment(type3.$time).format("YYYY-MM-DD HH:mm:ss"), time: moment(type3.$time).format("YYYY-MM-DD HH:mm:ss"),
text: type3.body text: type3.body,
}); });
} }
} }
...@@ -126,7 +130,10 @@ const actions = { ...@@ -126,7 +130,10 @@ const actions = {
topic: "PROCESS/RECEIVE/" + state.hangar.deviceId, topic: "PROCESS/RECEIVE/" + state.hangar.deviceId,
callback(ok) { callback(ok) {
ok && ok &&
console.log("mqtt订阅主题", "PROCESS/RECEIVE/" + state.hangar.deviceId); console.log(
"mqtt订阅主题",
"PROCESS/RECEIVE/" + state.hangar.deviceId
);
}, },
}); });
}, },
...@@ -167,7 +174,7 @@ const actions = { ...@@ -167,7 +174,7 @@ const actions = {
commit("setState", { key: "hangar", value: null }); commit("setState", { key: "hangar", value: null });
commit("setState", { commit("setState", {
key: "hangarRealTimeData", key: "hangarRealTimeData",
value: hangarRealTimeData, value: initHangarRealTimeData(),
}); });
}, },
/** /**
...@@ -283,6 +290,45 @@ const actions = { ...@@ -283,6 +290,45 @@ const actions = {
}, },
}); });
}, },
/**
* 一键起飞
* @param {function} data.callback //完成回调
*/
async takeOff({ state }, data) {
console.log(state.airlineData, data);
try {
// 生成架次号
const flightSortieId = await TaskInfo.flightSortieId({
id: state.hangar.uav.deviceId,
});
/* const flightSortieId = {
data: `tmj-v4-${Date.now()}`
} */
// 上传航线指令
const waypointList = state.airlineData?.content;
window.$mmc.$store.dispatch("MMCMQTT/publish", {
topic: "PROCESS/OBTAIN/" + state.hangar.deviceId,
data: {
cmdControlType: 100004,
uavDeviceId: state.hangar.uav.deviceId, //无人机id
wayLineObj: {
taskId: state.airlineData.id,
flightSortiesID: flightSortieId.data,
waypointList: waypointList,
autoFlightSpeed: state.airlineData.baseSpeed || 6,
finishedAction: "GO_HOME",
headingMode: "AUTO",
isExitMissionOnRCSignalLostEnabled: true,
maxFlightSpeed: 12,
},
},
callback() {},
});
} catch (e) {
console.log("一键起飞失败", e);
data?.callback && data.callback(false);
}
},
}; };
export default { export default {
......
...@@ -37,7 +37,8 @@ export default { ...@@ -37,7 +37,8 @@ export default {
useAirway: true, //使用航线而不使用任务起飞 useAirway: true, //使用航线而不使用任务起飞
baseUrl: '', //api请求的base url baseUrl: '', //api请求的base url
wsUrl: '', //websocket的url wsUrl: '', //websocket的url
mqttUrl: '' //mqtt的url mqttUrl: '', //无人机的mqtt地址
mqttUrlHangar: '', //机库的mqtt地址
}, },
mutations: { mutations: {
/** /**
......
...@@ -16,7 +16,8 @@ const defaultPos = { ...@@ -16,7 +16,8 @@ const defaultPos = {
longitude: 0, // 经度 longitude: 0, // 经度
}; };
const uavRealTimeData = { function initUavRealTimeData() {
return {
attitude: { attitude: {
roll: 0, // 飞机的俯仰值:向前为正,向后为负。单位为度。 roll: 0, // 飞机的俯仰值:向前为正,向后为负。单位为度。
pitch: 0, // 飞机的横滚值:正向为正,反向为负。单位为度。 pitch: 0, // 飞机的横滚值:正向为正,反向为负。单位为度。
...@@ -171,13 +172,14 @@ const uavRealTimeData = { ...@@ -171,13 +172,14 @@ const uavRealTimeData = {
up45Link 4/5G上行速率,单位字节/秒 Long up45Link 4/5G上行速率,单位字节/秒 Long
down45Link 4/5G下行速率,单位字节/秒 Long down45Link 4/5G下行速率,单位字节/秒 Long
} */ } */
flightMode: 'UNKNOWN' flightMode: "UNKNOWN",
}; };
}
const state = { const state = {
openTest: false, // 开启测试 openTest: false, // 开启测试
uav: null, // 选择中的无人机信息 uav: null, // 选择中的无人机信息
uavRealTimeData, uavRealTimeData: initUavRealTimeData(),
airlineEntity: null, // 航线实例 airlineEntity: null, // 航线实例
uavModelEntity: null, // 飞机模型实例 uavModelEntity: null, // 飞机模型实例
smuTime: false, // 模拟上报定时器 smuTime: false, // 模拟上报定时器
...@@ -229,7 +231,7 @@ const actions = { ...@@ -229,7 +231,7 @@ const actions = {
commit("setState", { key: "mountList", value: [] }); commit("setState", { key: "mountList", value: [] });
commit("setState", { key: "selectMount", value: null }); commit("setState", { key: "selectMount", value: null });
commit("setState", { key: "showVideo", value: false }); commit("setState", { key: "showVideo", value: false });
commit("setState", { key: "uavRealTimeData", value: uavRealTimeData }); commit("setState", { key: "uavRealTimeData", value: initUavRealTimeData() });
positions = []; positions = [];
}, },
...@@ -294,7 +296,8 @@ const actions = { ...@@ -294,7 +296,8 @@ const actions = {
const type2017 = data[2017]?.data; const type2017 = data[2017]?.data;
const type272 = data[272]?.data; // 避障信息 const type272 = data[272]?.data; // 避障信息
const type275 = data[275]?.data; // 健康管理 const type275 = data[275]?.data; // 健康管理
const type270 = data[270]?.data; //飞控应答消息 const type270 = data[270]?.data; // 飞控应答消息
const type260 = data[260]?.data; // 无人机提示信息
let msgList = state.uavRealTimeData.msgList || []; let msgList = state.uavRealTimeData.msgList || [];
...@@ -305,8 +308,24 @@ const actions = { ...@@ -305,8 +308,24 @@ const actions = {
); );
if (!findMsg) { if (!findMsg) {
msgList.push({ msgList.push({
...type270, grade: 'AUTO',
text: type270.text,
time: moment(type270.timestamp).format("YYYY-MM-DD HH:mm:ss"), time: moment(type270.timestamp).format("YYYY-MM-DD HH:mm:ss"),
timestamp: type270.timestamp
});
}
}
if (type260) {
type260.timestamp = data[260].timestamp;
let findMsg = msgList.find(
(item) => item.timestamp === type260.timestamp
);
if (!findMsg) {
msgList.push({
grade: type260.grade <= 2 ? "[危险]" : type260.grade == 3 ? "[错误]" : type260.grade ==4 ? "[警告]" : type260.grade == 5 ? "[通知]" : type260.grade == 6 ? "[正常]" : type260.grade == 7 ? "[调试]" : "AUTO",
text: type260.msg,
time: moment(type260.timestamp).format("YYYY-MM-DD HH:mm:ss"),
timestamp: type260.timestamp
}); });
} }
} }
...@@ -640,7 +659,7 @@ const actions = { ...@@ -640,7 +659,7 @@ const actions = {
taskId: state.airlineData.id, taskId: state.airlineData.id,
flightSortiesID: flightSortieId.data, flightSortiesID: flightSortieId.data,
waypointList: waypointList, waypointList: waypointList,
autoFlightSpeed: state.airlineData.baseSpeed, autoFlightSpeed: state.airlineData.baseSpeed || 6,
finishedAction: "GO_HOME", finishedAction: "GO_HOME",
headingMode: "AUTO", headingMode: "AUTO",
isExitMissionOnRCSignalLostEnabled: true, isExitMissionOnRCSignalLostEnabled: true,
...@@ -894,7 +913,7 @@ const actions = { ...@@ -894,7 +913,7 @@ const actions = {
* @param {number} data.id 模式id * @param {number} data.id 模式id
* @param {function} data.callback * @param {function} data.callback
*/ */
modeChange({ state }, data){ modeChange({ state }, data) {
if (state.uav.network == 2) { if (state.uav.network == 2) {
window.$mmc.$store.dispatch("MMCMQTT/publish", { window.$mmc.$store.dispatch("MMCMQTT/publish", {
topic: "PX4/OBTAIN/" + state.uav.deviceId, topic: "PX4/OBTAIN/" + state.uav.deviceId,
...@@ -1246,7 +1265,7 @@ const actions = { ...@@ -1246,7 +1265,7 @@ const actions = {
topic: "PX4/OBTAIN/" + state.uav.deviceId, topic: "PX4/OBTAIN/" + state.uav.deviceId,
data: { data: {
type: window.$mmc.$store.state.MMCMQTT.orders.链路切换, type: window.$mmc.$store.state.MMCMQTT.orders.链路切换,
data data,
}, },
callback() {}, callback() {},
}); });
......
This source diff could not be displayed because it is too large. You can view the blob instead.
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论