提交 bc5e5a8a 作者: 翁进城

AI未完成

上级 40c90ae4
流水线 #10847 已失败 于阶段
...@@ -2,26 +2,25 @@ ...@@ -2,26 +2,25 @@
<MMCFlightControlCenter <MMCFlightControlCenter
style="width: 100%; height: 100%;" style="width: 100%; height: 100%;"
v-if="userInfo" v-if="userInfo"
:url="url"
:userInfo="userInfo" :userInfo="userInfo"
:devMode="devMode"
:uavTaskList="uavTaskList" :uavTaskList="uavTaskList"
:hangarTaskList="hangarTaskList"
:scene="scene" :scene="scene"
:useSTLAirway="useSTLAirway" :useSTLAirway="useSTLAirway"
:useTimedTask="useTimedTask" :useTimedTask="useTimedTask"
:useAirway="useAirway" :useAirway="useAirway"
@tokenInvalid="dispatchEvent('tokenInvalid')" @tokenInvalid="dispatchEvent('tokenInvalid')"
@uavChange="dispatchEvent('uavChange', $event)" @uavChange="dispatchEvent('uavChange', $event)"
@uavTaskStart="dispatchEvent('uavTaskStart', $event)" @taskAdd="dispatchEvent('taskAdd', $event)"
@uavTaskAdd="dispatchEvent('uavTaskAdd', $event)" @taskBatchAdd="dispatchEvent('taskBatchAdd', $event)"
@uavAirwayAdd="dispatchEvent('uavAirwayAdd', $event)" @airwayAdd="dispatchEvent('airwayAdd', $event)"
@hangarChange="dispatchEvent('hangarChange', $event)" @hangarChange="dispatchEvent('hangarChange', $event)"
@hangarTaskTabChange="dispatchEvent('hangarTaskTabChange', $event)" @hangarTaskTabChange="dispatchEvent('hangarTaskTabChange', $event)"
@hangarTaskStart="dispatchEvent('hangarTaskStart', $event)" @taskStart="dispatchEvent('taskStart', $event)"
@hangarTaskAdd="dispatchEvent('hangarTaskAdd', $event)" @taskDel="dispatchEvent('taskDel', $event)"
@hangarTaskDel="dispatchEvent('hangarTaskDel', $event)" @airwayListGet="dispatchEvent('airwayListGet', $event)"
@airwayPageChange="dispatchEvent('airwayPageChange', $event)"
@airwayGet="dispatchEvent('airwayGet', $event)" @airwayGet="dispatchEvent('airwayGet', $event)"
@taskListGet="dispatchEvent('taskListGet', $event)"
></MMCFlightControlCenter> ></MMCFlightControlCenter>
</template> </template>
...@@ -30,81 +29,30 @@ export default { ...@@ -30,81 +29,30 @@ export default {
name: "App", name: "App",
data() { data() {
return { return {
baseUrl: "https://test.tmj.mmcuav.cn", url: {
devMode: false, baseUrl: "/",
wsUrl: "wss://tmj.mmcuav.cn/websocket",
mqttUrl: "wss://fkzx.mmcuav.cn:8884/mqtt",
},
scene: 0, // 场景类型 1: 无人机 2: 机库 scene: 0, // 场景类型 1: 无人机 2: 机库
account: "mmctest@admin", account: "mmctest@admin",
password: "test@Admin001", password: "test@Admin001",
userInfo: null, userInfo: null,
useSTLAirway: true, // 使用标准航线 useSTLAirway: true, // 使用标准航线
useTimedTask: false, // 使用定时任务 useTimedTask: false, // 使用定时任务
uavTaskList: [ uavTaskList: [],
], airwayList: [],
hangarTaskList: {
// 常态
normal: [
/*
{
name: "任务1",
id: 1,
airwayId: 105,
},
{
name: "任务2",
id: 2,
airwayId: 106,
}, */
],
// 定时
timed: [
/* {
name: "任务",
id: 1,
time: "2024-04-28 01:00:00", //定时与周期的时间
status: "未执行", //任务状态
airwayId: 105,
}, */
],
// 周期
period: [
/* {
name: '任务',
id: 1,
time: '', //定时与周期的时间
status: '', 任务状态
airway: {
name: '航线名称',
id: 1
}
} */
],
},
airwayList: [
],
hangarTaskAddCB: null, //机库创建任务回调 hangarTaskAddCB: null, //机库创建任务回调
uavTaskAddCB: null, //机库创建任务回调 uavTaskAddCB: null, //机库创建任务回调
airwayPageChangeCB: null, //航线翻页时回调 airwayPageChangeCB: null, //航线翻页时回调
airwayGetCB: null, //获取航线数据回调 airwayGetCB: null, //获取航线数据回调
useAirway: true, //使用航线而不使用任务起飞 taskListGetCB: null, //获取任务数据回调
useAirway: true, //使用航线而不使用任务起飞
callbackList: {},
}; };
}, },
computed: {}, computed: {},
watch: { watch: {},
devMode: {
immediate: true,
handler() {
if (this.devMode) {
this.account = "mmctest@admin";
this.password = "test@Admin001";
this.baseUrl = "https://test.tmj.mmcuav.cn";
} else {
this.account = "mmcadmin@kbt001";
this.password = "TMJMMC@kbta0227&adm";
this.baseUrl = "https://tmj.mmcuav.cn";
}
},
},
},
created() { created() {
this.postTop({ this.postTop({
type: "ready", type: "ready",
...@@ -130,21 +78,17 @@ export default { ...@@ -130,21 +78,17 @@ export default {
* 事件处理 * 事件处理
*/ */
eventHandler() { eventHandler() {
window.addEventListener( window.addEventListener("message", (event) => {
"message", if (event.data.module === "MMCFlightControlCenter") {
(event) => { console.log("iframe收到数据", event.data);
if (event.data.module === "MMCFlightControlCenter") { this.paramHandler(event.data);
console.log("iframe收到数据", event.data); this.callbackHandler(event.data);
this.paramHandler(event.data); this.logHandler(event.data);
this.callbackHandler(event.data); }
this.logHandler(event.data); });
}
},
false
);
}, },
/** /**
* 参数处理 * 外部平台参数传入处理
*/ */
paramHandler({ type, param, data }) { paramHandler({ type, param, data }) {
if (type === "param") { if (type === "param") {
...@@ -156,10 +100,10 @@ export default { ...@@ -156,10 +100,10 @@ export default {
*/ */
callbackHandler({ type, event, data }) { callbackHandler({ type, event, data }) {
if (type === "callback") { if (type === "callback") {
let cb = this[event + "CB"]; let cb = this.callbackList[event]; // this[event + "CB"];
if (cb) { if (cb) {
cb(data); cb(data);
this[event + "CB"] = null; this.callbackList[event] = null;
} }
} }
}, },
...@@ -198,7 +142,7 @@ export default { ...@@ -198,7 +142,7 @@ export default {
*/ */
dispatchEvent(event, data) { dispatchEvent(event, data) {
// 回调函数不能通过postMessage传递 // 回调函数不能通过postMessage传递
switch (event) { /* switch (event) {
case "hangarTaskAdd": case "hangarTaskAdd":
this.hangarTaskAddCB = data.callback; this.hangarTaskAddCB = data.callback;
delete data.callback; delete data.callback;
...@@ -218,6 +162,15 @@ export default { ...@@ -218,6 +162,15 @@ export default {
this.airwayGetCB = data.callback; this.airwayGetCB = data.callback;
delete data.callback; delete data.callback;
break; break;
case "taskListGet":
this.taskListGetCB = data.callback;
delete data.callback;
break;
} */
if (data.callback) {
this.callbackList[event] = data.callback;
delete data.callback;
} }
this.postTop({ this.postTop({
type: "event", type: "event",
......
export { default as Control_API } from './modules/uav_control'; export { default as Control_API } from './modules/uav_control';
export { default as flightTaskAPI } from './modules/flightTask'; export { default as flightTaskAPI } from './modules/flightTask';
export { default as AirLine } from './modules/air-line'; export { default as AirLine } from './modules/air-line';
export { default as Map } from './modules/map'; export { default as Map } from './modules/map';
\ No newline at end of file export { default as AI_API} from './modules/ai';
\ No newline at end of file
import axios from "axios";
class AI_API {
// 人脸
static face(data){
return axios.post("http://api.user.mmcuav.cn/aidemo/facedetect", data);
}
// 车牌
static car(data) {
return axios.post("http://183.62.225.251:9090/api/inflet/v1/tasks/e01d1d01-52e2-4883-a5de-0ae268764db0/predict", data);
}
// 人流
static person(data){
return axios.post("http://183.62.225.251:9090/api/inflet/v1/tasks/18493235-4dd0-4f54-ab55-c1856ca7e3a5/predict", data);
}
// 烟雾
static smoke(data){
return axios.post("http://183.62.225.251:9090/api/inflet/v1/tasks/fca2eb65-8b99-4109-9f9e-a9f7fd06ac1f/predict", data);
}
// 漏油识别
static oilLeak(data){
return axios.post("http://183.62.225.251:9002/detect/image", data);
}
// 裸土识别
static bareSoil(data){
return axios.post("http://183.62.225.251:9090/api/inflet/v1/tasks/05a9d657-8339-4575-bced-04b60b74c690/predict", data);
}
}
\ No newline at end of file
...@@ -77,6 +77,14 @@ class Control_API { ...@@ -77,6 +77,14 @@ class Control_API {
data, data,
}); });
} }
static uploadFile(data){
return request({
url: `/admin-api/infra/file/upload`,
method: "post",
data,
});
}
// 保存AI图片 // 保存AI图片
// static addAiPhoto(data) { // static addAiPhoto(data) {
// return request({ // return request({
......
...@@ -4,10 +4,6 @@ import { resetMessage } from "./message"; ...@@ -4,10 +4,6 @@ import { resetMessage } from "./message";
import router from "../router"; import router from "../router";
import store from "../store"; import store from "../store";
let prodUrl = "http://192.168.5.80:30080";
// let prodUrl = "http://192.168.3.12:48080"; // 戴嘉骏
let devUrl = "http://192.168.5.80:30080";
const $axios = axios.create({ const $axios = axios.create({
// baseURL: process.env.VUE_APP_BASE_API_TG // baseURL: process.env.VUE_APP_BASE_API_TG
// withCredentials: true // withCredentials: true
...@@ -21,11 +17,7 @@ const loading = null; ...@@ -21,11 +17,7 @@ const loading = null;
*/ */
$axios.interceptors.request.use( $axios.interceptors.request.use(
(config) => { (config) => {
if (store.state.devMode) { config.baseURL = store.state.baseUrl;
config.baseURL = devUrl;
} else {
config.baseURL = prodUrl;
}
const token = store.state.token; const token = store.state.token;
if (token) { if (token) {
......
<template>
<div class="rm-actions dialog1027" v-interact>
<div class="dialog-header">
<img class="dialog-header__icon" src="../../../../../../../../assets/images/mount_head.png" />
<div class="dialog-header__title">航点动作</div>
<div class="dialog-header__close">
<el-dropdown trigger="click">
<span class="el-dropdown-link">
<div class="icon el-icon-plus" title="添加"></div>
</span>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item
v-for="(item, index) in actions"
@click.native="selectActions1.push(item)"
>{{ item.label }}</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
<div class @click="$emit('close')">关闭</div>
</div>
</div>
<div class="rm-as-list">
<div
class="rm-as-item"
v-for="(item, i) in selectActions1"
:key="i"
:class="{double: ['云台控制'].includes(item.label)}"
>
<div class="rm-as-item__title">{{item.label}}</div>
<div class="rm-as-item__input" v-if="['间隔拍照', '悬停', '变焦'].includes(item.label)">
<div>
<el-input-number
:min="item.min"
:max="item.max"
v-if="['间隔拍照', '悬停'].includes(item.label)"
v-model="item.param1"
></el-input-number>
<el-input-number
:min="item.min"
:max="item.max"
v-if="['变焦'].includes(item.label)"
v-model="item.param2"
></el-input-number>
{{item.unit}}
</div>
</div>
<div class="rm-as-item__input" v-if="['云台控制'].includes(item.label)">
<div>
(俯仰)
<el-input-number :min="-90" :max="30" v-model="item.param1"></el-input-number>(度)
</div>
<div>
(偏航)
<el-input-number :min="-145" :max="145" v-model="item.param3"></el-input-number>(度)
</div>
</div>
<i class="el-icon-delete rm-as-item__del" v-hover @click="selectActions.splice()"></i>
</div>
</div>
<div class="rm-rp-btns">
<div class="rm-rp-btn" v-hover @click="$emit('close')">取消</div>
<div class="rm-rp-btn save" v-hover @click="$emit('save', selectActions1)">保存</div>
</div>
</div>
</template>
<script>
export default {
name: "Actions",
props: {
selectActions: {
type: Array,
default() {
return [];
},
},
},
data() {
return {
actions: [
{
label: "无动作",
actionType: "",
param1: 1,
},
{
label: "间隔拍照",
actionType: "TRIGGER",
param1: 1,
unit: "米",
},
{
label: "悬停",
min: 0,
// max: 32000,
actionType: "STAY",
param1: 10,
unit: "秒",
},
{
label: "云台控制",
actionType: "GIMBAL_PITCH",
param1: 0,
param2: 0,
param3: 0,
param4: 2,
},
{
label: "开始录像",
actionType: "START_RECORD",
param1: 1,
},
{
label: "停止录像",
actionType: "STOP_RECORD",
param1: 1,
},
{
label: "变焦",
min: 0,
// max: 32000,
actionType: "CAMERA_ZOOM",
param1: 2,
param2: 0,
unit: "倍",
},
{
label: "拍照",
actionType: "START_TAKE_PHOTO",
param3: 1,
},
], //全部动作
selectActions1: [], //选中的动作
};
},
created(){
this.selectActions1 = JSON.parse(JSON.stringify(this.selectActions));
}
};
</script>
<style lang="scss" scoped>
.rm-actions {
position: absolute;
left: 480px;
top: 0;
height: 100%;
width: 420px;
background: #222222;
display: flex;
flex-direction: column;
.dialog-header__close::v-deep {
display: flex;
gap: 20px;
.icon {
color: #fff;
}
}
.rm-as-list {
padding: 16px;
flex: auto;
overflow-y: auto;
display: flex;
flex-direction: column;
gap: 16px;
.rm-as-item::v-deep {
background: #3c3c3c;
border-radius: 1px;
display: flex;
align-items: center;
font-weight: 400;
font-size: 14px;
color: #dedede;
line-height: 20px;
padding: 16px 16px;
justify-content: space-between;
&.double {
.rm-as-item__title {
width: 60px;
}
}
.el-input__inner {
height: 32px;
background: #191919;
border-radius: 2px;
border: 1px solid #4b4b4b;
}
.rm-as-item__title {
width: 120px;
}
.rm-as-item__input {
width: 140px;
flex: auto;
display: flex;
flex-direction: column;
gap: 16px;
.el-input-number {
width: 140px;
line-height: 32px;
}
.el-input-number__decrease {
width: 32px;
height: 32px;
background: transparent;
border-right: 1px solid #4b4b4b;
}
.el-input-number__increase {
width: 32px;
height: 32px;
background: transparent;
border-left: 1px solid #4b4b4b;
}
}
.rm-as-item__del {
font-size: 24px;
}
}
}
}
.rm-rp-btns {
flex: 0;
padding: 32px 0;
display: flex;
justify-content: center;
gap: 32px;
}
.rm-rp-btn {
width: 100px;
height: 32px;
border-radius: 2px;
border: 1px solid #3388ff;
font-weight: 400;
font-size: 14px;
color: #ffffff;
line-height: 16px;
display: flex;
justify-content: center;
align-items: center;
box-sizing: border-box;
&.save {
background: #3388ff;
border: none;
}
&.del {
background: #f56c6c;
border: none;
}
}
</style>
\ No newline at end of file
<template>
<div class="taskListBox">
<el-form class="task-main" label-width="70px">
<el-form-item label="航线选择">
<el-select v-model="selectedAirwayId">
<el-option v-for="(item , i) in airwayList" :label="item.name" :value="item.id"></el-option>
</el-select>
</el-form-item>
<div class="btn" @click="onStartTask" v-hover>一键任务</div>
<div class>
<span class="btn__add-line" @click="showAirwayEdit = true">
<span class="f8"></span> 创建航线
</span>
</div>
</el-form>
<AirwayEdit v-if="showAirwayEdit" @close="showAirwayEdit = false" @addDone="getAirwayList"></AirwayEdit>
</div>
</template>
<script>
import { Utils } from "../../../../../../../../../../lib/cesium";
import { mapState, mapActions } from "vuex";
import { Control_API } from "../../../../../../../../../../api";
import AirwayEdit from "./components/airwayEdit";
const airwayEntities = []; // 航线实体
let point_entity = null;
export default {
name: "taskList",
components: { AirwayEdit },
props: {},
inject: ["rootNode", "bus"],
data() {
return {
//航线列表
airwayList: [],
// 选择的航线
selectedAirwayId: "",
// 创建航线窗口
showAirwayEdit: false,
};
},
computed: {
...mapState("MMCFlightControlCenter", ["cesiumViewer", "useSTLAirway"]),
...mapState("MMCFlightControlCenter/uav", ["uav"]),
...mapState("MMCFlightControlCenter/hangar", ["hangar"]),
// 选择的航线
selectedAirway() {
let find = this.airwayList.find((item) => {
return item.id == this.selectedAirwayId;
});
if (find) {
return find;
} else {
return {
name: "",
id: -1,
};
}
},
},
watch: {
selectedAirway() {
this.clearAirwayEntities();
if (this.selectedAirway.id !== -1) {
try {
let airway = this.selectedAirway.content;
this.createAirwayEntities({
polyline: airway,
id: airway.id,
});
} catch (e) {
console.log("绘制航线失败", e);
}
}
},
},
async created() {
this.bus.$on("startTask", this.onStartTask);
/* if (this.useSTLAirway) {
let res = await Control_API.getUavRouteList({
pageNo: 1,
pageSize: 100,
nestId: this.hangar.id,
});
if (res?.code === 0) {
let airwayList = [];
for (let i = 0; i < res.data.list.length; i++) {
let item = res.data.list[i];
let flightCourseJson;
try {
flightCourseJson = JSON.parse(item.flightCourseJson);
} catch (e) {
console.log(e);
}
// 转换成飞控中心能接受的数据协议
let content = flightCourseJson
? await this.$store.dispatch(
"MMCFlightControlCenter/apiPointsToFKZXPoints",
{
list: flightCourseJson?.linePointSaveReqVOS || [],
actionListKey: "pointActionSaveReqVOS",
}
)
: null;
airwayList.push({
name: item.flightName,
id: item.id,
content: content,
});
}
this.airwayList = airwayList;
}
} else {
this.rootNode.$emit("airwayListGet", {
pageNo: this.airwayData.pageNo,
pageSize: this.airwayData.pageSize,
callback: (data) => {
this.airwayList = airwayData?.records || [];
},
});
} */
this.getAirwayList();
},
beforeDestroy() {
this.clearAirwayEntities();
},
methods: {
...mapActions("MMCFlightControlCenter", [
"createAirwayEntities",
"clearAirwayEntities",
"apiPointsToFKZXPoints",
]),
...mapActions("MMCFlightControlCenter/uav", ["isTakeOver"]),
/**
* 更新任务列表
*/
getAirwayList(id) {
console.log("getAirwayList", this.taskListAll);
this.rootNode.$emit("airwayListGet", {
pageNo: 1,
pageSize: 100,
hangar: this.hangar,
callback: (res) => {
this.airwayList = res?.records || [];
this.$nextTick(() => {
if(id){
this.selectedAirwayId = id;
}
});
},
});
},
/**
* 一键任务事件
*/
async onStartTask() {
// 判断是否已接管
if (!(await this.isTakeOver())) {
this.$message.warning("请先接管无人机");
return;
}
// 判断是否选择了航线
if (this.selectedAirway.id === -1) {
this.$message.warning("请选择航线");
return;
}
try {
await this.$confirm("请确认是否进行一键任务操作?", "安全确认", {
cancelButtonText: "取消",
confirmButtonText: "确定",
customClass: "uav_controlPane",
showClose: false,
});
this.$store.commit("MMCFlightControlCenter/uav/setState", {
key: "airlineData",
value: this.selectedAirway,
});
this.$store.dispatch("MMCFlightControlCenter/uav/takeOff", {
callback: (status) => {
if (status) {
this.$message.success("一键任务指令发送成功");
} else {
this.$message.error("一键任务指令发送失败");
}
},
});
this.rootNode.$emit("taskStart", {
uav: this.uav,
task: this.selectedTask,
airway: this.selectedAirway,
});
} catch (e) {}
},
},
};
</script>
<style lang="scss" scoped>
.taskListBox {
height: 100%;
width: 416px;
background: #222222;
border-radius: 12px;
transition: 0.3s;
display: flex;
flex-direction: column;
.header {
flex-shrink: 0;
display: flex;
justify-content: space-between;
height: 32px;
background: #3c3c3c;
border-radius: 12px 12px 0px 0px;
.title {
display: flex;
align-items: center;
margin-left: 10px;
.font {
font-size: 20px;
font-family: YouSheBiaoTiHei;
color: #14faff;
line-height: 26px;
text-shadow: 0px 1px 1px rgba(2, 32, 56, 0.2);
background-image: -webkit-linear-gradient(
right,
#e3aa77,
#f5cda9,
#f9ecd3,
#fcdbb1,
#edb07a
);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
}
.active {
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;
font-family: MicrosoftYaHei-Bold;
font-size: 14px;
color: #70daf9;
letter-spacing: 0;
font-weight: 700;
}
.default {
background-image: linear-gradient(
180deg,
#9198ff 0%,
rgba(45, 81, 153, 0.22) 40%,
#05091a 100%
);
border: 1px solid #70daf9;
font-family: MicrosoftYaHei-Bold;
font-size: 14px;
color: rgba(112, 218, 249, 0.5);
letter-spacing: 0;
font-weight: 700;
}
}
.task-main::v-deep {
flex: auto;
padding: 38px 16px 16px;
position: relative;
display: flex;
flex-direction: column;
.el-form-item__label {
color: #fff;
}
.btn__add-line {
position: absolute;
bottom: 20px;
right: 20px;
font-size: 10px;
color: #43deff;
cursor: pointer;
}
.el-form-item {
flex-grow: 1;
}
}
.btn {
width: 122px;
height: 32px;
text-align: center;
line-height: 32px;
margin: 0 auto;
color: #fff;
background: #3388ff;
font-family: SourceHanSansCN, SourceHanSansCN;
font-weight: 400;
font-size: 14px;
cursor: pointer;
}
}
.select-airway__btn {
width: 100%;
height: 30px;
padding: 0;
}
</style>
<template>
<div class="task-add dialog1027" v-interact>
<div class="dialog-header">
<div class="dialog-header__title">定时任务</div>
<div class="dialog-header__close" @click="$emit('close')">关闭</div>
</div>
<div class="dialog-content">
<el-form ref="form" :model="form" :rules="rules" label-width="100px">
<el-form-item label="执行日期" prop="date" required>
<el-date-picker
v-model="form.date"
type="daterange"
range-separator="至"
start-placeholder="开始日期"
end-placeholder="结束日期"
size="mini"
popper-class="mmc"
value-format="yyyy-MM-dd"
:picker-options="pickerOptions"
></el-date-picker>
</el-form-item>
<el-form-item label="执行时间" prop="time" required>
<el-time-picker
is-range
v-model="form.time"
range-separator="至"
start-placeholder="开始时间"
end-placeholder="结束时间"
placeholder="选择时间范围"
size="mini"
popper-class="mmc"
value-format="HH:mm:ss"
></el-time-picker>
</el-form-item>
<el-form-item label="航线名称" required>
<el-select v-model="form.airwayId" size="mini" popper-class="mmc" style="width:100%">
<el-option :label="item.name" :value="item.id" v-for="(item, index) in airwayList"></el-option>
</el-select>
</el-form-item>
</el-form>
</div>
<div class="task-add-btn">
<div class="task-add__btn" @click="onConfirm">确认</div>
</div>
</div>
</template>
<script>
import { mapState, mapActions } from "vuex";
import { AirLine, Control_API } from "../../../../../../../../../../../../api";
export default {
name: "TaskAdd",
inject: ["rootNode"],
data() {
return {
form: {
date: [],
time: ["00:00:00", "23:59:59"],
airwayId: "",
},
rules: {
date: [{ required: true, message: "请选择日期", trigger: "blur" }],
time: [{ required: true, message: "请选择时间", trigger: "blur" }],
airwayId: [{ required: true, message: "请选择航线", trigger: "blur" }],
},
pickerOptions: {
disabledDate: (time) => {
// 日期选择限制
return time.getTime() < Date.now() - 8.64e7;
},
},
airwayList: [], //航线列表
};
},
computed: {
...mapState("MMCFlightControlCenter/hangar", ["hangar"]),
...mapState("MMCFlightControlCenter", ["airwayEntities", "useSTLAirway"]),
/**
* 选择的日常任务数据
*/
selectedAirway() {
let find = this.airwayList.find((item) => {
return item.id === this.form.airwayId;
});
return find;
},
},
watch: {
selectedAirway: {
async handler(newVal, oldVal) {
//清除旧的航线并渲染新航线
let find = this.airwayEntities.find(
(item1) => oldVal?.id === item1.airwayId
);
if (find) {
this.clearAirwayEntities({ id: this.selectedAirway.id });
}
//渲染新航线
if (newVal) {
this.createAirwayEntities({
polyline: this.selectedAirway.content,
id: this.selectedAirway.id,
});
}
},
},
},
async mounted() {
if (this.useSTLAirway) {
let res = await Control_API.getUavRouteList({
pageNo: 1,
pageSize: 100,
nestId: this.hangar.id,
});
if (res?.code === 0) {
let airwayList = [];
for (let i = 0; i < res.data.list.length; i++) {
let item = res.data.list[i];
let flightCourseJson;
try {
flightCourseJson = JSON.parse(item.flightCourseJson);
} catch (e) {
console.log(e);
}
// 转换成飞控中心能接受的数据协议
let content = flightCourseJson
? await this.$store.dispatch(
"MMCFlightControlCenter/apiPointsToFKZXPoints",
{
list: flightCourseJson?.linePointSaveReqVOS || [],
actionListKey: "pointActionSaveReqVOS",
}
)
: null;
airwayList.push({
name: item.flightName,
id: item.id,
content: content,
});
}
this.airwayList = airwayList;
}
} else {
this.rootNode.$emit("airwayListGet", {
pageNo: 1,
pageSize: 100,
hangar: this.hangar,
callback: (data) => {
this.airwayList = data?.records || [];
},
});
}
},
methods: {
...mapActions("MMCFlightControlCenter", [
"createAirwayEntities",
"clearAirwayEntities",
]),
/**
* 确认事件
*/
onConfirm() {
this.$refs["form"].validate((valid) => {
if (valid) {
this.rootNode.$emit("taskBatchAdd", {
type: 3, //1: 日常任务 2.定时任务 3.周期任务
taskList: [{ ...this.form, airway: this.selectedAirway }], //任务数据
hangar: this.hangar,
callback: () => {
this.$emit("addDone");
this.$emit("close");
},
}); // 根节点发送机库任务新增事件
} else {
return false;
}
});
},
},
};
</script>
<style lang="scss" scoped>
.task-add {
height: 286px;
background: rgba(9, 32, 87, 0.7);
// border: 1px solid #70daf9;
position: absolute;
top: -5px;
left: 550px;
width: 512x;
z-index: 1;
display: flex;
flex-direction: column;
gap: 5px;
padding-bottom: 20px;
&.more {
height: 376px;
}
.dialog-header {
padding-left: 16px !important;
}
.task-add-main {
padding: 20px 20px 0 10px;
}
.task-add-btn {
flex-shrink: 0;
.task-add__btn {
margin: auto;
width: 92px;
height: 36px;
background: #3388ff;
border-radius: 2px;
cursor: pointer;
text-align: center;
color: #fff;
display: flex;
justify-content: center;
align-items: center;
}
}
.task-add-more {
background-color: rgba(13, 82, 143, 0.6);
height: 24px;
cursor: pointer;
display: flex;
justify-content: center;
align-items: center;
}
}
</style>
\ No newline at end of file
<template>
<div class="timed-task">
<div class="timed-task-header">
<div class="header__column flex2">名称</div>
<div class="header__column flex2">时间</div>
<div class="header__column">状态</div>
<div class="header__column flex2">操作</div>
</div>
<div class="timed-task-main">
<div class="row" v-for="item in taskListAll" :key="item.id">
<div class="row__column flex2">
<el-tooltip class="item" effect="dark" :content="item.name" placement="top-start">
<span>{{item.name}}</span>
</el-tooltip>
</div>
<div class="row__column flex2">
<el-tooltip
class="item"
effect="dark"
:content="`${item.taskStartTime}至${item.taskEndTime}`"
placement="top-start"
>
<span>{{`${item.taskStartTime}至${item.taskEndTime}`}}</span>
</el-tooltip>
</div>
<div class="row__column" style="color: rgb(255, 189, 54);">{{item.status}}</div>
<div class="row__column flex2 ctrl">
<el-tooltip content="查看" placement="top">
<span
class="icon-chakan1 iconfont icon"
style="color: #ffffff; font-size: 10px;"
@click="onSwitchAirway(item)"
></span>
</el-tooltip>
<!-- <el-tooltip content="历史" placement="top">
<img class="icon" style="width: 15px;" src="../../assets/images/history.png" />
</el-tooltip>-->
<!-- <el-tooltip content="禁用" v-if="!item.enable" placement="top">
<img class="icon" style="width: 18px;" src="../../assets/images/enable.png" />
</el-tooltip>
<el-tooltip content="启用" v-if="item.enable" placement="top">
<img class="icon" style="width: 15px;" src="../../assets/images/able.png" />
</el-tooltip>-->
<el-tooltip content="删除" placement="top">
<span class="icon-shanchu iconfont icon" @click="onDelAirway(item)"></span>
</el-tooltip>
</div>
</div>
</div>
<div class="task-add-btn">
<div class="task-add__btn" @click="showTaskAdd = true">创建周期任务</div>
</div>
<TaskAdd v-if="showTaskAdd" @close="onTaskAddClose" @addDone="onAddDone"></TaskAdd>
</div>
</template>
<script>
import { mapState, mapActions } from "vuex";
import { AirLine } from "../../../../../../../../../../api";
import TaskAdd from "./components/taskAdd";
export default {
name: "hangarPeriodTask",
components: {
TaskAdd,
},
inject: ["rootNode", "bus"],
data() {
return {
showTaskAdd: false,
taskListAll: [],
};
},
computed: {
...mapState("MMCFlightControlCenter", ["airwayEntities"]),
...mapState("MMCFlightControlCenter/hangar", [
"hangarRealTimeData",
"hangar",
]),
},
created() {
this.rootNode.$emit("hangarTaskTabChange", {
type: 3,
});
this.getTaskList();
},
beforeDestroy() {
this.clearAirwayEntities();
},
methods: {
...mapActions("MMCFlightControlCenter", [
"createAirwayEntities",
"clearAirwayEntities",
]),
/**
* 更新任务列表
*/
getTaskList() {
console.log("getTaskList", this.taskListAll);
this.rootNode.$emit("taskListGet", {
pageNo: 1,
pageSize: 100,
type: 3, // 1: 日常任务 2: 定时任务 3:周期任务
hangar: this.hangar,
callback: (res) => {
this.taskListAll = res.records || [];
},
});
},
/**
* 显示或隐藏航线
*/
async onSwitchAirway(item) {
this.rootNode.$emit("airwayGet", {
airwayId: item.airwayId,
callback: (airway) => {
let find = this.airwayEntities.find(
(item1) => item1.airwayId === airway.id
);
if (find) {
this.clearAirwayEntities({ id: airway.id });
} else {
this.createAirwayEntities({
polyline: airway.content,
id: airway.id,
});
}
},
});
},
async onDelAirway(item) {
try {
await this.$confirm("请确认是否删除该任务?", "安全确认", {
cancelButtonText: "取消",
confirmButtonText: "确定",
customClass: "uav_controlPane",
showClose: false,
});
this.rootNode.$emit("taskDel", {
task: item,
type: 3, // 1: 日常任务 2: 定时任务 3:周期任务
callback: () => {
this.getTaskList();
}
});
} catch (e) {
console.log(e);
}
},
onTaskAddClose() {
this.showTaskAdd = false;
},
onAddDone(){
this.getTaskList();
}
},
};
</script>
<style lang="scss" scoped>
.timed-task {
height: 100%;
display: flex;
flex-direction: column;
padding: 5px 10px 5px;
gap: 8px;
box-sizing: border-box;
.timed-task-header {
display: flex;
flex-shrink: 0;
font-family: MicrosoftYaHei-Bold;
font-size: 14px;
color: #b5e5ff;
padding: 5px 0;
letter-spacing: 0;
font-weight: 700;
background: rgba(87, 96, 138, 0.2);
border: 1px solid rgba(207, 234, 255, 0.33);
gap: 3px;
.header__column {
flex: 1;
display: flex;
justify-content: center;
align-items: center;
&.flex2 {
flex: 2;
}
}
}
.timed-task-main {
color: #fff;
overflow-y: auto;
flex: 1;
.row {
display: flex;
color: #fff;
background: url("../../assets/images/listBg.png");
background-repeat: no-repeat;
background-size: 100% 100%;
height: 33px;
line-height: 33px;
padding-left: 4px;
margin-bottom: 16px;
gap: 3px;
.row__column {
flex: 1;
text-align: center;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
&.flex2 {
flex: 2;
}
&.ctrl {
display: flex;
justify-content: center;
align-items: center;
gap: 5px;
.icon {
cursor: pointer;
}
}
}
}
}
.task-add-btn {
text-align: center;
.task-add__btn {
width: 124px;
height: 36px;
background: #3388ff;
border-radius: 2px;
text-align: center;
line-height: 32px;
margin: 0 auto;
margin-bottom: 10px;
cursor: pointer;
color: #fff;
}
}
}
</style>
\ No newline at end of file
<template>
<div class="task-add dialog1027" :class="{more: showMore}" v-interact>
<div class="task-add-header dialog-header">
<div class="header__title dialog-header__title">定时任务</div>
<div class="header-right dialog-header__close">
<div class="header-right__add" @click="onTaskAdd">
<span class="iconfont icon-zengjia"></span>添加任务
</div>
<div class="header-right__close" @click="$emit('close')">关闭</div>
</div>
</div>
<div class="task-add-main dialog-content">
<div class="main-item" v-for="(item, index) in list" :key="index">
<el-date-picker
v-model="item.time"
size="mini"
popper-class="mmc"
type="datetime"
placeholder="选择时间"
value-format="yyyy-MM-dd HH:mm:ss"
:picker-options="pickerOptions"
></el-date-picker>
<el-select
v-model="item.airwayId"
size="mini"
popper-class="mmc"
placeholder="请选择航线"
>
<el-option
:label="item1.name"
:value="item1.id"
v-for="(item1, index) in airwayList"
></el-option>
</el-select>
<el-tooltip content="删除" placement="top">
<span class="icon-shanchu iconfont" @click="onDelTask(index)"></span>
</el-tooltip>
<el-tooltip content="查看" placement="top">
<span
class="icon-chakan1 iconfont"
style="font-size: 10px;"
@click="onSwitchAirway(item)"
></span>
</el-tooltip>
</div>
</div>
<div class="task-add-btn">
<div class="task-add__btn" @click="onConfirm">确认</div>
</div>
<div class="task-add-more" @click="showMore = !showMore">
<img src="../../../../assets/images/xb.png" width="15" />
</div>
</div>
</template>
<script>
import { mapState, mapActions } from "vuex";
import { AirLine } from "../../../../../../../../../../../../api";
export default {
name: "TaskAdd",
inject: ["rootNode"],
data() {
return {
list: [
/* {
time: '',
airwayId: ''
} */
],
showMore: false,
pickerOptions: {
disabledDate: (time) => {
// 日期选择限制
return time.getTime() < Date.now() - 8.64e7;
},
},
airwayList: [], //航线列表
};
},
computed: {
...mapState("MMCFlightControlCenter/hangar", ["hangar"]),
...mapState("MMCFlightControlCenter", ["airwayEntities"]),
},
mounted(){
this.rootNode.$emit('airwayListGet', {
pageNo: 1,
pageSize: 100,
hangar: this.hangar,
callback: (data) => {
this.airwayList = data?.records || [];
}
})
},
methods: {
...mapActions("MMCFlightControlCenter", [
"createAirwayEntities",
"clearAirwayEntities",
]),
/**
* 显示或隐藏航线
*/
async onSwitchAirway(item) {
this.rootNode.$emit("airwayGet", {
airwayId: item.airwayId,
callback: (airway) => {
let find = this.airwayEntities.find(
(item1) => item1.airwayId === airway.id
);
if (find) {
this.clearAirwayEntities({ id: airway.id });
} else {
this.createAirwayEntities({
polyline: airway.content,
id: airway.id,
});
}
},
});
},
/**
* 添加新任务
*/
onTaskAdd(item) {
this.list.push({
time: "",
airwayId: "",
});
},
/**
* 删除的任务
*/
onDelTask(index) {
this.list = this.list.filter((item, i) => i !== index);
},
/**
* 确认事件
*/
onConfirm() {
let isOk = true;
this.list.some((item) => {
if (!item.time) {
this.$message.warning("请选择时间");
isOk = false;
return true;
}
if (!item.airwayId) {
this.$message.warning("请选择航线");
isOk = false;
return true;
}
});
if (isOk) {
let list = this.list.map(item => {
let find = this.airwayList.find(airway => airway.id === item.airwayId);
return {
...item,
airway: find
}
})
this.rootNode.$emit("taskBatchAdd", {
type: 2, //1: 日常任务 2.定时任务 3.周期任务
taskList: list, //任务数据
hangar: this.hangar,
callback: () => {
this.$emit("addDone");
this.$emit("close");
},
}); // 根节点发送机库任务新增事件
}
},
},
};
</script>
<style lang="scss" scoped>
.task-add {
height: 250px;
position: absolute;
top: -5px;
left: 550px;
width: 520px;
z-index: 1;
display: flex;
flex-direction: column;
gap: 5px;
&.more {
height: 376px;
}
.task-add-header {
flex-shrink: 0;
display: flex;
justify-content: space-between;
align-items: center;
height: 32px;
padding: 0 20px 0 0;
.header__title {
font-family: MicrosoftYaHei-Bold;
font-size: 16px;
color: #70daf9;
letter-spacing: 0;
font-weight: 700;
}
.header-right {
display: flex;
gap: 20px;
font-family: MicrosoftYaHei;
font-size: 16px;
color: #70daf9;
letter-spacing: 0;
font-weight: 400;
.header-right__add {
font-size: 12px;
display: flex;
align-items: center;
cursor: pointer;
}
.header-right__close {
font-size: 16px;
cursor: pointer;
}
}
}
.task-add-main {
padding: 20px 20px 0 10px;
flex: 1;
overflow-y: auto;
.main-item::v-deep {
margin-bottom: 20px;
display: flex;
align-items: center;
font-size: 15px;
color: #fff;
gap: 5px;
height: fit-content;
.el-date-editor {
width: 188px;
}
.el-select {
width: 200px;
}
.input {
width: 150px;
}
.iconfont {
color: rgb(67, 222, 255);
cursor: pointer;
}
}
}
.task-add-btn {
flex-shrink: 0;
.task-add__btn {
width: 92px;
height: 36px;
background: #3388ff;
border-radius: 2px;
text-align: center;
line-height: 32px;
margin: 0 auto;
margin-bottom: 10px;
cursor: pointer;
color: #fff;
}
}
.task-add-more {
background-color: #191919;
height: 24px;
cursor: pointer;
display: flex;
justify-content: center;
align-items: center;
}
}
</style>
\ No newline at end of file
<template>
<div class="timed-task">
<div class="timed-task-header">
<div class="header__column flex2">名称</div>
<div class="header__column flex2">时间</div>
<div class="header__column">状态</div>
<div class="header__column flex2">操作</div>
</div>
<div class="timed-task-main">
<div class="row" v-for="item in taskListAll" :key="item.id">
<div class="row__column flex2">
<el-tooltip class="item" effect="dark" :content="item.name" placement="top-start">
<span>{{item.name}}</span>
</el-tooltip>
</div>
<div class="row__column flex2">
<el-tooltip class="item" effect="dark" :content="item.taskStartTime" placement="top-start">
<span>{{item.taskStartTime}}</span>
</el-tooltip>
</div>
<div class="row__column" style="color: rgb(255, 189, 54);">{{item.status}}</div>
<div class="row__column flex2 ctrl">
<el-tooltip content="查看" placement="top">
<span
class="icon-chakan1 iconfont icon"
style="color: #ffffff; font-size: 10px;"
@click="onSwitchAirway(item)"
></span>
</el-tooltip>
<!-- <el-tooltip content="历史" placement="top">
<img class="icon" style="width: 15px;" src="../../assets/images/history.png" />
</el-tooltip>-->
<!-- <el-tooltip content="禁用" v-if="!item.enable" placement="top">
<img class="icon" style="width: 18px;" src="../../assets/images/enable.png" />
</el-tooltip>
<el-tooltip content="启用" v-if="item.enable" placement="top">
<img class="icon" style="width: 15px;" src="../../assets/images/able.png" />
</el-tooltip>-->
<el-tooltip content="删除" placement="top">
<span class="icon-shanchu iconfont icon" @click="onDelAirway(item)"></span>
</el-tooltip>
</div>
</div>
</div>
<div class="task-add-btn">
<div class="task-add__btn" @click="showTaskAdd = true">创建定时任务</div>
</div>
<TaskAdd v-if="showTaskAdd" @close="onTaskAddClose" @addDone="onAddDone"></TaskAdd>
</div>
</template>
<script>
import { mapState, mapActions } from "vuex";
import { AirLine } from "../../../../../../../../../../api";
import TaskAdd from "./components/taskAdd";
export default {
name: "hangarTimedTask",
components: {
TaskAdd,
},
inject: ["rootNode", "bus"],
data() {
return {
showTaskAdd: false,
taskListAll: [],
};
},
computed: {
...mapState("MMCFlightControlCenter", ["airwayEntities"]),
...mapState("MMCFlightControlCenter/hangar", [
"hangarRealTimeData",
"hangar",
"taskList",
]),
},
created() {
this.rootNode.$emit("hangarTaskTabChange", {
type: 2,
});
this.getTaskList();
},
beforeDestroy() {
this.clearAirwayEntities();
},
methods: {
...mapActions("MMCFlightControlCenter", [
"createAirwayEntities",
"clearAirwayEntities",
]),
/**
* 更新任务列表
*/
getTaskList() {
console.log("getTaskList", this.taskListAll);
this.rootNode.$emit("taskListGet", {
pageNo: 1,
pageSize: 100,
type: 2, // 1: 日常任务 2: 定时任务 3:周期任务
hangar: this.hangar,
callback: (res) => {
this.taskListAll = res.records || [];
},
});
},
/**
* 显示或隐藏航线
*/
async onSwitchAirway(item) {
this.rootNode.$emit("airwayGet", {
airwayId: item.airwayId,
callback: (airway) => {
let find = this.airwayEntities.find(
(item1) => item1.airwayId === airway.id
);
if (find) {
this.clearAirwayEntities({ id: airway.id });
} else {
this.createAirwayEntities({
polyline: airway.content,
id: airway.id,
});
}
},
});
},
async onDelAirway(item) {
try {
await this.$confirm("请确认是否删除该任务?", "安全确认", {
cancelButtonText: "取消",
confirmButtonText: "确定",
customClass: "uav_controlPane",
showClose: false,
});
this.rootNode.$emit("taskDel", {
task: item,
type: 2, // 1: 日常任务 2: 定时任务 3:周期任务
callback: () => {
this.getTaskList();
}
});
} catch (e) {
console.log(e);
}
},
onTaskAddClose() {
this.showTaskAdd = false;
},
onAddDone(){
this.getTaskList();
}
},
};
</script>
<style lang="scss" scoped>
.timed-task {
height: 100%;
display: flex;
flex-direction: column;
padding: 5px 10px 5px;
gap: 8px;
box-sizing: border-box;
.timed-task-header {
display: flex;
flex-shrink: 0;
font-family: MicrosoftYaHei-Bold;
font-size: 14px;
color: #b5e5ff;
padding: 5px 0;
letter-spacing: 0;
font-weight: 700;
background: rgba(87, 96, 138, 0.2);
border: 1px solid rgba(207, 234, 255, 0.33);
gap: 3px;
.header__column {
flex: 1;
display: flex;
justify-content: center;
align-items: center;
&.flex2 {
flex: 2;
}
}
}
.timed-task-main {
color: #fff;
overflow-y: auto;
flex: 1;
.row {
display: flex;
color: #fff;
background: url("../../assets/images/listBg.png");
background-repeat: no-repeat;
background-size: 100% 100%;
height: 33px;
line-height: 33px;
padding-left: 4px;
margin-bottom: 16px;
gap: 3px;
.row__column {
flex: 1;
text-align: center;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
&.flex2 {
flex: 2;
}
&.ctrl {
display: flex;
justify-content: center;
align-items: center;
gap: 5px;
.icon {
cursor: pointer;
}
}
}
}
}
.task-add-btn {
text-align: center;
.task-add__btn {
width: 124px;
height: 36px;
background: #3388ff;
border-radius: 2px;
text-align: center;
line-height: 32px;
margin: 0 auto;
margin-bottom: 10px;
cursor: pointer;
color: #fff;
}
}
}
</style>
\ No newline at end of file
// 机库状态字典
export default [
{
value: 0,
label: "空闲 ",
},
{
value: 1,
label: "正在执行出仓待命 ",
},
{
value: 2,
label: "正在执行回收入仓 ",
},
{
value: 3,
label: "正在执行充电流程",
},
{
value: 4,
label: "正在结束充电流程",
},
{
value: 5,
label: "正在执行休眠流程",
},
{
value: 6,
label: "正在执行预热流程",
},
{
value: 7,
label: "正在执行初始化",
},
{
value: 8,
label: "未初始化",
},
{
value: 9,
label: "正在执行关舱流程 ",
},
{
value: 10,
label: "正在执行回中器操作 ",
},
{
value: 99,
label: "正在执行飞行任务",
},
];
<template>
<div class="task-list">
<div class="task-list-header">
<div class="task-list-header__item" :class="{active: tabIndex === 0 && useTimedTask}" @click="tabIndex = 0">
<label>常态飞行</label>
</div>
<template v-if="useTimedTask">
<div class="task-list-header__item" :class="{active: tabIndex === 1}" @click="tabIndex = 1">
<label>定时飞行</label>
</div>
<div class="task-list-header__item" :class="{active: tabIndex === 2}" @click="tabIndex = 2">
<label>周期飞行</label>
</div>
</template>
</div>
<div class="task-list-main">
<!-- 常态任务 -->
<NormalTask v-if="tabIndex === 0"></NormalTask>
<!-- 定时任务 -->
<TimedTask v-else-if="tabIndex === 1"></TimedTask>
<!-- 周期任务 -->
<PeriodTask v-else-if="tabIndex === 2"></PeriodTask>
</div>
</div>
</template>
<script>
import NormalTask from "./components/normalTask";
import TimedTask from "./components/timedTask";
import PeriodTask from "./components/periodTask";
import { mapState } from "vuex";
export default {
name: "hangarTaskList",
components: {
NormalTask,
TimedTask,
PeriodTask,
},
data() {
return {
tabIndex: 0,
};
},
computed: {
...mapState("MMCFlightControlCenter", ["useTimedTask"]),
},
watch: {
useTimedTask() {
if (!this.useTimedTask) {
this.tabIndex = 0;
}
},
},
mounted() {},
methods: {},
};
</script>
<style lang="scss" scoped>
.task-list {
width: 416px;
height: 254px;
background: #222222;
border-radius: 10px 10px 0 0;
display: flex;
flex-direction: column;
.task-list-header {
background: #3c3c3c;
border-radius: 10px 10px 0px 0px;
height: 32px;
flex-shrink: 0;
display: flex;
.task-list-header__item {
flex: 1;
display: flex;
justify-content: center;
align-items: center;
font-family: YouSheBiaoTiHei;
font-size: 16px;
color: #fff;
cursor: pointer;
* {
cursor: pointer;
}
&.active {
background: #3388ff;
label {
font-family: YouSheBiaoTiHei;
font-size: 20px;
color: #14faff;
line-height: 26px;
text-shadow: 0px 1px 1px rgba(2, 32, 56, 0.2);
text-align: left;
font-style: normal;
background: linear-gradient(
right,
#e3aa77,
#f5cda9,
#f9ecd3,
#fcdbb1,
#edb07a
);
line-height: 32px;
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
}
}
}
.task-list-main {
flex: 1;
overflow: hidden;
}
}
</style>
\ No newline at end of file
...@@ -58,8 +58,8 @@ ...@@ -58,8 +58,8 @@
<el-pagination <el-pagination
layout="prev, pager, next" layout="prev, pager, next"
:total="airwayData.total" :total="airwayData.total"
:pageSize="airwayData.size" :pageSize="airwayData.pageSize"
:currentPage.sync="airwayData.current" :currentPage.sync="airwayData.pageNo"
@current-change="getAirway" @current-change="getAirway"
></el-pagination> ></el-pagination>
</div> </div>
...@@ -75,9 +75,9 @@ export default { ...@@ -75,9 +75,9 @@ export default {
return { return {
keyword: null, keyword: null,
airwayData: { airwayData: {
current: 1, pageNo: 1,
records: [], records: [],
size: 10, pageSize: 10,
total: 0, total: 0,
}, },
}; };
...@@ -109,8 +109,8 @@ export default { ...@@ -109,8 +109,8 @@ export default {
async getAirway() { async getAirway() {
if (this.useSTLAirway) { if (this.useSTLAirway) {
let res = await Control_API.getUavRouteList({ let res = await Control_API.getUavRouteList({
pageNo: this.airwayData.current, pageNo: this.airwayData.pageNo,
pageSize: this.airwayData.size, pageSize: this.airwayData.pageSize,
// nestId: this.hangar.id, // TODO 目前还没有新增航线操作 // nestId: this.hangar.id, // TODO 目前还没有新增航线操作
}); });
if (res?.code === 0) { if (res?.code === 0) {
...@@ -122,14 +122,14 @@ export default { ...@@ -122,14 +122,14 @@ export default {
5: "驳回", 5: "驳回",
}; };
this.airwayData = (res.data.list && { this.airwayData = (res.data.list && {
current: this.airwayData.current, pageNo: this.airwayData.pageNo,
records: res.data.list, records: res.data.list,
size: this.airwayData.size, pageSize: this.airwayData.pageSize,
total: res.data.total, total: res.data.total,
}) || { }) || {
current: this.airwayData.current, pageNo: this.airwayData.pageNo,
records: [], records: [],
size: this.airwayData.size, pageSize: this.airwayData.pageSize,
total: this.airwayData.total, total: this.airwayData.total,
}; };
...@@ -148,14 +148,14 @@ export default { ...@@ -148,14 +148,14 @@ export default {
}); });
} }
} else { } else {
this.rootNode.$emit("airwayPageChange", { this.rootNode.$emit("airwayListGet", {
page: this.airwayData.current, pageNo: this.airwayData.pageNo,
pageSize: this.airwayData.size, pageSize: this.airwayData.pageSize,
callback: (data) => { callback: (data) => {
this.airwayData = data || { this.airwayData = data || {
current: 1, pageNo: 1,
records: [], records: [],
size: 10, pageSize: 10,
total: 0, total: 0,
}; };
}, },
......
...@@ -203,7 +203,7 @@ export default { ...@@ -203,7 +203,7 @@ export default {
} }
}, },
}); });
this.rootNode.$emit("hangarTaskStart", { this.rootNode.$emit("taskStart", {
type: 1, //1: 日常任务 2:定时任务 3:周期任务 type: 1, //1: 日常任务 2:定时任务 3:周期任务
hangar: this.hangar, hangar: this.hangar,
task: this.selectedTask, task: this.selectedTask,
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
<img class="left-bar-item__icon" src="./assets/images/task.svg" /> <img class="left-bar-item__icon" src="./assets/images/task.svg" />
<div class="left-bar-item__text">任务</div> <div class="left-bar-item__text">任务</div>
</div> </div>
<TaskList class="task-list" v-if="openTask"></TaskList> <AirwayList class="task-list" v-if="openTask"></AirwayList>
<div class="left-bar-item item" @click="onClickAI"> <div class="left-bar-item item" @click="onClickAI">
<img class="left-bar-item__icon" src="./assets/images/ai.svg" /> <img class="left-bar-item__icon" src="./assets/images/ai.svg" />
<div class="left-bar-item__text">智能识别</div> <div class="left-bar-item__text">智能识别</div>
...@@ -62,7 +62,7 @@ import { mapState } from "vuex"; ...@@ -62,7 +62,7 @@ import { mapState } from "vuex";
import Car from "./components/car"; import Car from "./components/car";
import Face from "./components/face"; import Face from "./components/face";
import Jm from "./components/Jm"; import Jm from "./components/Jm";
import TaskList from "./components/taskList"; import AirwayList from "./components/airwayList";
import Traffic from "./components/traffic"; import Traffic from "./components/traffic";
import PlayerInner from "./components/player/inner"; import PlayerInner from "./components/player/inner";
import PlayerOuter from "./components/player/outer"; import PlayerOuter from "./components/player/outer";
...@@ -73,7 +73,7 @@ export default { ...@@ -73,7 +73,7 @@ export default {
components: { components: {
Car, Car,
Jm, Jm,
TaskList, AirwayList,
Traffic, Traffic,
Face, Face,
PlayerInner, PlayerInner,
......
...@@ -13,7 +13,7 @@ export default { ...@@ -13,7 +13,7 @@ export default {
return this.$store.state.MMCMQTT?.dataSet?.[this.uav?.deviceId]; return this.$store.state.MMCMQTT?.dataSet?.[this.uav?.deviceId];
}, },
mqttUrl() { mqttUrl() {
return this.$store.getters["MMCFlightControlCenter/mqttUrl"]; return this.$store.state.MMCFlightControlCenter.mqttUrl;
}, },
}, },
watch: { watch: {
......
...@@ -510,8 +510,8 @@ export default { ...@@ -510,8 +510,8 @@ export default {
}; };
}, },
computed: { computed: {
stream() { isQingLiu() {
return this.$store.state.fckernel.stream; return this.$store.state.MMCFlightControlCenter.uav.isQingLiu;
} }
}, },
watch: { watch: {
...@@ -691,7 +691,7 @@ export default { ...@@ -691,7 +691,7 @@ export default {
}, },
type: 528 type: 528
}; };
if (this.stream == 'QingLiu') { if (this.isQingLiu) {
streamData.data.messageID = 1016; streamData.data.messageID = 1016;
} else { } else {
streamData.data.messageID = 1007; streamData.data.messageID = 1007;
...@@ -711,7 +711,7 @@ export default { ...@@ -711,7 +711,7 @@ export default {
}, },
type: 528 type: 528
}; };
if (this.stream == 'QingLiu') { if (this.isQingLiu) {
streamData.data.messageID = 1017; streamData.data.messageID = 1017;
streamData.data.data.status = this.record; streamData.data.data.status = this.record;
} else { } else {
......
...@@ -595,8 +595,8 @@ export default { ...@@ -595,8 +595,8 @@ export default {
}; };
}, },
computed: { computed: {
stream() { isQingLiu() {
return this.$store.state.fckernel.stream; return this.$store.state.MMCFlightControlCenter.uav.isQingLiu;
} }
}, },
watch: { watch: {
...@@ -972,7 +972,7 @@ export default { ...@@ -972,7 +972,7 @@ export default {
}, },
type: 528 type: 528
}; };
if (this.stream == 'QingLiu') { if (this.isQingLiu) {
streamData.data.messageID = 1016; streamData.data.messageID = 1016;
} else { } else {
streamData.data.messageID = 1007; streamData.data.messageID = 1007;
...@@ -990,7 +990,7 @@ export default { ...@@ -990,7 +990,7 @@ export default {
}, },
type: 528 type: 528
}; };
if (this.stream == 'QingLiu') { if (this.isQingLiu) {
streamData.data.messageID = 1017; streamData.data.messageID = 1017;
streamData.data.data.status = this.record; streamData.data.data.status = this.record;
} else { } else {
......
...@@ -177,7 +177,10 @@ export default { ...@@ -177,7 +177,10 @@ export default {
this.onPickPoint, this.onPickPoint,
Cesium.ScreenSpaceEventType.LEFT_DOWN Cesium.ScreenSpaceEventType.LEFT_DOWN
); );
this.cesiumViewer.dataSources.remove(this.dataSource); // 直接销毁会报错
this.$nextTick(() => {
this.cesiumViewer.dataSources.remove(this.dataSource);
})
}, },
methods: { methods: {
// 保存航线 // 保存航线
...@@ -222,7 +225,7 @@ export default { ...@@ -222,7 +225,7 @@ export default {
waypointActions: actions, waypointActions: actions,
}; };
}); });
this.rootNode.$emit("uavAirwayAdd", { this.rootNode.$emit("airwayAdd", {
airway: { airway: {
content: waypoints, content: waypoints,
distance: this.distance, distance: this.distance,
...@@ -230,10 +233,11 @@ export default { ...@@ -230,10 +233,11 @@ export default {
name: this.name, name: this.name,
speed: this.form[0].speed, speed: this.form[0].speed,
}, },
callback: (data) => {
this.$emit('addDone', data.id);
this.$emit('close');
}
}); });
this.$nextTick(() => {
this.$emit('close');
})
}, },
/** /**
* 动作保存 * 动作保存
......
...@@ -57,8 +57,8 @@ ...@@ -57,8 +57,8 @@
<el-pagination <el-pagination
layout="prev, pager, next" layout="prev, pager, next"
:total="airwayData.total" :total="airwayData.total"
:pageSize="airwayData.size" :pageSize="airwayData.pageSize"
:currentPage.sync="airwayData.current" :currentPage.sync="airwayData.pageNo"
@current-change="getAirway" @current-change="getAirway"
></el-pagination> ></el-pagination>
</div> </div>
...@@ -74,9 +74,9 @@ export default { ...@@ -74,9 +74,9 @@ export default {
return { return {
keyword: null, keyword: null,
airwayData: { airwayData: {
current: 1, pageNo: 1,
records: [], records: [],
size: 10, pageSize: 10,
total: 0, total: 0,
}, },
}; };
...@@ -107,8 +107,8 @@ export default { ...@@ -107,8 +107,8 @@ export default {
async getAirway() { async getAirway() {
if (this.useSTLAirway) { if (this.useSTLAirway) {
let res = await Control_API.getUavRouteList({ let res = await Control_API.getUavRouteList({
pageNo: this.airwayData.current, pageNo: this.airwayData.pageNo,
pageSize: this.airwayData.size, pageSize: this.airwayData.pageSize,
}); });
if (res?.code === 0) { if (res?.code === 0) {
let statusMap = { let statusMap = {
...@@ -119,14 +119,14 @@ export default { ...@@ -119,14 +119,14 @@ export default {
5: "驳回", 5: "驳回",
}; };
this.airwayData = (res.data.list && { this.airwayData = (res.data.list && {
current: this.airwayData.current, pageNo: this.airwayData.pageNo,
records: res.data.list, records: res.data.list,
size: this.airwayData.size, pageSize: this.airwayData.pageSize,
total: res.data.total, total: res.data.total,
}) || { }) || {
current: this.airwayData.current, pageNo: this.airwayData.pageNo,
records: [], records: [],
size: this.airwayData.size, pageSize: this.airwayData.pageSize,
total: this.airwayData.total, total: this.airwayData.total,
}; };
...@@ -145,14 +145,14 @@ export default { ...@@ -145,14 +145,14 @@ export default {
}); });
} }
} else { } else {
this.rootNode.$emit("airwayPageChange", { this.rootNode.$emit("airwayListGet", {
page: this.airwayData.current, pageNo: this.airwayData.pageNo,
pageSize: this.airwayData.size, pageSize: this.airwayData.pageSize,
callback: (data) => { callback: (data) => {
this.airwayData = data || { this.airwayData = data || {
current: 1, pageNo: 1,
records: [], records: [],
size: 10, pageSize: 10,
total: 0, total: 0,
}; };
}, },
......
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
</span> </span>
</div> </div>
</el-form> </el-form>
<AirwayEdit v-if="showAirwayEdit" @close="showAirwayEdit = false"></AirwayEdit> <AirwayEdit v-if="showAirwayEdit" @close="showAirwayEdit = false" @addDone="getAirwayList"></AirwayEdit>
</div> </div>
</template> </template>
<script> <script>
...@@ -82,7 +82,7 @@ export default { ...@@ -82,7 +82,7 @@ export default {
}, },
async created() { async created() {
this.bus.$on("startTask", this.onStartTask); this.bus.$on("startTask", this.onStartTask);
let res = await Control_API.getUavRouteList({ /* let res = await Control_API.getUavRouteList({
pageNo: 1, pageNo: 1,
pageSize: 100, pageSize: 100,
}); });
...@@ -113,7 +113,8 @@ export default { ...@@ -113,7 +113,8 @@ export default {
}); });
} }
this.airwayList = airwayList; this.airwayList = airwayList;
} } */
this.getAirwayList();
}, },
beforeDestroy() { beforeDestroy() {
this.clearAirwayEntities(); this.clearAirwayEntities();
...@@ -126,6 +127,24 @@ export default { ...@@ -126,6 +127,24 @@ export default {
]), ]),
...mapActions("MMCFlightControlCenter/uav", ["isTakeOver"]), ...mapActions("MMCFlightControlCenter/uav", ["isTakeOver"]),
/** /**
* 更新任务列表
*/
getAirwayList(id) {
console.log("getAirwayList", this.taskListAll);
this.rootNode.$emit("airwayListGet", {
pageNo: 1,
pageSize: 100,
callback: (res) => {
this.airwayList = res?.records || [];
this.$nextTick(() => {
if(id){
this.selectedAirwayId = id;
}
});
},
});
},
/**
* 一键任务事件 * 一键任务事件
*/ */
async onStartTask() { async onStartTask() {
...@@ -160,10 +179,10 @@ export default { ...@@ -160,10 +179,10 @@ export default {
} }
}, },
}); });
this.rootNode.$emit("uavTaskStart", { this.rootNode.$emit("taskStart", {
uav: this.uav, uav: this.uav,
selectedTask: this.selectedTask, task: this.selectedTask,
selectedAirway: this.selectedAirway, airway: this.selectedAirway,
}); });
} catch (e) {} } catch (e) {}
}, },
......
...@@ -222,7 +222,7 @@ export default { ...@@ -222,7 +222,7 @@ export default {
waypointActions: actions, waypointActions: actions,
}; };
}); });
this.rootNode.$emit("uavAirwayAdd", { this.rootNode.$emit("airwayAdd", {
airway: { airway: {
content: waypoints, content: waypoints,
distance: this.distance, distance: this.distance,
......
...@@ -57,8 +57,8 @@ ...@@ -57,8 +57,8 @@
<el-pagination <el-pagination
layout="prev, pager, next" layout="prev, pager, next"
:total="airwayData.total" :total="airwayData.total"
:pageSize="airwayData.size" :pageSize="airwayData.pageSize"
:currentPage.sync="airwayData.current" :currentPage.sync="airwayData.pageNo"
@current-change="getAirway" @current-change="getAirway"
></el-pagination> ></el-pagination>
</div> </div>
...@@ -74,9 +74,9 @@ export default { ...@@ -74,9 +74,9 @@ export default {
return { return {
keyword: null, keyword: null,
airwayData: { airwayData: {
current: 1, pageNo: 1,
records: [], records: [],
size: 10, pageSize: 10,
total: 0, total: 0,
}, },
}; };
...@@ -107,8 +107,8 @@ export default { ...@@ -107,8 +107,8 @@ export default {
async getAirway() { async getAirway() {
if (this.useSTLAirway) { if (this.useSTLAirway) {
let res = await Control_API.getUavRouteList({ let res = await Control_API.getUavRouteList({
pageNo: this.airwayData.current, pageNo: this.airwayData.pageNo,
pageSize: this.airwayData.size, pageSize: this.airwayData.pageSize,
}); });
if (res?.code === 0) { if (res?.code === 0) {
let statusMap = { let statusMap = {
...@@ -119,14 +119,14 @@ export default { ...@@ -119,14 +119,14 @@ export default {
5: "驳回", 5: "驳回",
}; };
this.airwayData = (res.data.list && { this.airwayData = (res.data.list && {
current: this.airwayData.current, pageNo: this.airwayData.pageNo,
records: res.data.list, records: res.data.list,
size: this.airwayData.size, pageSize: this.airwayData.pageSize,
total: res.data.total, total: res.data.total,
}) || { }) || {
current: this.airwayData.current, pageNo: this.airwayData.pageNo,
records: [], records: [],
size: this.airwayData.size, pageSize: this.airwayData.pageSize,
total: this.airwayData.total, total: this.airwayData.total,
}; };
...@@ -145,14 +145,14 @@ export default { ...@@ -145,14 +145,14 @@ export default {
}); });
} }
} else { } else {
this.rootNode.$emit("airwayPageChange", { this.rootNode.$emit("airwayListGet", {
page: this.airwayData.current, pageNo: this.airwayData.pageNo,
pageSize: this.airwayData.size, pageSize: this.airwayData.pageSize,
callback: (data) => { callback: (data) => {
this.airwayData = data || { this.airwayData = data || {
current: 1, pageNo: 1,
records: [], records: [],
size: 10, pageSize: 10,
total: 0, total: 0,
}; };
}, },
......
...@@ -144,7 +144,7 @@ export default { ...@@ -144,7 +144,7 @@ export default {
*/ */
onChangeLine(data) { onChangeLine(data) {
this.selectedAirway = data; this.selectedAirway = data;
this.rootNode.$emit("uavTaskAdd", { this.rootNode.$emit("taskAdd", {
airway: data, airway: data,
callback: ({ id }) => { callback: ({ id }) => {
// 返回新增任务后的任务id // 返回新增任务后的任务id
...@@ -187,10 +187,10 @@ export default { ...@@ -187,10 +187,10 @@ export default {
} }
}, },
}); });
this.rootNode.$emit("uavTaskStart", { this.rootNode.$emit("taskStart", {
uav: this.uav, uav: this.uav,
selectedTask: this.selectedTask, task: this.selectedTask,
selectedAirway: this.selectedAirway, airway: this.selectedAirway,
}); });
} catch (e) {} } catch (e) {}
}, },
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
:is="selectMount.gimbalName" :is="selectMount.gimbalName"
v-if="selectMount" v-if="selectMount"
class="mount-panel" class="mount-panel"
:keyFlag="nxNormal"
@directive="mountDirective" @directive="mountDirective"
@take_photo="mountTakePhoto" @take_photo="mountTakePhoto"
@close="mountClose" @close="mountClose"
...@@ -61,7 +62,11 @@ export default { ...@@ -61,7 +62,11 @@ export default {
"mountList", "mountList",
"airlineId", "airlineId",
"selectMount", "selectMount",
"uavRealTimeData"
]), ]),
nxNormal(){
return this.uavRealTimeData?.healthData?.NX?.warningLevel === 'NORMAL';
}
}, },
created() {}, created() {},
mounted() {}, mounted() {},
......
...@@ -487,9 +487,14 @@ export default { ...@@ -487,9 +487,14 @@ export default {
align-items: center; align-items: center;
position: relative; position: relative;
img { .item {
width: 24px;
height: 24px; height: 24px;
width: 24px;
}
img {
width: 100%;
height: 100%;
} }
.s-count { .s-count {
......
<template>
<div>
<el-tooltip content="AI识别" placement="bottom">
<div class="menu-item">
<img src="../../assets/images/car1.png" @click="aiVisible = !aiVisible" />
<div class="ai-list" v-if="aiVisible">
<el-tooltip
v-for="(item,index) in aiIdentifyList"
:key="index"
:content="item.title"
placement="bottom"
>
<div class="ai-item" @click="onAiIdentify(item.type)">
<img class="img_src" :src="item.Img" />
</div>
</el-tooltip>
</div>
</div>
</el-tooltip>
<el-dialog :title="`${aiTitle}结果`" :visible.sync="aiResultShow">
<el-image style="width: 100px; height: 100px" :src="aiResultImg" fit="contain"></el-image>
</el-dialog>
</div>
</template>
<script>
import { mapState } from "vuex";
import axios from "axios";
import { Control_API } from "../../../../../../api";
import { AI_API } from "../../../../../../api";
import testImg from './img';
function blobToBase64(blob) {
return new Promise((resolve, reject) => {
let reader = new FileReader();
reader.onload = () => {
resolve(reader.result);
};
reader.readAsDataURL(blob);
});
}
export default {
name: "AIList",
data() {
return {
aiVisible: false,
aiIdentifyList: [
{
title: "人脸识别",
type: "face",
Img: require("../../assets/images/人脸识别.png"),
},
{
title: "车牌识别",
type: "car",
Img: require("../../assets/images/车牌检测.png"),
},
{
title: "人流识别",
type: "person",
Img: require("../../assets/images/人流识别.png"),
},
{
title: "火焰烟雾",
type: "smoke",
Img: require("../../assets/images/火焰烟雾.png"),
},
{
title: "漏油识别",
type: "oilLeak",
Img: require("../../assets/images/车辆识别.png"),
},
{
title: "裸土识别",
type: "bareSoil",
Img: require("../../assets/images/异物检测.svg"),
},
],
aiResultShow: false, //ai识别结果展示
aiTitle: "",
aiResultImg: "", //ai结果图
};
},
computed: {
...mapState("MMCFlightControlCenter", ["cesiumViewer"]),
...mapState("MMCFlightControlCenter/uav", ["uav"]),
},
methods: {
/**
* ai识别事件
*/
onAiIdentify(type) {
let find = this.aiIdentifyList.find((item) => item.type === type);
this.aiTitle = find.title;
// 截图做ai识别
this.$emit("screenShot", {
callback: async (blob) => {
let base64 = await blobToBase64(blob);
let results = [
/* {
x: 0,
y: 0,
width: 0,
height: 0,
label: "",
prob: 1,
}, */
];
switch (type) {
// 用的百度
case "face":
break;
// 另一种识别结果
case "bareSoil":
break;
// 共达地通用数据结构
default:
let res = await AI_API[type]({
image: base64,
});
results = res.data.targets.map((item) => {
return {
x: item.bbox.box.left_top_x,
y: item.bbox.box.left_top_y,
width:
item.bbox.box.right_bottom_x - item.bbox.box.left_top_x,
height:
item.bbox.box.right_bottom_y - item.bbox.box.left_top_x,
label: item.bbox.label,
prob: item.bbox.prob,
};
});
break;
}
// 将识别结果绘制到图片上
let img = new Image();
img.onload = function () {
let width = img.width;
let height = img.height;
console.log("图片宽度:", width, "高度:", height);
// 现在可以在Canvas上绘制图片和矩形框
let canvas = drawOnCanvas(img, width, height, results);
// 展示识别结果
this.aiResultImg = canvas.toDataURL("image/png");
this.aiResultShow = true;
// 识别结果上传到视图库
};
// img.src = base64;
img.src = testImg;
},
});
},
},
drawOnCanvas(img, width, height, aiResults) {
let canvas = document.createElement("canvas");
let ctx = canvas.getContext("2d");
// 设置Canvas大小与图片相同
canvas.width = width;
canvas.height = height;
// 绘制图片
ctx.drawImage(img, 0, 0, width, height);
// 绘制矩形框
aiResults.forEach((item) => {
ctx.beginPath();
ctx.rect(item.x, item.y, item.width, item.height); // 你可以调整这些值来改变矩形框的位置和大小
ctx.strokeStyle = "red"; // 矩形框的颜色
ctx.lineWidth = 1; // 矩形框的边框宽度
ctx.stroke();
ctx.fillStyle = "white"; // 文字颜色
ctx.textAlign = "left";
// 绘制文字背景
ctx.fillStyle = "rgba(255, 0, 0, 0.5)"; // 背景颜色
ctx.fillRect(item.x, item.y - 50, item.width, item.height); // 背景的位置和大小
// 绘制文字
ctx.fillText(`${item.label}: ${prob}`, item.x, item.y); // 文字内容和位置
});
return canvas;
},
};
</script>
<style>
</style>
\ No newline at end of file
...@@ -458,7 +458,7 @@ export default { ...@@ -458,7 +458,7 @@ export default {
speed: this.speed, speed: this.speed,
}; };
this.rootNode.$emit('uavAirwayAdd', { this.rootNode.$emit('airwayAdd', {
airway: data airway: data
}); });
this.$emit("close"); this.$emit("close");
......
<template> <template>
<!-- 清流融合 --> <!-- 清流融合 -->
<div class="player" v-interact> <div class="player" :class="big" v-interact>
<div ref="video" class="video-wrap" :class="big" @dblclick="screen"> <div ref="video" class="video-wrap" @dblclick="screen">
<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">
...@@ -112,7 +112,11 @@ ...@@ -112,7 +112,11 @@
<div class="detail">{{ infoData ? infoData.vbuffer / 1000 : "0" }}ms</div> <div class="detail">{{ infoData ? infoData.vbuffer / 1000 : "0" }}ms</div>
</div> </div>
</div> </div>
<div class="info_isStatus" v-if="showInfo && streamSelect == 'QINGLIU'&&isStatus" v-interact> <div
class="info_isStatus"
v-if="showInfo && streamSelect == 'QINGLIU'&&isStatus"
v-interact
>
<div class="title_box"> <div class="title_box">
<div class="title pl20"> <div class="title pl20">
<img src="./assets/images/mount_head.png" /> <img src="./assets/images/mount_head.png" />
...@@ -332,7 +336,7 @@ ...@@ -332,7 +336,7 @@
<img src="./assets/images/photojz.svg" /> <img src="./assets/images/photojz.svg" />
</div> </div>
</el-tooltip> </el-tooltip>
<el-tooltip content="AI识别" placement="bottom"> <!-- <el-tooltip content="AI识别" placement="bottom">
<div class="menu-item"> <div class="menu-item">
<img src="./assets/images/car1.png" @click="aiVisible = !aiVisible" /> <img src="./assets/images/car1.png" @click="aiVisible = !aiVisible" />
<div class="ai-list" v-if="aiVisible"> <div class="ai-list" v-if="aiVisible">
...@@ -346,29 +350,10 @@ ...@@ -346,29 +350,10 @@
<img class="img_src" :src="item.Img" /> <img class="img_src" :src="item.Img" />
</div> </div>
</el-tooltip> </el-tooltip>
<el-tooltip content="人脸识别" placement="bottom">
<div class="ai-item" @click="handle('a')">
<img src="~./assets/images/faceAI2.png" />
</div>
</el-tooltip>
<el-tooltip content="车牌识别" placement="bottom">
<div class="ai-item" @click="handle('b')">
<img src="~./assets/images/carAI.png" />
</div>
</el-tooltip>
<el-tooltip content="人流识别" placement="bottom">
<div class="ai-item" @click="frame()">
<img src="~./assets/images/trafficAI.png" />
</div>
</el-tooltip>
<el-tooltip content="车流识别" placement="bottom">
<div class="ai-item" @click="carFrame()">
<img src="~./assets/images/carAI2.png" />
</div>
</el-tooltip>
</div> </div>
</div> </div>
</el-tooltip> </el-tooltip> -->
<AiList @screenShot="screenShot"></AiList>
<div class="menu-item" @click="startLinePoint" content="航点动作"> <div class="menu-item" @click="startLinePoint" content="航点动作">
<img src="./assets/images/point_small.svg" /> <img src="./assets/images/point_small.svg" />
</div> </div>
...@@ -379,6 +364,7 @@ ...@@ -379,6 +364,7 @@
:mountData="mountDatas" :mountData="mountDatas"
v-if="showFlywayAction" v-if="showFlywayAction"
@close="showFlywayAction = false" @close="showFlywayAction = false"
@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" />
...@@ -389,6 +375,7 @@ ...@@ -389,6 +375,7 @@
:trafficData="cartrafficData" :trafficData="cartrafficData"
@close="cartrafficShow = false" @close="cartrafficShow = false"
/> />
</div> </div>
</template> </template>
...@@ -409,11 +396,8 @@ import Obstacle from "./components/obstacle"; ...@@ -409,11 +396,8 @@ import Obstacle from "./components/obstacle";
import PointList from "./components/pointList"; 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 svg1 from "./assets/images/车牌检测.svg"; import { mapState } from "vuex";
import svg2 from "./assets/images/火焰烟雾.svg"; import AiList from './components/aiList';
import svg3 from "./assets/images/异物检测.svg";
import svg4 from "./assets/images/跌倒检测.svg";
import svg5 from "./assets/images/游泳检测.svg";
export default { export default {
name: "Player", name: "Player",
...@@ -428,6 +412,7 @@ export default { ...@@ -428,6 +412,7 @@ export default {
Obstacle, Obstacle,
SRSPlayer, SRSPlayer,
videoModelChange, videoModelChange,
AiList
}, },
inject: ["bus"], inject: ["bus"],
props: { props: {
...@@ -451,41 +436,55 @@ export default { ...@@ -451,41 +436,55 @@ export default {
}, },
aiIdentifyList: [ aiIdentifyList: [
{ {
title: "车牌识别", title: "人脸识别",
aiType: 12, aiType: 10,
class: "right28 top40", // aiType: 1,
Img: svg1, class: "right30",
Img: require("./assets/images/人脸识别.png"),
}, },
{ {
title: "车辆类型检测", title: "车牌识别",
aiType: 9, aiType: 8,
class: "right66 top40", // aiType: 2,
Img: svg1, class: "right-90",
Img: require("./assets/images/车牌检测.png"),
}, },
{ {
title: "火焰烟雾", title: "人流识别",
aiType: 7, aiType: 3,
class: "right-88 top40", class: "right-10",
Img: svg2, Img: require("./assets/images/人流识别.png"),
}, },
{ {
title: "异物检测", title: "火焰烟雾",
aiType: 6, aiType: 4,
class: "right-11 top40", class: "right-50",
Img: svg3, Img: require("./assets/images/火焰烟雾.png"),
}, },
{ {
title: "跌倒检测", title: "漏油识别",
aiType: 5, aiType: 5,
class: "right-50 top40", class: "right70",
Img: svg4, Img: require("./assets/images/车辆识别.png"),
}, },
{ {
title: "游泳检测", title: "裸土识别",
aiType: 4, aiType: 6,
class: " right66", class: "right-90 top40",
Img: svg5, Img: require("./assets/images/异物检测.svg"),
}, },
// {
// title: "跌倒检测",
// aiType: 5,
// class: "right-50 top40",
// Img: require("@/assets/newImage/跌倒检测.svg")
// },
// {
// title: "游泳检测",
// aiType: 4,
// class: " right66",
// Img: require("@/assets/newImage/游泳检测.svg")
// }
], ],
ygisCenterFlag: false, ygisCenterFlag: false,
ygValue: null, ygValue: null,
...@@ -540,9 +539,12 @@ export default { ...@@ -540,9 +539,12 @@ export default {
isInfoShow: false, isInfoShow: false,
openOSD: true, // 是否开启OSD openOSD: true, // 是否开启OSD
showFlywayAction: false, //显示航点动作 showFlywayAction: false, //显示航点动作
showContinueFly: false, //显示继续飞行对话框
continueFlyContent: '', //继续飞行对话框内容
}; };
}, },
computed: { computed: {
...mapState("MMCFlightControlCenter/uav", ["uav"]),
/** /**
* 播放器组件名 * 播放器组件名
*/ */
...@@ -647,6 +649,22 @@ export default { ...@@ -647,6 +649,22 @@ export default {
}, },
watch: { watch: {
playerCom: {
immediate: true,
handler(newVal) {
if (newVal === "QingLiuPlayer") {
this.$store.commit("MMCFlightControlCenter/uav", {
key: "isQingLiu",
value: true,
});
} else {
this.$store.commit("MMCFlightControlCenter/uav", {
key: "isQingLiu",
value: false,
});
}
},
},
uavRealTimeData: function (newval) { uavRealTimeData: function (newval) {
let gps = null; let gps = null;
if ( if (
...@@ -863,7 +881,7 @@ export default { ...@@ -863,7 +881,7 @@ export default {
}, },
}); });
}, },
//游泳识别 //AI识别
async aiIdentifyType(aiType) { async aiIdentifyType(aiType) {
const data = { const data = {
deviceId: this.device.deviceId, deviceId: this.device.deviceId,
...@@ -902,7 +920,7 @@ export default { ...@@ -902,7 +920,7 @@ export default {
}); });
} }
} else { } else {
this.$message.success("截屏失败"); this.$message.warning("截屏失败");
} }
}, },
// 人脸车牌识别 // 人脸车牌识别
......
...@@ -10,7 +10,7 @@ export default { ...@@ -10,7 +10,7 @@ export default {
return this.$store.state.MMCGroundStation?.dataSet?.[this.uav?.deviceId]; return this.$store.state.MMCGroundStation?.dataSet?.[this.uav?.deviceId];
}, },
mqttUrl() { mqttUrl() {
return this.$store.getters["MMCFlightControlCenter/mqttUrl"]; return this.$store.state.MMCFlightControlCenter.mqttUrl;
}, },
}, },
watch: { watch: {
......
...@@ -31,80 +31,22 @@ export default { ...@@ -31,80 +31,22 @@ export default {
MapSearch, MapSearch,
}, },
props: { props: {
devMode: { url: {
// 开发环境 // api地址前缀
type: Boolean, type: Object,
default: false, default: () => {
return {
baseUrl: "/",
wsUrl: "wss://tmj.mmcuav.cn/websocket",
mqttUrl: "wss://fkzx.mmcuav.cn:8884/mqtt",
};
},
}, },
// 天目将登录用户信息 // 天目将登录用户信息
userInfo: { userInfo: {
type: Object, type: Object,
default: null, default: null,
}, },
// 无人机任务列表
uavTaskList: {
type: Array,
default() {
return [
/* {
name: '任务',
id: 1,
children: [],
airway: {
name: '航线名称',
id: 1
}
} */
];
},
},
// 机库任务列表
hangarTaskList: {
type: Object,
default() {
return {
// 常态
normal: [
/* {
name: '任务',
id: 1,
status: '', 任务状态
children: [],
airway: {
name: '航线名称',
id: 1
}
} */
],
// 定时
Timed: [
/* {
name: '任务',
id: 1,
time: '', //定时与周期的时间
status: '', 任务状态
airway: {
name: '航线名称',
id: 1
}
} */
],
// 周期
period: [
/* {
name: '任务',
id: 1,
time: '', //定时与周期的时间
status: '', 任务状态
airway: {
name: '航线名称',
id: 1
}
} */
],
};
},
},
// 场景 1: 无人机 2: 机库 // 场景 1: 无人机 2: 机库
scene: { scene: {
type: Number, type: Number,
...@@ -128,8 +70,8 @@ export default { ...@@ -128,8 +70,8 @@ export default {
// 使用航线而不使用任务起飞 // 使用航线而不使用任务起飞
useAirway: { useAirway: {
type: Boolean, type: Boolean,
default: true default: true,
} },
}, },
data() { data() {
return { return {
...@@ -143,23 +85,21 @@ export default { ...@@ -143,23 +85,21 @@ export default {
}; };
}, },
watch: { watch: {
uavTaskList: { url: {
immediate: true, immediate: true,
handler(newVal) { handler(newVal) {
this.$store.commit("MMCFlightControlCenter/uav/setState", { this.$store.commit("MMCFlightControlCenter/setState", {
key: "taskList", key: "baseUrl",
value: newVal, value: newVal.baseUrl,
}); });
}, this.$store.commit("MMCFlightControlCenter/setState", {
}, key: "wsUrl",
hangarTaskList: { value: newVal.wsUrl,
immediate: true, });
handler(newVal) { this.$store.commit("MMCFlightControlCenter/setState", {
this.$store.commit("MMCFlightControlCenter/hangar/setState", { key: "mqttUrl",
key: "taskList", value: newVal.mqttUrl,
value: newVal,
}); });
this.bus.$emit("updateHangarTaskList");
}, },
}, },
useSTLAirway: { useSTLAirway: {
...@@ -203,10 +143,6 @@ export default { ...@@ -203,10 +143,6 @@ export default {
}, },
created() { created() {
this.$store.commit("MMCFlightControlCenter/setState", { this.$store.commit("MMCFlightControlCenter/setState", {
key: "devMode",
value: this.devMode,
});
this.$store.commit("MMCFlightControlCenter/setState", {
key: "token", key: "token",
value: this.userInfo.accessToken, value: this.userInfo.accessToken,
}); });
...@@ -289,6 +225,27 @@ export default { ...@@ -289,6 +225,27 @@ export default {
} }
} }
div[class*="cpt-MMC_Gimbal"] {
background: #222222;
border-radius: 10px 10px 0px 0px;
border: 0;
.hd {
box-sizing: border-box;
padding-left: 32px;
padding-right: 16px;
background-position: 12px 4px;
height: 32px;
width: 100%;
background: #3c3c3c;
border-radius: 10px 10px 0px 0px;
display: flex;
justify-content: space-between;
align-items: center;
position: relative;
box-shadow: none;
}
}
.dialog1027 { .dialog1027 {
z-index: 1; z-index: 1;
background: #222222; background: #222222;
...@@ -340,7 +297,7 @@ export default { ...@@ -340,7 +297,7 @@ export default {
.dialog-header__close { .dialog-header__close {
font-size: 14px; font-size: 14px;
font-family: MicrosoftYaHei; font-family: MicrosoftYaHei;
color: #ACACAC; color: #acacac;
line-height: 19px; line-height: 19px;
cursor: pointer; cursor: pointer;
} }
...@@ -502,7 +459,7 @@ export default { ...@@ -502,7 +459,7 @@ export default {
position: relative; position: relative;
background: #191919; background: #191919;
border: 1px solid #4B4B4B; border: 1px solid #4b4b4b;
} }
&.is-multiple { &.is-multiple {
......
...@@ -35,6 +35,9 @@ export default { ...@@ -35,6 +35,9 @@ export default {
useSTLAirway: true, //是否使用标准航线库 useSTLAirway: true, //是否使用标准航线库
useTimedTask: false, //是否使用定时任务 useTimedTask: false, //是否使用定时任务
useAirway: true, //使用航线而不使用任务起飞 useAirway: true, //使用航线而不使用任务起飞
baseUrl: '', //api请求的base url
wsUrl: '', //websocket的url
mqttUrl: '' //mqtt的url
}, },
mutations: { mutations: {
/** /**
...@@ -271,6 +274,7 @@ export default { ...@@ -271,6 +274,7 @@ export default {
}, },
}, },
getters: { getters: {
/*
//地面站websocket url //地面站websocket url
wsUrl(state) { wsUrl(state) {
if (!state.devMode) { if (!state.devMode) {
...@@ -287,7 +291,7 @@ export default { ...@@ -287,7 +291,7 @@ export default {
return "wss://test.fkzx.mmcuav.cn:8884/mqtt"; return "wss://test.fkzx.mmcuav.cn:8884/mqtt";
// return "wss://fkzx.mmcuav.cn:8884/mqtt"; // return "wss://fkzx.mmcuav.cn:8884/mqtt";
} }
}, }, */
}, },
modules: { modules: {
uav, uav,
......
...@@ -194,20 +194,7 @@ const state = { ...@@ -194,20 +194,7 @@ const state = {
selectMount: null, // 选中的挂载 selectMount: null, // 选中的挂载
showPlayer: false, //显示播放器 showPlayer: false, //显示播放器
showPanel: false, //显示数据面板 showPanel: false, //显示数据面板
// 任务列表 isQingLiu: null, // 当前视频播放的是否为清流
taskList: [
/* {
name: "任务",
id: 1,
children: [],
airway: {
name: "航线名称1",
id: 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}',
},
}, */
],
}; };
const mutations = { const mutations = {
...@@ -481,7 +468,7 @@ const actions = { ...@@ -481,7 +468,7 @@ const actions = {
const token = window.$mmc.$store.state.MMCFlightControlCenter.token; const token = window.$mmc.$store.state.MMCFlightControlCenter.token;
window.$mmc.$store window.$mmc.$store
.dispatch("MMCGroundStation/init", { .dispatch("MMCGroundStation/init", {
url: window.$mmc.$store.getters["MMCFlightControlCenter/wsUrl"], url: window.$mmc.$store.state.MMCFlightControlCenter.wsUrl,
userInfo: { userInfo: {
type: 100, type: 100,
systemCode: "mmc", systemCode: "mmc",
......
...@@ -22,6 +22,8 @@ export default { ...@@ -22,6 +22,8 @@ export default {
} */ } */
}, },
orders, //所有指令 orders, //所有指令
username: 'tmj',
password: 'Tmj@192D9'
}, },
mutations: { mutations: {
/** /**
...@@ -57,6 +59,8 @@ export default { ...@@ -57,6 +59,8 @@ export default {
init({ commit, state }, data) { init({ commit, state }, data) {
let clientId = Date.now(); let clientId = Date.now();
let client = mqtt.connect(data.url, { let client = mqtt.connect(data.url, {
username: state.username,
password: state.password,
clientId, clientId,
}); });
......
...@@ -87,8 +87,12 @@ export default { ...@@ -87,8 +87,12 @@ export default {
data() { data() {
return { return {
isIframeReady: false, //是否接收到iframe里的ready事件 isIframeReady: false, //是否接收到iframe里的ready事件
baseUrl: "http://192.168.5.80:30080",
devMode: false, devMode: false,
url: {
baseUrl: "/",
wsUrl: "wss://tmj.mmcuav.cn/websocket",
mqttUrl: "wss://fkzx.mmcuav.cn:8884/mqtt",
},
scene1: false, // 场景类型 true: 无人机 false: 机库 scene1: false, // 场景类型 true: 无人机 false: 机库
useSTLAirway: false, // 使用标准航线库 useSTLAirway: false, // 使用标准航线库
useTimedTask: false, // 使用定时任务 useTimedTask: false, // 使用定时任务
...@@ -167,6 +171,7 @@ export default { ...@@ -167,6 +171,7 @@ export default {
} */ } */
], ],
}, },
postIframeList: [], //给iframe传递参数的队列
}; };
}, },
computed: { computed: {
...@@ -175,28 +180,37 @@ export default { ...@@ -175,28 +180,37 @@ export default {
}, },
}, },
watch: { watch: {
/* isIframeReady(){ isIframeReady() {
if(this.isIframeReady){ if (this.isIframeReady) {
this.login(); this.postIframeList.forEach((item) => {
this.postIframe(item);
});
} }
}, */ },
devMode: { devMode: {
immediate: true, immediate: true,
handler() { handler() {
if (this.devMode) { if (this.devMode) {
this.account = "admin"; this.account = "admin";
this.password = "mmc@123456"; this.password = "mmc@123456";
this.baseUrl = "http://192.168.5.80:30080"; this.url = {
baseUrl: "http://192.168.5.80:30080",
wsUrl: "wss://tmj.mmcuav.cn/websocket",
mqttUrl: "wss://fkzx.mmcuav.cn:8884/mqtt",
};
} else { } else {
this.account = "admin"; this.account = "admin";
this.password = "mmc@123456"; this.password = "mmc@123456";
this.baseUrl = "http://192.168.5.80:30080"; this.url = {
// this.baseUrl = "http://192.168.3.12:48080"; // 戴嘉骏 baseUrl: "http://192.168.5.80:30132",
wsUrl: "wss://tmj.mmcuav.cn/websocket",
mqttUrl: "wss://fkzx.mmcuav.cn:8884/mqtt",
};
} }
this.postIframe({ this.postIframe({
type: "param", type: "param",
param: "devMode", param: "url",
data: this.devMode, data: this.url,
}); });
}, },
}, },
...@@ -278,6 +292,7 @@ export default { ...@@ -278,6 +292,7 @@ export default {
*/ */
postIframe(data) { postIframe(data) {
if (!this.isIframeReady) { if (!this.isIframeReady) {
this.postIframeList.push(data);
throw Error("iframe未准备好"); throw Error("iframe未准备好");
} }
let iframeWindow = this.$refs.iframe.contentWindow; let iframeWindow = this.$refs.iframe.contentWindow;
...@@ -636,12 +651,12 @@ export default { ...@@ -636,12 +651,12 @@ export default {
let formData = new FormData(); let formData = new FormData();
formData.append("userAccount", this.account); formData.append("userAccount", this.account);
formData.append("password", Base64.encode(this.password)); formData.append("password", Base64.encode(this.password));
let res = await fetch(this.baseUrl + "/admin-api/system/auth/login", { let res = await fetch(this.url.baseUrl + "/admin-api/system/auth/login", {
method: "post", method: "post",
headers: { headers: {
"Content-Type": "application/json", "Content-Type": "application/json",
"Tenant-Id": 1, "Tenant-Id": 1,
"terminal": 2 terminal: 2,
}, },
body: JSON.stringify({ body: JSON.stringify({
username: this.account, username: this.account,
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论