提交 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 @@
"@liveqing/liveplayer": "^2.7.10",
"axios": "^1.3.4",
"dayjs": "^1.11.7",
"downloadjs": "^1.4.7",
"echarts": "^4.9.0",
"element-ui": "^2.15.6",
"file-saver": "^2.0.5",
"global": "^4.4.0",
"html2canvas": "^1.4.1",
"interactjs": "^1.10.17",
"jquery": "^3.7.1",
"jspack": "^0.0.4",
......
......@@ -106,14 +106,13 @@ export default {
box-sizing: border-box;
display: flex;
flex-direction: column;
gap: 20px;
gap: 5px;
justify-content: center;
.battery-inner {
display: flex;
align-items: center;
position: relative;
margin: -38px 0px;
.dec {
flex-shrink: 0;
......@@ -174,7 +173,7 @@ export default {
}
.size-wrap {
width: 68px;
width: 55px;
height: 25px;
flex-shrink: 0;
position: relative;
......
......@@ -156,10 +156,10 @@ export default {
*/
async onStartTask() {
// 判断是否已接管
if (!(await this.isTakeOver())) {
/* if (!(await this.isTakeOver())) {
this.$message.warning("请先接管无人机");
return;
}
} */
// 判断是否选择了航线
if (this.selectedAirway.id === -1) {
......@@ -173,11 +173,11 @@ export default {
customClass: "uav_controlPane",
showClose: false,
});
this.$store.commit("MMCFlightControlCenter/uav/setState", {
this.$store.commit("MMCFlightControlCenter/hangar/setState", {
key: "airlineData",
value: this.selectedAirway,
});
this.$store.dispatch("MMCFlightControlCenter/uav/takeOff", {
this.$store.dispatch("MMCFlightControlCenter/hangar/takeOff", {
callback: (status) => {
if (status) {
this.$message.success("一键任务指令发送成功");
......
<template>
<div class="task-list">
<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>
</div>
<template v-if="useTimedTask">
......@@ -97,13 +101,13 @@ export default {
text-shadow: 0px 1px 1px rgba(2, 32, 56, 0.2);
text-align: left;
font-style: normal;
background: linear-gradient(
background-image: -webkit-linear-gradient(
right,
#e3aa77,
#f5cda9,
#f9ecd3,
#fcdbb1,
#edb07a
#e3aa77,
#f5cda9,
#f9ecd3,
#fcdbb1,
#edb07a
);
line-height: 32px;
-webkit-background-clip: text;
......
......@@ -9,7 +9,8 @@
<span class="label">{{ label }}</span>
<!-- <div class="el-icon-close close" @click="close"></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>
</div>
</div>
......@@ -46,6 +47,7 @@ export default {
data() {
return {
isFullScreen: false, //是否全屏
showPlayer: true,
};
},
computed: {
......@@ -152,6 +154,13 @@ export default {
font-size: 12px;
}
}
.video-reset {
position: absolute;
right: 5px;
bottom: 5px;
color: #fff;
}
}
@keyframes scrollTitle {
......
......@@ -82,6 +82,13 @@ export default {
return streamOptions;
},
},
watch: {
streamOptions(){
if(this.streamOptions.length > 0){
this.selectUrl = this.streamOptions[0].url;
}
}
},
mounted() {
this.selectUrl = this.streamOptions[0]?.url || "";
},
......
......@@ -189,11 +189,11 @@ export default {
});
// 当前机库状态是否空闲
if ([0, 8].includes(this.hangarRealTimeData.processStatus)) {
this.$store.commit("MMCFlightControlCenter/uav/setState", {
this.$store.commit("MMCFlightControlCenter/hangar/setState", {
key: "airlineData",
value: this.selectedAirway,
});
this.$store.dispatch("MMCFlightControlCenter/uav/takeOff", {
this.$store.dispatch("MMCFlightControlCenter/hangar/takeOff", {
uav: this.uav,
callback: (status) => {
if (status) {
......
<template>
<div class="task-list">
<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>
</div>
<template v-if="useTimedTask">
......@@ -97,13 +101,13 @@ export default {
text-shadow: 0px 1px 1px rgba(2, 32, 56, 0.2);
text-align: left;
font-style: normal;
background: linear-gradient(
background-image: -webkit-linear-gradient(
right,
#e3aa77,
#f5cda9,
#f9ecd3,
#fcdbb1,
#edb07a
#e3aa77,
#f5cda9,
#f9ecd3,
#fcdbb1,
#edb07a
);
line-height: 32px;
-webkit-background-clip: text;
......
......@@ -33,7 +33,7 @@
<span class="line" :class="!productType ? 'w62' : 'w22'"></span>
<span class="w10 mr4 h10 radius"></span>释放无人机
</div>
<div class="default" :class="rktFn(uavMsg)">
<div class="default" :class="rktFn(hangarRealTimeData.msg)">
<span class="line" :class="!productType ? 'w62' : 'w22'"></span>
<span class="w10 mr4 h10 radius"></span>无人机RTK定位
</div>
......@@ -50,7 +50,7 @@
<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-else-if="item.type == 8">普通</span>
<span class="type" v-else>未知</span>
<span class="type" v-else>AUTO</span>
</div>
<div class="text">{{ item.text }}</div>
<div class="time">{{ item.time }}</div>
......@@ -89,7 +89,10 @@ export default {
},
},
computed: {
...mapState("MMCFlightControlCenter/hangar", ["hangar", "hangarRealTimeData"]),
...mapState("MMCFlightControlCenter/hangar", [
"hangar",
"hangarRealTimeData",
]),
...mapState("MMCFlightControlCenter/uav", ["uavRealTimeData"]),
hangarMsgList() {
return this.hangarRealTimeData.msgList.slice().reverse();
......@@ -254,29 +257,19 @@ export default {
},
rktFn(data) {
if (this.productType) {
if (data.code == 1000 && this.folder == 2 && this.lifts == 2) {
if (
data?.locationCoordinate3D?.latitude !== 0 &&
this.folder == 2 &&
this.lifts == 2
) {
return "end";
} else if (this.folder == 2 && this.lifts == 2) {
if (data.code != 1000) {
return "current";
} else {
return "end";
}
} else {
return "default";
}
return "default";
} else {
if (data.code == 1000 && this.folder == 2) {
if (data?.locationCoordinate3D?.latitude !== 0 && this.folder == 2) {
return "end";
} else if (this.folder == 2) {
if (data.code != 1000) {
return "current";
} else {
return "end";
}
} else {
return "default";
}
return "default";
}
},
},
......@@ -329,11 +322,12 @@ export default {
border-top: 0.2px dashed #afdcff;
}
&.end {
color: #3388FF;
&.end,
.current {
color: #3388ff;
.radius {
background: #3388FF;
background: #3388ff;
border: 0;
}
}
......@@ -354,7 +348,7 @@ export default {
.font {
font-size: 20px;
font-family: YouSheBiaoTiHei;
color: #ACACAC;
color: #acacac;
line-height: 26px;
text-shadow: 0px 1px 1px rgba(2, 32, 56, 0.2);
background: linear-gradient(
......@@ -385,14 +379,14 @@ export default {
.iconfont {
font-size: 18px;
color: #3388FF;
color: #3388ff;
margin-right: 4px;
}
.icon-text {
font-family: MicrosoftYaHeiUI;
font-size: 14px;
color: #ACACAC;
color: #acacac;
font-weight: 400;
}
}
......@@ -519,7 +513,7 @@ export default {
transform: rotate(270deg) !important;
}
.close {
color: #ACACAC;
color: #acacac;
cursor: pointer;
margin: 0 10px 0 20px;
}
......
......@@ -59,7 +59,7 @@
<div class="icon-box">
<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>
......@@ -85,10 +85,12 @@ export default {
},
inject: ["rootNode"],
data() {
return {};
return {
locationEntity: null
};
},
computed: {
...mapState("MMCFlightControlCenter", ["listCollapse"]),
...mapState("MMCFlightControlCenter", ["listCollapse", "cesiumViewer"]),
...mapState("MMCFlightControlCenter/hangar", ["showPanel", "hangar"]),
...mapState("MMCFlightControlCenter/uav", ["uav"]),
},
......@@ -114,6 +116,7 @@ export default {
}
return name;
},
// 机库选中
handClick(isCheck, device) {
console.log("checkbox", isCheck, device);
device.isCheck = isCheck;
......@@ -199,6 +202,38 @@ export default {
}
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>
......
......@@ -2,7 +2,7 @@
<template>
<div class="list" :class="{ collapse: listCollapse }">
<div class="list-header">
<span class="list-header__text">机库列表</span>
<span class="list-header__text">鹰巢列表</span>
<div class="list-header__count">
{{ count.sumCount }}架 /
<span class="online">{{ count.onlineCount }}在线</span>
......@@ -10,14 +10,26 @@
{{ count.offlineCount }}离线
</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="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>
<template v-if="list && list.length">
<Item v-for="item in list" :key="item.id" :data="item" />
</template>
</div>
<!-- 未进入机库或者进入机库后列表是展开的情况下,才显示收纳按钮 -->
<div
......@@ -35,6 +47,7 @@
import { Control_API } from "../../../../api";
import Item from "./components/item";
import { mapState } from "vuex";
import mock from './mock';
export default {
name: "List",
......@@ -42,9 +55,10 @@ export default {
components: { Item },
data() {
return {
list: [],
list: mock/* [] */,
deviceType: 2, // 设备类型 2鹰巢
timeHandle: null,
searchContent: '',
};
},
......@@ -91,11 +105,17 @@ export default {
methods: {
async getList() {
let res = await Control_API.getUavTree({
name: "",
serchKey: this.searchContent,
deviceType: this.deviceType,
});
this.list = res.data;
},
/**
* 无人机搜索
*/
onUavSearch() {
this.getList();
},
},
};
</script>
......@@ -106,14 +126,14 @@ export default {
flex-direction: column;
position: absolute;
width: 420px;
height: 85%;
height: 100%;
left: 0;
top: 60px;
top: 0;
// height: 86vh;
z-index: 99;
transition: 0.3s;
border-radius: 5px 5px 0px 0px;
overflow: visible;
background: #222222;
&.collapse {
transform: translateX(-100%);
......@@ -146,102 +166,83 @@ export default {
border-bottom: 9px solid #fff;
}
}
}
.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: 1;
flex-direction: column;
background: #222222;
overflow-y: auto;
.search-box {
.uav-search::v-deep {
flex-shrink: 0;
padding: 0 16px;
display: flex;
height: 36px;
padding: 0 10px;
background: #000000;
border: 1px solid #3dcdff;
border-radius: 2px;
box-sizing: border-box;
justify-content: space-between;
align-items: center;
::v-deep .el-input {
height: 36px;
.uav-search__input {
width: 292px;
height: 32px;
border-radius: 4px;
input {
height: 36px;
background-color: transparent;
border: none;
padding: 0;
.el-input__icon {
line-height: 32px;
color: #a8abb2 !important;
}
font-family: Microsoft YaHei;
font-size: 16px;
color: #08c2d1;
input {
height: 32px;
background: #191919;
font-family: PingFangSC, PingFang SC;
font-weight: 400;
}
font-size: 12px;
color: #fff;
border: 1px solid #4b4b4b;
.el-input__suffix {
display: flex;
align-items: center;
&::placeholder {
font-size: 12px;
color: #a8abb2;
}
}
}
.search-icon-box {
.uav-search__btn {
display: flex;
justify-content: center;
align-items: center;
cursor: pointer;
width: 80px;
height: 32px;
font-size: 14px;
color: #fff;
border-radius: 2px;
border: 0;
background: #3388ff;
}
}
}
.cpt-observe-nest-list {
display: flex;
flex: 1;
flex-direction: column;
overflow-y: auto;
padding: 0 16px;
.iconfont {
font-size: 24px;
color: #08ffff;
}
/* 滚动条整体样式 */
&::-webkit-scrollbar {
width: 10px; /* 滚动条宽度 */
}
&:hover {
.iconfont {
opacity: 0.8;
}
}
}
/* 滚动条滑块样式 */
&::-webkit-scrollbar-thumb {
background-color: #02173d; /* 滑块颜色 */
}
.ctx-box {
flex: 1;
overflow: auto;
height: 100%;
/* backdrop-filter: blur(3px); */
position: relative;
top: 0px;
/* 滚动条滑块悬停样式 */
&::-webkit-scrollbar-thumb:hover {
background-color: #112d5b; /* 悬停时滑块颜色 */
}
&::-webkit-scrollbar-track-piece {
/* background-color: #182F5C; */
}
&::-webkit-scrollbar-track {
background-color: #182f5c;
}
}
.jianj {
display: flex;
align-items: center;
height: 100%;
}
.jl {
margin: 0 0 0 5px;
color: #70daf9 !important;
font-weight: 700 !important;
}
.list-header {
box-sizing: border-box;
......@@ -249,23 +250,16 @@ export default {
justify-content: space-between;
align-items: center;
// width: 100%;
height: 33px;
background: #3c3c3c;
height: 54px;
padding: 0 16px;
.list-header__text {
vertical-align: bottom;
font-family: PingFangSC, PingFang SC;
font-weight: 600;
font-size: 16px;
color: #ffffff;
}
.list-header__icon {
width: 26px;
margin-left: 9px;
}
.list-header__count {
color: #fff;
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 {
computed: {
...mapState("MMCFlightControlCenter/hangar", ["hangar"]),
...mapState("MMCFlightControlCenter/uav", ["uav"]),
...mapState("MMCFlightControlCenter", ['mqttUrlHangar']),
// mqtt实时数据
mqttDataSetHangar() {
return this.$store.state.MMCMQTT?.dataSet?.[this.hangar?.deviceId];
......@@ -12,9 +13,6 @@ export default {
mqttDataSetUav() {
return this.$store.state.MMCMQTT?.dataSet?.[this.uav?.deviceId];
},
mqttUrl() {
return this.$store.state.MMCFlightControlCenter.mqttUrl;
},
},
watch: {
mqttDataSetHangar(newVal) {
......@@ -36,7 +34,7 @@ export default {
try {
this.$store
.dispatch("MMCMQTT/init", {
url: this.mqttUrl,
url: this.mqttUrlHangar,
})
.then(() => {
console.log("mqtt连接成功");
......
......@@ -221,6 +221,7 @@ export default {
return ret;
});
console.log('提交的动作', actions);
return {
altitude: val.altitude,
coordinate: {
......
......@@ -13,14 +13,14 @@
</div>
<div class="ctx-box dialog-content">
<div class="head mt7">
<div class="text">CODE</div>
<div class="text">消息等级</div>
<div class="text con">消息内容</div>
<div class="time">时间</div>
</div>
<div class="list-box mt7">
<div class="item-box" v-for="(item,index) in msgList" :key="index">
<div class="text-box">
<span class="code">{{ item.code }}</span>
<span class="grade">{{ item.grade }}</span>
<div class="text">{{ item.text }}</div>
<div class="time">{{ item.time }}</div>
</div>
......@@ -143,6 +143,11 @@ export default {
display: flex;
flex-direction: column;
padding: 0 16px;
width: 100%;
&.dialog-content {
flex-wrap: initial;
}
.head {
display: flex;
justify-content: space-between;
......@@ -153,6 +158,7 @@ export default {
letter-spacing: 1px;
line-height: 22px;
font-weight: 700;
width: 100%;
.text,
.time {
width: 20%;
......@@ -181,7 +187,7 @@ export default {
justify-content: space-between;
align-items: center;
.code {
.grade {
width: 20%;
height: 20px;
text-align: center;
......
......@@ -37,8 +37,34 @@
<a href="http://32.128.6.52:4500/11.11平台部署/ChromeStandaloneSetup64.exe">下载最新谷歌</a>
</p>-->
<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
v-else
class="infinite-list"
v-infinite-scroll="onLoadList"
style="overflow:auto"
......@@ -46,24 +72,29 @@
:infinite-scroll-disabled="noMore"
>
<li v-for="item in photoList" class="infinite-list-item">
<div class="list-item-date">
<div>{{item.date}}</div>
</div>
<div class="list-item-imgs">
<MMCImage
class="list-item__img"
v-for="(img, i) in item.imgList"
: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>
</div>
<template v-if="item.imgList.length > 0">
<div class="list-item-date">
<div>{{item.date}}</div>
<el-button type="text" size="small" @click="photoListDate = [item]">更多></el-button>
</div>
<div class="list-item-imgs">
<template v-for="(img, i) in item.imgList">
<MMCImage
v-if="i < 3"
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>
</div>
......@@ -85,12 +116,15 @@ import {
} from "../../../../../../../../api";
import { mapState } from "vuex";
import MMCImage from "../../../../../../../../components/image";
import mock from "./mock";
import download from 'downloadjs';
export default {
name: "ViewLib",
components: {
MMCImage,
},
inject: ["rootNode"],
data() {
return {
checkList: [], // 多选结果
......@@ -160,28 +194,30 @@ export default {
// value: "车牌识别",
// },
], //视图库类型
fileType: '图片', //视图文件类型 0:图片;1:视频
fileType: "图片", //视图文件类型 0:图片;1:视频
fileType2: 0, //机载文件类型
photoList: [], //资源列表
photoList: mock /* [] */, //资源列表
photoListDate: null, //某日期的所有资源
moreShow: false, //显示更多,
page: {
pageNo: 0,
pageSize: 10,
},
noMore: false, //是否没有更多数据了
};
},
computed: {
...mapState("MMCFlightControlCenter/uav", ["uav"]),
...mapState("MMCFlightControlCenter", ["baseUrl"])
...mapState("MMCFlightControlCenter", ["baseUrl"]),
},
watch: {
fileType(){
fileType() {
this.init();
}
},
},
mounted() {
this.init();
// this.init();
},
methods: {
async init() {
......@@ -193,7 +229,7 @@ export default {
async getPage() {
let res = await ViewLibrary.page({
...this.page,
fileType: this.fileType === '图片' ? 0 : 1,
fileType: this.fileType === "图片" ? 0 : 1,
deviceId: this.uav.deviceId,
type: parseInt(this.viewLibTab),
});
......@@ -202,9 +238,16 @@ export default {
this.noMore = true;
} else {
photoList.forEach((item) => {
item.imgList = item.viewLibraryRespVOS.map((item1) => {
return this.aiType == 1 ? `${this.baseUrl}${item1.fileUrl}` : `${this.baseUrl}${item1.aiImageUrl}`;
});
item.imgList = item.viewLibraryRespVOS
.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);
}
......@@ -236,7 +279,7 @@ export default {
this.init();
},
onDownload(url) {
window.open(url, "_self");
download(url);
},
/**
* 加载下一页数据
......@@ -444,6 +487,8 @@ export default {
color: #878787;
line-height: 22px;
margin-bottom: 6px;
display: flex;
justify-content: space-between;
}
.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 {
}, */
];
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":
/* {
// 用的百度
......@@ -137,8 +161,7 @@ export default {
}
}
break; */
// 车牌识别
case "plate":
// 漏油识别结果
case "oilLeak":
{
......@@ -235,29 +258,12 @@ export default {
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) {
console("识别结果", results);
console.log("识别结果", results);
this.$message.success("识别成功");
// 将识别结果绘制到图片上
let img = new Image();
img.onload = () => {
img.onload = async () => {
let width = img.width;
let height = img.height;
console.log("图片宽度:", width, "高度:", height);
......@@ -269,6 +275,32 @@ export default {
this.aiResultImg = canvas.toDataURL("image/svg");
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 = testImg;
......@@ -307,7 +339,7 @@ export default {
ctx.textAlign = "left";
// 绘制文字
ctx.fillText(
`${item.label}: ${item.prob}(相似度)`,
`${item.label}${item.prob ? ": " + item.prob + "(相似度)" : ""}`,
item.x,
item.y - 20,
250
......
......@@ -5,7 +5,7 @@
<div class="cpt_video" @click="lensControl" v-if="showPlayer">
<Obstacle v-if="!isStatus"></Obstacle>
<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="types">{{ streamName }}</div> -->
<div v-show="!isStatus" class="close" @click="close()">关闭</div>
......@@ -28,11 +28,11 @@
:LivePlayerInfor="false"
:fpvUrl="fpvUrl"
:data="vUrl"
:device="device"
:device="uav"
:controls="false"
:className="'fkLivePlayer'"
:infoflag="infoflag"
:deviceName="device.name"
:deviceName="uav.name"
:raw_msg="raw_msg"
:isInfoShow="isInfoShow"
@close="infoflag = false"
......@@ -314,7 +314,7 @@
</div>
<div class="right-menu">
<template v-if="device.network === 2">
<template v-if="uav.network === 2">
<el-tooltip content="拍照" placement="bottom">
<div class="menu-item plate" @click="photojz">
<img src="./assets/images/ai.png" />
......@@ -344,26 +344,25 @@
</div>
<PointList
:uavRealTimeData="uavRealTimeData"
:mountData="mountDatas"
:mountData="selectMount"
v-if="showFlywayAction"
@close="showFlywayAction = false"
@dblclick.native.stop
></PointList>
</div>
<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" />
<carTraffic
v-if="cartrafficShow"
:trafficData="cartrafficData"
@close="cartrafficShow = false"
/>
</div>
</template>
<script>
import { Control_API } from "../../../../api";
import { ViewLibrary } from "../../../../api";
import dayjs from "dayjs";
import FaceAI from "./components/faceai";
import CarAI from "./components/carai";
......@@ -380,7 +379,7 @@ import PointList from "./components/pointList";
import videoModelChange from "./components/videoModelChange";
import fkutils from "./methods/utils";
import { mapState } from "vuex";
import AiList from './components/aiList';
import AiList from "./components/aiList";
export default {
name: "Player",
......@@ -395,23 +394,10 @@ export default {
Obstacle,
SRSPlayer,
videoModelChange,
AiList
AiList,
},
inject: ["bus"],
props: {
mountDatas: {
type: Object,
default: () => ({}),
},
NXdata: {
type: Object,
default: () => {},
},
device: {
type: Object,
default: () => ({}),
},
},
props: {},
data() {
return {
backgroundStyle: {
......@@ -471,11 +457,11 @@ export default {
openOSD: true, // 是否开启OSD
showFlywayAction: false, //显示航点动作
showContinueFly: false, //显示继续飞行对话框
continueFlyContent: '', //继续飞行对话框内容
continueFlyContent: "", //继续飞行对话框内容
};
},
computed: {
...mapState("MMCFlightControlCenter/uav", ["uav"]),
...mapState("MMCFlightControlCenter/uav", ["uav", "selectMount"]),
/**
* 播放器组件名
*/
......@@ -507,7 +493,7 @@ export default {
* @returns 专网 | 公网
*/
networkType() {
// console.log('网络判断', this.device.videos)
// console.log('网络判断', this.uav.videos)
let name = "公网";
return name;
......@@ -521,7 +507,7 @@ export default {
*/
streamOptions() {
let streamOptions = [];
let streamConfiguration = this.device?.streamConfiguration.find(
let streamConfiguration = this.uav?.streamConfiguration.find(
(item) => item.urlType === 0
);
......@@ -681,22 +667,12 @@ export default {
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() {
this.showCenter = !this.showCenter;
},
async VideoModelChange() {
let res = await API.FCKERNEL.checkUseOperate({
deviceId: this.device.deviceId,
deviceId: this.uav.deviceId,
});
if (res.code == 201) {
this.$message.warning(res.msg);
......@@ -753,11 +729,11 @@ export default {
},
//车流密度
async carFrame() {
this.carFlow(this.device.deviceId);
this.carFlow(this.uav.deviceId);
},
//人流密度
async frame() {
this.flow(this.device.deviceId);
this.flow(this.uav.deviceId);
},
/**
* 截图
......@@ -816,38 +792,32 @@ export default {
let blob = this.$refs.player.screenShot();
if (blob) {
console.log(blob, window.URL.createObjectURL(blob));
const data = new FormData();
data.append("addtime", dayjs().format("YYYY-MM-DD HH:mm:ss"));
data.append("file", blob);
data.append("deviceId", this.device.deviceId);
data.append("name", this.device.name);
data.append("imageType", 1);
data.append("sortie", this.flightSortie || "");
if (this.device?.locationCoordinate3D?.longitude) {
data.append(
"longitude",
this.device?.locationCoordinate3D?.longitude
);
data.append("latitude", this.device?.locationCoordinate3D?.latitude);
}
const res = await Control_API.addPhoto(data);
if (res.code === 0) {
this.$message.success("截屏成功");
} else {
this.$message({
type: "error",
message: res.msg || "出错了",
duration: 1000,
let formData = new FormData();
formData.append("file", blob, `截图.jpeg`);
let uploadRes = await ViewLibrary.uploadFile(formData);
if (uploadRes.code === 0) {
let res = await ViewLibrary.create({
fileUrl: uploadRes.data,
fileType: 0,
deviceId: this.uav.deviceId,
});
if (res.code === 0) {
this.$message.success("截屏成功");
} else {
this.$message.error(res.msg || "截屏失败");
}
} else {
this.$message.error(uploadRes.msg || "截屏失败");
}
} else {
this.$message.warning("截屏失败");
return;
}
this.$message.warning("截屏失败");
},
// 人脸车牌识别
handle(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 {
*/
async lensControl(el) {
// let mountData =this.$store.state.device.move_data
let { device, mountData } = this;
let { mountData } = this;
// if mountStatus =1 代表启用 屏幕指点功能
if (
mountData.mountStatus == 1 &&
device.deviceId == mountData.deviceId &&
this.uav.deviceId == mountData.deviceId &&
mountData.moveType == "wrj"
) {
let evt = window.event || el;
......@@ -917,8 +887,8 @@ export default {
}
let mounteList = { data: buffer, ...mountData };
if (buffer) {
if (this.device.network === 2) {
let topic = "PX4/OBTAIN/" + this.device.deviceId;
if (this.uav.network === 2) {
let topic = "PX4/OBTAIN/" + this.uav.deviceId;
this.$store.dispatch("MMCMQTT/publish", {
topic: topic,
data: {
......@@ -953,10 +923,10 @@ export default {
/**
* ai截图事件
*/
onAiScreenShot({callback}){
onAiScreenShot({ callback }) {
let blob = this.$refs.player.screenShot();
callback(blob);
}
},
},
};
</script>
......@@ -1434,8 +1404,6 @@ export default {
> img {
width: 100%;
}
}
}
</style>
<!-- 飞控中心无人机应slot -->
<template>
<div class="h700 list">
<div class="list">
<template v-if="wsList && wsList.length">
<!-- <div class="all">全部</div> -->
<div class="pl10 pb30 pr8">
......
......@@ -4,7 +4,6 @@
<img style src="./assets/images/collapse.svg" />
</div>
<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>
</div>
<div class="uav-search">
......@@ -115,14 +114,13 @@ export default {
flex-direction: column;
position: absolute;
width: 420px;
height: 85%;
height: 100%;
left: 0;
top: 60px;
top: 0;
// height: 86vh;
z-index: 99;
transition: 0.3s;
background: #222222;
border-radius: 5px 5px 0px 0px;
// border: 1px solid #70daf9;
.uav-list_btn {
position: absolute;
......@@ -153,44 +151,26 @@ export default {
display: flex;
align-items: center;
width: 100%;
height: 33px;
background: #3c3c3c;
border-radius: 5px 5px 0px 0px;
height: 54px;
padding: 0 16px;
.uav-list-header__text {
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;
font-family: PingFangSC, PingFang SC;
font-weight: 600;
font-size: 16px;
color: #ffffff;
}
}
::v-deep .uav-search {
.uav-search::v-deep {
flex-shrink: 0;
padding: 0 24px;
padding: 0 16px;
display: flex;
justify-content: space-between;
align-items: center;
// margin-bottom: 7px;
margin-top: 14px;
.uav-search__input {
width: 317px;
width: 292px;
height: 32px;
border-radius: 4px;
......@@ -219,11 +199,11 @@ export default {
display: flex;
justify-content: center;
align-items: center;
width: 79px;
width: 80px;
height: 32px;
font-size: 14px;
color: #fff;
border-radius: 4px;
border-radius: 2px;
border: 0;
background: #3388ff;
}
......
......@@ -5,8 +5,6 @@
class="player"
ref="player"
v-if="showPlayer && uav"
:device="uav"
:mountDatas="selectMount"
@close="onPlayerClose"
/>
<ControlPanel v-if="uav && showPanel"></ControlPanel>
......@@ -43,7 +41,6 @@ export default {
"uav",
"showPlayer",
"showPanel",
"selectMount"
]),
},
created() {
......
......@@ -101,6 +101,10 @@ export default {
key: "mqttUrl",
value: newVal.mqttUrl,
});
this.$store.commit("MMCFlightControlCenter/setState", {
key: "mqttUrlHangar",
value: newVal.mqttUrlHangar
})
},
},
useSTLAirway: {
......
import moment from "moment";
import { TaskInfo } from "../api";
let hangarRealTimeData = {
chargerPower: 0, //充电电源,0-未知,1-打开,2-关闭
cover: 0, //舱盖,0-未知,1-关闭,2-打开,3-正在关闭,4-正在打开
driverPower: 0, // 伺服电源,0-未知,1-打开,2-关闭
folder: 0, // 回中器,0-未知,1-夹紧,2-放松,3-夹紧过程,4-放松过程
hangarHumid: 0, // 停机坪内湿度,单位:%
hangarMode: 0, // 停机坪模式,0-未知,1-正常模式,2-休眠模式
hangarPower: 0, // 停机坪电源,0-未知,1-打开,2-关闭
hangarTemp: 0, // 停机坪内温度,单位:度
inLamp: 0, // 内部灯,0-未知,1-打开,2-关闭
lifts: 0, // 起降台,0-未知,1-降下,2-升起,3-降下过程,4-升起过程
outCameraPower: 0, // 外置摄像头电源,0-未知,1-打开,2-关闭
outLamp: 0, // 外部灯,0-未知,1-打开,2-关闭
processStatus: 0, // 0-空闲 、1-正在执行出仓待命、2-正在执行回收入仓、3-正在执行充电流程 、4-正在结束充电流程、5-正在执行休眠流程、6-正在执行预热流程、7-正在执行初始化、8-未初始化 、9-正在执行关舱流程 、10-正在执行回中器操作、99-正在执行飞行任务
remotePower: 0, // 遥控电源,0-未知,1-打开,2-关闭
rfPower: 0, // 射频电源,0-未知,1-打开,2-关闭
rtkPower: 0, // RTK 基站电源,0-未知,1-打开,2-关闭
videoPower: 0, // 机载视频电源,0-未知,1-打开,2-关闭
waterWarn: 0, // 水浸报警,0-未知,1-报警,2-正常
msg: {
// 2063 飞控应答消息
number: 0, // 包序列号
text: "", // 文本内容
type: 1, // 系统消息数据:2063
},
msgList: [], //飞控应答消息记录
weatherStation: {
// 2066 气象站数据
rain: 0, // 雨量,0-无雨,1-有雨
homeLat: 0, // 停机坪纬度,单位 deg
homeLon: 0, // 停机坪经度,单位 deg
humidity: 0, // 湿度,单位:%
light: 0, // 光照,单位:lux
number: 0, // 包序列号
homesatellite: 0, // 停机坪卫星数
temp: 0, // 温度,单位:C
weatherHumid: 0, // 气象站湿度,单位:%
weatherTemp: 0, // 气象站温度,单位:度
windDirection: 0, // 风向,单位:deg
windSpeed: 0, // 风速,单位 m/s
},
};
function initHangarRealTimeData(){
return {
chargerPower: 0, //充电电源,0-未知,1-打开,2-关闭
cover: 0, //舱盖,0-未知,1-关闭,2-打开,3-正在关闭,4-正在打开
driverPower: 0, // 伺服电源,0-未知,1-打开,2-关闭
folder: 0, // 回中器,0-未知,1-夹紧,2-放松,3-夹紧过程,4-放松过程
hangarHumid: 0, // 停机坪内湿度,单位:%
hangarMode: 0, // 停机坪模式,0-未知,1-正常模式,2-休眠模式
hangarPower: 0, // 停机坪电源,0-未知,1-打开,2-关闭
hangarTemp: 0, // 停机坪内温度,单位:度
inLamp: 0, // 内部灯,0-未知,1-打开,2-关闭
lifts: 0, // 起降台,0-未知,1-降下,2-升起,3-降下过程,4-升起过程
outCameraPower: 0, // 外置摄像头电源,0-未知,1-打开,2-关闭
outLamp: 0, // 外部灯,0-未知,1-打开,2-关闭
processStatus: 0, // 0-空闲 、1-正在执行出仓待命、2-正在执行回收入仓、3-正在执行充电流程 、4-正在结束充电流程、5-正在执行休眠流程、6-正在执行预热流程、7-正在执行初始化、8-未初始化 、9-正在执行关舱流程 、10-正在执行回中器操作、99-正在执行飞行任务
remotePower: 0, // 遥控电源,0-未知,1-打开,2-关闭
rfPower: 0, // 射频电源,0-未知,1-打开,2-关闭
rtkPower: 0, // RTK 基站电源,0-未知,1-打开,2-关闭
videoPower: 0, // 机载视频电源,0-未知,1-打开,2-关闭
waterWarn: 0, // 水浸报警,0-未知,1-报警,2-正常
msg: {
// 2063 飞控应答消息
number: 0, // 包序列号
text: "", // 文本内容
type: 1, // 系统消息数据:2063
},
msgList: [], //飞控应答消息记录
weatherStation: {
// 2066 气象站数据
rain: 0, // 雨量,0-无雨,1-有雨
homeLat: 0, // 停机坪纬度,单位 deg
homeLon: 0, // 停机坪经度,单位 deg
humidity: 0, // 湿度,单位:%
light: 0, // 光照,单位:lux
number: 0, // 包序列号
homesatellite: 0, // 停机坪卫星数
temp: 0, // 温度,单位:C
weatherHumid: 0, // 气象站湿度,单位:%
weatherTemp: 0, // 气象站温度,单位:度
windDirection: 0, // 风向,单位:deg
windSpeed: 0, // 风速,单位 m/s
},
};
}
const state = {
hangar: null, // 选择中的机库信息
showPanel: false, //显示数据面板
hangarRealTimeData, // 实时数据
hangarRealTimeData: initHangarRealTimeData(), // 实时数据
airlineData: null, //航线数据
};
......@@ -79,7 +81,9 @@ const actions = {
if (type2063) {
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) {
msgList.push({
...type2063,
......@@ -87,13 +91,13 @@ const actions = {
});
}
}
if(type3){
if (type3) {
let findMsg = msgList.find((item) => item.$time === type3.$time);
if (!findMsg) {
msgList.push({
...type3,
time: moment(type3.$time).format("YYYY-MM-DD HH:mm:ss"),
text: type3.body
text: type3.body,
});
}
}
......@@ -126,7 +130,10 @@ const actions = {
topic: "PROCESS/RECEIVE/" + state.hangar.deviceId,
callback(ok) {
ok &&
console.log("mqtt订阅主题", "PROCESS/RECEIVE/" + state.hangar.deviceId);
console.log(
"mqtt订阅主题",
"PROCESS/RECEIVE/" + state.hangar.deviceId
);
},
});
},
......@@ -167,7 +174,7 @@ const actions = {
commit("setState", { key: "hangar", value: null });
commit("setState", {
key: "hangarRealTimeData",
value: hangarRealTimeData,
value: initHangarRealTimeData(),
});
},
/**
......@@ -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 {
......
......@@ -37,7 +37,8 @@ export default {
useAirway: true, //使用航线而不使用任务起飞
baseUrl: '', //api请求的base url
wsUrl: '', //websocket的url
mqttUrl: '' //mqtt的url
mqttUrl: '', //无人机的mqtt地址
mqttUrlHangar: '', //机库的mqtt地址
},
mutations: {
/**
......
This source diff could not be displayed because it is too large. You can view the blob instead.
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论