提交 875c6d55 作者: 温凯

合并分支 'master' 到 'v4_master'

Master

查看合并请求 !5
......@@ -66,7 +66,12 @@ Vue.use(MMCSTL);
* 修正机库指令
* 增加是否定支持定时任务的判断
* 修正多个缺陷
## v1.6.0
* MQTT新增账号密码
## v1.6.1
* fix: 文件名大小写错误
## v2.0.0
* 合并V4分支更新到v2.0.0版本
## 项目结构
```
......
This source diff could not be displayed because it is too large. You can view the blob instead.
{
"name": "mmc-stl-vue2",
"version": "1.5.0",
"version": "2.0.0",
"description": "科比特前端标准化组件",
"main": "index.js",
"scripts": {
......
......@@ -29,4 +29,17 @@ export default class TaskInfo {
data
});
}
}
/**
* 全部单位
* @param {*} params
* @returns
*/
static listAll(params) {
return request({
url: '/admin-api/system/dept/simple-list',
method: 'get',
params,
});
}
}
\ No newline at end of file
......@@ -15,28 +15,30 @@
<el-form-item label="航线名称" required>
<el-input clearable v-model="name"></el-input>
</el-form-item>
<el-form-item label="所属单位:" required>
<el-cascader ref="CascaderRef" v-model="departmentId" :options="orgList" clearable :show-all-levels="false"
placeholder="请选择所属单位" :props="{
children: 'children',
label: 'name',
value: 'id',
checkStrictly: true,
emitPath: false,
}" @change="changeNode"></el-cascader>
</el-form-item>
<el-form-item label="航线速度" prop="speed">
<el-input clearable v-model="curForm.speed"></el-input>
</el-form-item>
<el-form-item label="目标位置" prop="address">
<el-autocomplete
:popper-append-to-body="false"
v-model="curForm.address"
:fetch-suggestions="onAddressInput"
placeholder="请输入目标位置"
:trigger-on-focus="false"
@select="
(item) => {
onAddressChange(item, 'end');
}
"
clearable
>
<el-autocomplete :popper-append-to-body="false" v-model="curForm.address" :fetch-suggestions="onAddressInput"
placeholder="请输入目标位置" :trigger-on-focus="false" @select="(item) => {
onAddressChange(item, 'end');
}
" clearable>
<template slot-scope="{ item }">
<div>
<span style="font-size: 14px; color: #9e9e9e">
{{
item.name
item.name
}}
</span>
<span style="font-size: 12px; color: #999; margin-left: 12px">{{ item.address }}</span>
......@@ -58,27 +60,23 @@
<el-input clearable v-model="curForm.label"></el-input>
</el-form-item>
<el-form-item label="航点动作">
<el-button type="text" @click="showActions = true">{{curForm.actions.length}}个动作</el-button>
<el-button type="text" @click="showActions = true">{{ curForm.actions.length }}个动作</el-button>
</el-form-item>
<el-form-item label="航线总里程">{{distance}}m</el-form-item>
<el-form-item label="预计飞行时间">{{time}}</el-form-item>
<el-form-item label="航线总里程">{{ distance }}m</el-form-item>
<el-form-item label="预计飞行时间">{{ time }}</el-form-item>
</el-form>
<div class="ae-btns">
<el-button type="primary" @click="onSave" :loading="saveLoading">保存</el-button>
<el-button type="danger" @click="onDel">删除航点</el-button>
</div>
</div>
<Actions
v-if="showActions"
@close="showActions = false"
@save="onActionsSave"
:selectActions="curForm.actions"
></Actions>
<Actions v-if="showActions" @close="showActions = false" @save="onActionsSave" :selectActions="curForm.actions">
</Actions>
</div>
</template>
<script>
import { Map, AirLine } from "../../../../../../../../../../../../api";
import { Map, AirLine, TaskInfo } from "../../../../../../../../../../../../api";
import { mapState } from "vuex";
import Utils from "../../../../../../../../../../../../components/cesiumLayer/lib/cesium/utils";
import { nanoid } from "nanoid";
......@@ -115,7 +113,9 @@ export default {
inject: ["rootNode"],
data() {
return {
orgList: [],
name: "", //航线名
departmentId: "", //部门id
form: [], //表单集合
pageIndex: 0, //当前页码
locationIcon: null, //定位图标
......@@ -158,6 +158,7 @@ export default {
},
mounted() {
let viewer = this.cesiumViewer;
this.getOrgList()
this.dataSource = new Cesium.CustomDataSource("airway_edit");
viewer.dataSources.add(this.dataSource);
this.handler = new Cesium.ScreenSpaceEventHandler(viewer.canvas); //获取事件对象
......@@ -184,6 +185,7 @@ export default {
Cesium.ScreenSpaceEventType.LEFT_CLICK
);
this.pickerPointInit();
},
beforeDestroy() {
this.handler.removeInputAction(
......@@ -201,12 +203,87 @@ export default {
this.dataSource.show = false;
},
methods: {
async getOrgList() {
let data = await TaskInfo.listAll();
let res = data.data;
const config = {
id: "id",
parentId: "parentId",
childrenList: "children",
};
const childrenListMap = {};
const nodeIds = {};
const tree = [];
for (const d of res) {
const parentId = d[config.parentId];
if (childrenListMap[parentId] == null) {
childrenListMap[parentId] = [];
}
nodeIds[d[config.id]] = d;
childrenListMap[parentId].push(d);
}
for (const d of res) {
const parentId = d[config.parentId];
if (nodeIds[parentId] == null) {
tree.push(d);
}
}
for (const t of tree) {
adaptToChildrenList(t);
}
function adaptToChildrenList(o) {
if (childrenListMap[o[config.id]] !== null) {
o[config.childrenList] = childrenListMap[o[config.id]];
}
if (o[config.childrenList]) {
for (const c of o[config.childrenList]) {
adaptToChildrenList(c);
}
}
}
this.orgList = tree;
},
convertToSeconds(timeString) {
const regex = /(\d+)\s*(小时|分钟|秒)/g;
let totalSeconds = 0;
let match;
while ((match = regex.exec(timeString)) !== null) {
const value = parseInt(match[1], 10);
const unit = match[2];
switch (unit) {
case '小时':
totalSeconds += value * 3600; // 1小时 = 3600秒
break;
case '分钟':
totalSeconds += value * 60; // 1分钟 = 60秒
break;
case '秒':
totalSeconds += value; // 直接加秒
break;
}
}
return totalSeconds;
},
changeNode() {
this.$refs.CascaderRef.dropDownVisible = false;
},
// 保存航线
async onSave() {
if (!this.name) {
this.$message.warning("请输入航线名称");
return;
}
if (!this.departmentId) {
this.$message.warning("请选择所属机构");
return;
}
if (this.form.length === 0) {
this.$message.warning("请点击地图选择航点");
return;
......@@ -248,15 +325,19 @@ export default {
content: waypoints,
distance: this.distance,
dutyOrganizationId: "",
departmentId: this.departmentId,
name: this.name,
speed: this.form[0].speed,
flyTime: this.convertToSeconds(this.time)
};
try {
let res = await AirLine.add({
flightName: airway.name || `${this.userInfo.username}-巡查}`,
pointCount: airway.content.length,
distance: airway.distance,
departmentId: airway.departmentId,
sourceType: 1,
flyTime:airway.flyTime,
linePointSaveReqVOS: airway.content.map((point) => ({
latitude: point.coordinate.latitude,
longitude: point.coordinate.longitude,
......@@ -279,7 +360,7 @@ export default {
this.$message.success("创建航线成功");
this.$emit("addDone", res.data);
this.$emit("close");
} catch (e) {}
} catch (e) { }
this.saveLoading = false;
// 通过事件创建会出现重复创建的情况, 改为标准化里创建
......@@ -302,7 +383,6 @@ export default {
* 动作保存
*/
onActionsSave(actions) {
console.log("动作", actions);
this.curForm.actions = actions;
this.showActions = false;
},
......@@ -606,8 +686,8 @@ export default {
<style lang="scss" scoped>
.airway-edit {
position: absolute;
top: -50px;
width: 450px;
top: 0px;
width: 351px;
z-index: 2;
.dialog-content {
......
......@@ -143,6 +143,7 @@ export default {
}
},
beforeDestroy() {
this.showAirwayEdit = false;
this.bus.$off("startTask", this.onStartTask);
this.clearAirwayEntities();
},
......@@ -223,7 +224,7 @@ export default {
<style lang="scss" scoped>
.taskListBox {
height: 100%;
width: 416px;
width: 100%;
background: #222222;
border-radius: 12px;
transition: 0.3s;
......
......@@ -193,7 +193,7 @@ export default {
background: rgba(9, 32, 87, 0.7);
// border: 1px solid #70daf9;
position: absolute;
top: -5px;
top: 50px;
left: 550px;
width: 512x;
z-index: 1;
......
......@@ -176,7 +176,7 @@ export default {
.task-add {
height: 250px;
position: absolute;
top: -5px;
top: 50px;
left: 550px;
width: 520px;
z-index: 1;
......
......@@ -63,7 +63,7 @@ export default {
<style lang="scss" scoped>
.task-list {
width: 416px;
width: 350px;
height: 254px;
background: #222222;
border-radius: 10px 10px 0 0;
......
......@@ -63,7 +63,7 @@ export default {
<style lang="scss" scoped>
.task-list {
width: 416px;
width: 350px;
height: 254px;
background: #222222;
border-radius: 10px 10px 0 0;
......
......@@ -200,6 +200,7 @@ export default {
width: 48px;
height: 48px;
cursor: pointer;
z-index: 1;
&::before {
font-size: 24px;
......
......@@ -15,6 +15,16 @@
<el-form-item label="航线名称" required>
<el-input clearable v-model="name"></el-input>
</el-form-item>
<el-form-item label="所属单位:" required>
<el-cascader ref="CascaderRef" v-model="departmentId" :options="orgList" clearable :show-all-levels="false"
placeholder="请选择所属单位" :props="{
children: 'children',
label: 'name',
value: 'id',
checkStrictly: true,
emitPath: false,
}" @change="changeNode"></el-cascader>
</el-form-item>
<el-form-item label="航线速度" prop="speed">
<el-input clearable v-model="curForm.speed"></el-input>
</el-form-item>
......@@ -86,7 +96,7 @@
</template>
<script>
import { Map, AirLine } from "../../../../../../../../../../api";
import { Map, AirLine,TaskInfo } from "../../../../../../../../../../api";
import { mapState } from "vuex";
import Utils from "../../../../../../../../../../components/cesiumLayer/lib/cesium/utils";
import { nanoid } from "nanoid";
......@@ -123,7 +133,9 @@ export default {
inject: ["rootNode"],
data() {
return {
orgList: [],
name: "", //航线名
departmentId:'',//部门id
flightLabel:"",//航线标签
form: [], //表单集合
pageIndex: 0, //当前页码
......@@ -168,6 +180,7 @@ export default {
},
mounted() {
let viewer = this.cesiumViewer;
this.getOrgList();
this.dataSource = new Cesium.CustomDataSource(this.dataSourceName);
viewer.dataSources.add(this.dataSource);
this.handler = new Cesium.ScreenSpaceEventHandler(viewer.canvas); //获取事件对象
......@@ -212,6 +225,77 @@ export default {
this.dataSource.show = false;
},
methods: {
changeNode() {
this.$refs.CascaderRef.dropDownVisible = false;
},
async getOrgList() {
let data = await TaskInfo.listAll();
let res = data.data;
const config = {
id: "id",
parentId: "parentId",
childrenList: "children",
};
const childrenListMap = {};
const nodeIds = {};
const tree = [];
for (const d of res) {
const parentId = d[config.parentId];
if (childrenListMap[parentId] == null) {
childrenListMap[parentId] = [];
}
nodeIds[d[config.id]] = d;
childrenListMap[parentId].push(d);
}
for (const d of res) {
const parentId = d[config.parentId];
if (nodeIds[parentId] == null) {
tree.push(d);
}
}
for (const t of tree) {
adaptToChildrenList(t);
}
function adaptToChildrenList(o) {
if (childrenListMap[o[config.id]] !== null) {
o[config.childrenList] = childrenListMap[o[config.id]];
}
if (o[config.childrenList]) {
for (const c of o[config.childrenList]) {
adaptToChildrenList(c);
}
}
}
this.orgList = tree;
},
convertToSeconds(timeString) {
const regex = /(\d+)\s*(小时|分钟|秒)/g;
let totalSeconds = 0;
let match;
while ((match = regex.exec(timeString)) !== null) {
const value = parseInt(match[1], 10);
const unit = match[2];
switch (unit) {
case '小时':
totalSeconds += value * 3600; // 1小时 = 3600秒
break;
case '分钟':
totalSeconds += value * 60; // 1分钟 = 60秒
break;
case '秒':
totalSeconds += value; // 直接加秒
break;
}
}
return totalSeconds;
},
async getLabel() {
this.rootNode.$emit("getLabelList", {
callback: (data) => {
......@@ -225,6 +309,10 @@ export default {
this.$message.warning("请输入航线名称");
return;
}
if (!this.departmentId) {
this.$message.warning("请选择所属机构");
return;
}
if (this.form.length === 0) {
this.$message.warning("请点击地图选择航点");
return;
......@@ -269,15 +357,19 @@ export default {
content: waypoints,
distance: this.distance,
dutyOrganizationId: "",
departmentId: this.departmentId, //部门id
name: this.name,
speed: this.form[0].speed,
flyTime: this.convertToSeconds(this.time)
};
try {
let res = await AirLine.add({
flightName: airway.name || `${this.userInfo.username}-巡查}`,
pointCount: airway.content.length,
distance: airway.distance,
departmentId: airway.departmentId,
sourceType: 1,
flyTime:airway.flyTime,
linePointSaveReqVOS: airway.content.map((point) => ({
latitude: point.coordinate.latitude,
longitude: point.coordinate.longitude,
......@@ -629,9 +721,8 @@ export default {
<style lang="scss" scoped>
.airway-edit {
position: absolute;
top: -50px;
width: 450px;
top: 0px;
width: 352px;
.dialog-content {
display: flex;
flex-direction: column;
......
......@@ -210,7 +210,7 @@ export default {
<style lang="scss" scoped>
.taskListBox {
height: 200px;
width: 416px;
width: 350px;
background: #222222;
border-radius: 12px;
transition: 0.3s;
......
......@@ -543,9 +543,8 @@ export default {
<style lang="scss" scoped>
.airway-edit {
position: absolute;
top: -50px;
width: 450px;
top: 0px;
width: 352px;
.dialog-content {
display: flex;
flex-direction: column;
......
......@@ -234,7 +234,7 @@ export default {
<style lang="scss" scoped>
.taskListBox {
min-height: 254px;
width: 416px;
width:350px;
background: #222222;
border-radius: 12px;
transition: 0.3s;
......
......@@ -139,6 +139,7 @@ export default {
height: 48px;
background: #ffffff;
border-radius: 2px;
top: -29px;
display: flex;
justify-content: center;
align-items: center;
......
......@@ -11,17 +11,8 @@
<div class="nset_control_box_area">
<div class="wrj">
<div class="w97 h110 item" v-if="healthData.BAT">
<img
src="./assets/images/info.png"
alt
@click="infoDetail('智能电池','BAT')"
style="cursor: pointer;"
/>
<div
class="iconfont icon-chuli"
style="color: #ffe417;"
@click="infoDetail('智能电池','BAT',true)"
/>
<img src="./assets/images/info.png" alt @click="infoDetail('智能电池', 'BAT')" style="cursor: pointer;" />
<div class="iconfont icon-chuli" style="color: #ffe417;" @click="infoDetail('智能电池', 'BAT', true)" />
<div class="content">
<img src="./assets/images/cell.png" />
<span class="dib">智能电池</span>
......@@ -33,17 +24,8 @@
<div class="type" v-else>正常</div>
</div>
<div class="w97 h110 item cp" v-if="healthData.RTK">
<img
src="./assets/images/info.png"
alt
@click="infoDetail('RTK','RTK')"
style="cursor: pointer;"
/>
<div
class="iconfont icon-chuli"
style="color: #ffe417;"
@click="infoDetail('RTK','RTK',true)"
/>
<img src="./assets/images/info.png" alt @click="infoDetail('RTK', 'RTK')" style="cursor: pointer;" />
<div class="iconfont icon-chuli" style="color: #ffe417;" @click="infoDetail('RTK', 'RTK', true)" />
<div class="content">
<img src="./assets/images/rtk.png" />
<span class="dib">RTK</span>
......@@ -55,17 +37,8 @@
<div class="type" v-else>正常</div>
</div>
<div class="w97 h110 item cp" v-if="healthData.GPS">
<img
src="./assets/images/info.png"
alt
@click="infoDetail('GPS','GPS')"
style="cursor: pointer;"
/>
<div
class="iconfont icon-chuli"
style="color: #ffe417;"
@click="infoDetail('GPS','GPS',true)"
/>
<img src="./assets/images/info.png" alt @click="infoDetail('GPS', 'GPS')" style="cursor: pointer;" />
<div class="iconfont icon-chuli" style="color: #ffe417;" @click="infoDetail('GPS', 'GPS', true)" />
<div class="content">
<img src="./assets/images/gps.png" />
<span class="dib">GPS</span>
......@@ -77,17 +50,8 @@
<div class="type" v-else>正常</div>
</div>
<div class="w97 h110 item cp" v-if="healthData.OBS">
<img
src="./assets/images/info.png"
alt
@click="infoDetail('避障','OBS')"
style="cursor: pointer;"
/>
<div
class="iconfont icon-chuli"
style="color: #ffe417;"
@click="infoDetail('避障','OBS',true)"
/>
<img src="./assets/images/info.png" alt @click="infoDetail('避障', 'OBS')" style="cursor: pointer;" />
<div class="iconfont icon-chuli" style="color: #ffe417;" @click="infoDetail('避障', 'OBS', true)" />
<div class="content">
<img src="./assets/images/obstacles.png" />
......@@ -100,17 +64,8 @@
<div class="type" v-else>正常</div>
</div>
<div class="w97 h110 item cp" v-if="healthData.VPN">
<img
src="./assets/images/info.png"
alt
@click="infoDetail('公网','VPN')"
style="cursor: pointer;"
/>
<div
class="iconfont icon-chuli"
style="color: #ffe417;"
@click="infoDetail('公网','VPN',true)"
/>
<img src="./assets/images/info.png" alt @click="infoDetail('公网', 'VPN')" style="cursor: pointer;" />
<div class="iconfont icon-chuli" style="color: #ffe417;" @click="infoDetail('公网', 'VPN', true)" />
<div class="content">
<img src="./assets/images/public.png" />
<span class="dib">公网</span>
......@@ -122,17 +77,8 @@
<div class="type" v-else>正常</div>
</div>
<div class="w97 h110 item cp" v-if="healthData.SPE">
<img
src="./assets/images/info.png"
alt
@click="infoDetail('专网','SPE')"
style="cursor: pointer;"
/>
<div
class="iconfont icon-chuli"
style="color: #ffe417;"
@click="infoDetail('专网','SPE',true)"
/>
<img src="./assets/images/info.png" alt @click="infoDetail('专网', 'SPE')" style="cursor: pointer;" />
<div class="iconfont icon-chuli" style="color: #ffe417;" @click="infoDetail('专网', 'SPE', true)" />
<div class="content">
<img src="./assets/images/pr.png" />
<span class="dib">专网</span>
......@@ -144,69 +90,36 @@
<div class="type" v-else>正常</div>
</div>
<div class="w97 h110 item cp" v-if="healthData.CHUTE">
<img
src="./assets/images/info.png"
alt
@click="infoDetail('降落伞','CHUTE')"
style="cursor: pointer;"
/>
<div
class="iconfont icon-chuli"
style="color: #ffe417;"
@click="infoDetail('降落伞','CHUTE',true)"
/>
<img src="./assets/images/info.png" alt @click="infoDetail('降落伞', 'CHUTE')" style="cursor: pointer;" />
<div class="iconfont icon-chuli" style="color: #ffe417;" @click="infoDetail('降落伞', 'CHUTE', true)" />
<div class="content">
<img src="./assets/images/san.png" />
<span class="dib">降落伞</span>
</div>
<div
class="notice"
v-if="
healthData.CHUTE && healthData.CHUTE.warningLevel != 'NORMAL'
"
>
<div class="notice" v-if="
healthData.CHUTE && healthData.CHUTE.warningLevel != 'NORMAL'
">
<div v-if="healthData.CHUTE.title.length <= 6">{{ healthData.CHUTE.title }}</div>
<marquee v-else direction="left">{{ healthData.CHUTE.title }}</marquee>
</div>
<div class="type" v-else>正常</div>
</div>
<div class="w97 h110 item cp" v-if="healthData.SPEAK">
<img
src="./assets/images/info.png"
alt
@click="infoDetail('喊话器','SPEAK')"
style="cursor: pointer;"
/>
<div
class="iconfont icon-chuli"
style="color: #ffe417;"
@click="infoDetail('喊话器','SPEAK',true)"
/>
<img src="./assets/images/info.png" alt @click="infoDetail('喊话器', 'SPEAK')" style="cursor: pointer;" />
<div class="iconfont icon-chuli" style="color: #ffe417;" @click="infoDetail('喊话器', 'SPEAK', true)" />
<div class="content">
<img src="./assets/images/speak.png" />
<span class="dib">喊话器</span>
</div>
<div
class="notice"
v-if="healthData.SPEAK && healthData.SPEAK.warningLevel != 'NORMAL'"
>
<div class="notice" v-if="healthData.SPEAK && healthData.SPEAK.warningLevel != 'NORMAL'">
<div v-if="healthData.SPEAK.title.length <= 6">{{ healthData.SPEAK.title }}</div>
<marquee v-else direction="left">{{ healthData.SPEAK.title }}</marquee>
</div>
<div class="type" v-else>正常</div>
</div>
<div class="w97 h110 item cp" v-if="healthData.NX">
<img
src="./assets/images/info.png"
alt
@click="infoDetail('NX','NX')"
style="cursor: pointer;"
/>
<div
class="iconfont icon-chuli"
style="color: #ffe417;"
@click="infoDetail('NX','NX',true)"
/>
<img src="./assets/images/info.png" alt @click="infoDetail('NX', 'NX')" style="cursor: pointer;" />
<div class="iconfont icon-chuli" style="color: #ffe417;" @click="infoDetail('NX', 'NX', true)" />
<div class="content">
<img src="./assets/images/nx.png" />
<span class="dib">NX</span>
......@@ -230,7 +143,7 @@
</div>
<div class="nest_info">
<!-- <div class="btn" @click="getInfoList">异常记录</div> -->
<div class="bat" v-if="infoName == '智能电池' ">
<div class="bat" v-if="infoName == '智能电池'">
<div class="batteryList mt16" v-for="item in batteryList" :key="item.id">
<div class="head">
<div class="line"></div>
......@@ -269,47 +182,45 @@
<div class="rtk" v-else-if="infoName == 'RTK'">
<div class="item">
<div class="title">FIX状态:</div>
<div class="ingps">{{healthData.RTK&&healthData.RTK.title||'暂无'}}</div>
<div class="ingps">{{ healthData.RTK && healthData.RTK.title || '暂无' }}</div>
</div>
<div class="item">
<div class="title">搜星数:</div>
<div class="inrtk">{{uavRealTimeData.rtk&&uavRealTimeData.rtk.satelliteCount}}</div>
<div class="inrtk">{{ uavRealTimeData.rtk && uavRealTimeData.rtk.satelliteCount }}</div>
</div>
<div class="item">
<div class="title">定位精度:</div>
<div class="inrtk">{{uavRealTimeData.rtk&&uavRealTimeData.rtk.levelDivisor}}</div>
<div class="inrtk">{{ uavRealTimeData.rtk && uavRealTimeData.rtk.levelDivisor }}</div>
</div>
</div>
<div class="gps" v-else-if="infoName == 'GPS'">
<div class="item">
<div class="title">FIX状态:</div>
<div class="ingps">{{healthData.GPS&&healthData.GPS.title||'暂无'}}</div>
<div class="ingps">{{ healthData.GPS && healthData.GPS.title || '暂无' }}</div>
</div>
<div class="item">
<div class="title">搜星数:</div>
<div class="ingps">{{uavRealTimeData.gps&&uavRealTimeData.gps.satelliteCount||'暂无'}}</div>
<div class="ingps">{{ uavRealTimeData.gps && uavRealTimeData.gps.satelliteCount || '暂无' }}</div>
</div>
<div class="item">
<div class="title">定位精度:</div>
<div class="ingps">{{uavRealTimeData.gps&&uavRealTimeData.gps.levelDivisor||'暂无'}}</div>
<div class="ingps">{{ uavRealTimeData.gps && uavRealTimeData.gps.levelDivisor || '暂无' }}</div>
</div>
</div>
<div class="public" v-else-if="infoName == '专网'">
<div class="pu">
<div class="item">
<div class="title">专网信号质量:</div>
<div class="inpublic">{{healthData.SPE&&healthData.SPE.title||'暂无'}}</div>
<div class="inpublic">{{ healthData.SPE && healthData.SPE.title || '暂无' }}</div>
</div>
<div class="item">
<div class="title">消息类型:</div>
<div
class="inpublic"
:style="{'color':healthData.SPE&&warningLevel[healthData.SPE.warningLevel].color}"
>{{healthData.SPE&&warningLevel[healthData.SPE.warningLevel].title||'暂无'}}</div>
<div class="inpublic" :style="{ 'color': healthData.SPE && warningLevel[healthData.SPE.warningLevel].color }">
{{ healthData.SPE && warningLevel[healthData.SPE.warningLevel].title || '暂无' }}</div>
</div>
<div class="item">
<div class="title">描述:</div>
<div class="inpublic">{{healthData.SPE&&healthData.SPE.description||'暂无'}}</div>
<div class="inpublic">{{ healthData.SPE && healthData.SPE.description || '暂无' }}</div>
</div>
</div>
</div>
......@@ -318,18 +229,16 @@
<div class="pr">
<div class="item">
<div class="title">公网信号质量:</div>
<div class="inpublic">{{healthData.VPN&&healthData.VPN.title||'暂无'}}</div>
<div class="inpublic">{{ healthData.VPN && healthData.VPN.title || '暂无' }}</div>
</div>
<div class="item">
<div class="title">消息类型:</div>
<div
class="inpublic"
:style="{'color':healthData.VPN&&warningLevel[healthData.VPN.warningLevel].color}"
>{{healthData.VPN&&warningLevel[healthData.VPN.warningLevel].title||'暂无'}}</div>
<div class="inpublic" :style="{ 'color': healthData.VPN && warningLevel[healthData.VPN.warningLevel].color }">
{{ healthData.VPN && warningLevel[healthData.VPN.warningLevel].title || '暂无' }}</div>
</div>
<div class="item">
<div class="title">描述:</div>
<div class="inpublic">{{healthData.VPN&&healthData.VPN.description||'暂 无'}}</div>
<div class="inpublic">{{ healthData.VPN && healthData.VPN.description || '暂 无' }}</div>
</div>
</div>
</div>
......@@ -337,26 +246,22 @@
<div class="pu">
<div class="item">
<div class="title">避障状态:</div>
<div class="inpublic">{{healthData.OBS &&healthData.OBS.title||'暂 无'}}</div>
<div class="inpublic">{{ healthData.OBS && healthData.OBS.title || '暂 无' }}</div>
</div>
<div class="item">
<div class="title">消息类型:</div>
<div
class="inpublic"
:style="{'color':healthData.OBS&&warningLevel[healthData.OBS.warningLevel].color}"
>{{healthData.OBS&&warningLevel[healthData.OBS.warningLevel].title||'暂无'}}</div>
<div class="inpublic" :style="{ 'color': healthData.OBS && warningLevel[healthData.OBS.warningLevel].color }">
{{ healthData.OBS && warningLevel[healthData.OBS.warningLevel].title || '暂无' }}</div>
</div>
<div class="item">
<div class="title">是否触发:</div>
<div
class="inpublic"
>{{uavRealTimeData.obstacles&&uavRealTimeData.obstacles.enable? '触发避障':'未触发'}}</div>
<div class="inpublic">{{ uavRealTimeData.obstacles && uavRealTimeData.obstacles.enable ? '触发避障' : '未触发' }}</div>
</div>
</div>
<div class="pr">
<div class="item">
<div class="title">描述:</div>
<div class="inpr">{{healthData.OBS&&healthData.OBS.description||'暂 无'}}</div>
<div class="inpr">{{ healthData.OBS && healthData.OBS.description || '暂 无' }}</div>
</div>
</div>
</div>
......@@ -364,20 +269,19 @@
<div class="pu">
<div class="item">
<div class="title">状态:</div>
<div class="inpublic">{{healthData.CHUTE&&healthData.CHUTE.title||'暂 无'}}</div>
<div class="inpublic">{{ healthData.CHUTE && healthData.CHUTE.title || '暂 无' }}</div>
</div>
<div class="item">
<div class="title">消息类型:</div>
<div
class="inpublic"
:style="{'color':healthData.CHUTE&&warningLevel[healthData.CHUTE.warningLevel].color}"
>{{healthData.CHUTE&&warningLevel[healthData.CHUTE.warningLevel].title||'暂无'}}</div>
<div class="inpublic"
:style="{ 'color': healthData.CHUTE && warningLevel[healthData.CHUTE.warningLevel].color }">
{{ healthData.CHUTE && warningLevel[healthData.CHUTE.warningLevel].title || '暂无' }}</div>
</div>
</div>
<div class="pr">
<div class="item">
<div class="title">描述:</div>
<div class="inpr">{{healthData.CHUTE&&healthData.CHUTE.description||'暂 无'}}</div>
<div class="inpr">{{ healthData.CHUTE && healthData.CHUTE.description || '暂 无' }}</div>
</div>
</div>
</div>
......@@ -385,38 +289,35 @@
<div class="pu">
<div class="item">
<div class="title">状态:</div>
<div class="inpublic">{{healthData.SPEAK&&healthData.SPEAK.title||'暂 无'}}</div>
<div class="inpublic">{{ healthData.SPEAK && healthData.SPEAK.title || '暂 无' }}</div>
</div>
<div class="item">
<div class="title">消息类型:</div>
<div
class="inpublic"
:style="{'color':healthData.SPEAK&&warningLevel[healthData.SPEAK.warningLevel].color}"
>{{healthData.SPEAK&&warningLevel[healthData.SPEAK.warningLevel].title||'暂无'}}</div>
<div class="inpublic"
:style="{ 'color': healthData.SPEAK && warningLevel[healthData.SPEAK.warningLevel].color }">
{{ healthData.SPEAK && warningLevel[healthData.SPEAK.warningLevel].title || '暂无' }}</div>
</div>
</div>
<div class="pr">
<div class="item">
<div class="title">描述:</div>
<div class="inpr">{{healthData.SPEAK&&healthData.SPEAK.description||'暂 无'}}</div>
<div class="inpr">{{ healthData.SPEAK && healthData.SPEAK.description || '暂 无' }}</div>
</div>
</div>
</div>
<div class="rtk" v-else-if="infoName == 'NX'">
<div class="item">
<div class="title">NX状态:</div>
<div class="ingps">{{healthData.NX&&healthData.NX.title||'暂无'}}</div>
<div class="ingps">{{ healthData.NX && healthData.NX.title || '暂无' }}</div>
</div>
<div class="item">
<div class="title">消息类型:</div>
<div
class="inpublic"
:style="{'color':healthData.NX&&warningLevel[healthData.NX.warningLevel].color}"
>{{healthData.NX&&warningLevel[healthData.NX.warningLevel].title||'暂无'}}</div>
<div class="inpublic" :style="{ 'color': healthData.NX && warningLevel[healthData.NX.warningLevel].color }">
{{ healthData.NX && warningLevel[healthData.NX.warningLevel].title || '暂无' }}</div>
</div>
<div class="item">
<div class="title">描述:</div>
<div class="inrtk">{{healthData.NX&&healthData.NX.description||'暂无'}}</div>
<div class="inrtk">{{ healthData.NX && healthData.NX.description || '暂无' }}</div>
</div>
</div>
<Logs v-else :type="type"></Logs>
......@@ -512,7 +413,7 @@ export default {
message: {},
};
},
beforeDestroy() {},
beforeDestroy() { },
methods: {
// flag 为true 代表展示异常信息
infoDetail(name, val, flag) {
......@@ -524,7 +425,7 @@ export default {
this.infoShow = false;
this.infoName = "";
},
async addMessage() {},
async addMessage() { },
},
mounted() {
console.log(this.healthData, "healthData");
......@@ -564,14 +465,12 @@ export default {
color: #14faff;
line-height: 26px;
text-shadow: 0px 1px 1px rgba(2, 32, 56, 0.2);
background: linear-gradient(
135deg,
#e3aa77 0%,
#f5cda9 38%,
#f9ecd3 58%,
#fcdbb1 79%,
#edb07a 100%
);
background: linear-gradient(135deg,
#e3aa77 0%,
#f5cda9 38%,
#f9ecd3 58%,
#fcdbb1 79%,
#edb07a 100%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
......@@ -591,10 +490,9 @@ export default {
height: 258px;
overflow: auto;
display: flex;
// justify-content: space-between;
flex-wrap: wrap;
padding: 16px;
gap: 16px;
justify-content: space-around;
margin-top: 10px;
.item {
position: relative;
......@@ -605,17 +503,21 @@ export default {
display: flex;
flex-direction: column;
align-items: center;
width: 97px;
flex: 0 0 calc(33.33% - 32px);
/* 32px是左右padding的总和 */
height: 110px;
&:hover {
background: url("./assets/images/checkbg.png") no-repeat;
background-size: 100% 100%;
}
> img {
>img {
position: absolute;
right: 3px;
top: 3px;
}
.content {
width: 100%;
height: 82px;
......@@ -624,8 +526,9 @@ export default {
justify-content: end;
align-items: center;
margin-bottom: 10px;
img {
}
img {}
.dib {
margin-top: 6px;
font-size: 12px;
......@@ -634,6 +537,7 @@ export default {
color: #ffffff;
}
}
.type {
width: calc(100% - 2px);
text-align: center;
......@@ -646,6 +550,7 @@ export default {
color: #36e81a;
border-radius: 0 0 4.5px 4.5px;
}
.notice {
width: calc(100% - 2px);
text-align: center;
......@@ -658,10 +563,12 @@ export default {
color: #fff;
border-radius: 0 0 4.5px 4.5px;
}
.iconfont {
margin-top: 8px;
}
}
.item:nth-of-type(4n) {
margin-right: 0;
}
......@@ -673,8 +580,10 @@ export default {
cursor: pointer;
}
}
.nest_info {
padding: 16px;
.btn {
width: 80px;
height: 28px;
......@@ -686,18 +595,22 @@ export default {
text-align: center;
line-height: 28px;
}
.bat {
.batteryList {
display: flex;
flex-direction: column;
.head {
display: flex;
.line {
width: 4px;
height: 16px;
background: #ffd800;
border-radius: 2px;
}
.name {
margin-left: 4px;
font-size: 16px;
......@@ -705,19 +618,23 @@ export default {
color: #fff;
}
}
.center {
display: flex;
flex-wrap: wrap;
justify-content: start;
.item {
display: flex;
flex-wrap: nowrap;
.title {
white-space: nowrap;
font-size: 14px;
font-weight: 500;
color: #fff;
}
.indo {
font-size: 16px;
font-weight: 500;
......@@ -727,21 +644,25 @@ export default {
}
}
}
.rtk,
.gps {
margin-top: 16px;
display: flex;
justify-content: space-between;
.item {
display: flex;
flex-wrap: nowrap;
align-items: baseline;
.title {
white-space: nowrap;
font-size: 14px;
font-weight: 500;
color: #fff;
}
.ingps,
.inrtk {
font-size: 16px;
......@@ -750,24 +671,29 @@ export default {
}
}
}
.public {
display: flex;
flex-direction: column;
.pu,
.pr {
margin-top: 16px;
display: flex;
justify-content: space-between;
.item {
display: flex;
flex-wrap: nowrap;
align-items: baseline;
.title {
white-space: nowrap;
font-size: 14px;
font-weight: 500;
color: #fff;
}
.inpublic,
.inpr {
font-size: 16px;
......@@ -778,6 +704,7 @@ export default {
}
}
}
.list {
position: fixed;
top: calc(50% + 90px);
......@@ -788,16 +715,15 @@ export default {
border-radius: 10px;
border: 1px solid rgba(26, 92, 246, 0.5);
backdrop-filter: blur(1px);
.nset_control_box_header {
display: flex;
justify-content: space-between;
height: 32px;
background: linear-gradient(
180deg,
#9198ff 0%,
rgba(45, 81, 153, 0.45) 40%,
#05091a 100%
);
background: linear-gradient(180deg,
#9198ff 0%,
rgba(45, 81, 153, 0.45) 40%,
#05091a 100%);
box-shadow: inset 0px 0px 10px 2px #3f9dff;
border-radius: 10px 10px 0px 0px;
border: 1px solid #427dff;
......
......@@ -2,15 +2,10 @@
<div class="mountBox">
<div class="main" v-if="show">
<div v-if="mountList.length > 0" class="list">
<div
class="mount-item pr mt6"
:class="{
active:
(selectMount && selectMount.gimbalName) === item.gimbalName,
}"
v-for="(item, index) in mountList"
:key="index"
>
<div class="mount-item pr mt6" :class="{
active:
(selectMount && selectMount.gimbalName) === item.gimbalName,
}" v-for="(item, index) in mountList" :key="index">
<div class="icon-box" @click="onSelectMount(item)">
<img class :src="item.icon" />
</div>
......@@ -18,17 +13,9 @@
</div>
</div>
<template v-if="selectMount">
<component
:is="selectMount.gimbalName"
v-if="selectMount"
class="mount-panel"
:keyFlag="nxNormal"
:payload_data="selectMountPayload"
@directive="mountDirective"
@take_photo="mountTakePhoto"
@record="mountRecord"
@close="mountClose"
/>
<component :is="selectMount.gimbalName" v-if="selectMount" class="mount-panel" :keyFlag="nxNormal"
:payload_data="selectMountPayload" @directive="mountDirective" @take_photo="mountTakePhoto"
@record="mountRecord" @close="mountClose" />
</template>
</div>
</template>
......@@ -48,6 +35,11 @@ export default {
...mountComponents,
},
props: {
// 是否机库页面使用
isHangar: {
type: Boolean,
default: false,
},
show: {
type: Boolean,
default: false,
......@@ -78,11 +70,30 @@ export default {
return this.uavRealTimeData?.healthData?.NX?.warningLevel === "NORMAL";
},
},
created() {},
mounted() {},
beforeDestroy() {},
created() { },
mounted() { },
beforeDestroy() { },
methods: {
onSelectMount(item) {
/**
* 接管判断, 机库模块中不需要判断接管
*/
async isTakeOver() {
if (this.isHangar) {
return await this.$store.dispatch(
"MMCFlightControlCenter/hangar/isTakeOver"
);
} else {
return await this.$store.dispatch(
"MMCFlightControlCenter/uav/isTakeOver"
);
}
},
async onSelectMount(item) {
// 判断是否已接管
if (!(await this.isTakeOver())) {
this.$message.warning("请先接管设备");
return;
}
this.$store.commit("MMCFlightControlCenter/uav/setState", {
key: "selectMount",
value: item,
......
......@@ -2,72 +2,38 @@
<div class="control-right">
<!-- 挂载-警灯-无人机 -->
<div class="control-list" style="top: 13%">
<div
class="control-item"
:class="showHealth ? 'active' : ''"
@click="onSwitchShow('showHealth')"
>
<img :class="{active:showHealth}" src="./assets/images/health.svg" />
<div class="control-item" :class="showHealth ? 'active' : ''" @click="onSwitchShow('showHealth')">
<img :class="{ active: showHealth }" src="./assets/images/health.svg" />
<span class="">健康管理</span>
</div>
<!-- 机库信息 -->
<slot name="hangar"></slot>
<div
class="control-item"
:class="showMount ? 'active' : ''"
@click="onSwitchShow('showMount')"
>
<img :class="{active:showMount}" src="./assets/images/mount.svg" />
<div class="control-item" :class="showMount ? 'active' : ''" @click="onSwitchShow('showMount')">
<img :class="{ active: showMount }" src="./assets/images/mount.svg" />
<span class="">挂载</span>
</div>
<div
class="control-item"
:class="showControlList ? 'active' : ''"
@click="onSwitchShow('showControlList')"
>
<img :class="{active:showControlList}" src="./assets/images/uav.svg" />
<div class="control-item" :class="showControlList ? 'active' : ''" @click="onSwitchShow('showControlList')">
<img :class="{ active: showControlList }" src="./assets/images/uav.svg" />
<span class="">无人机</span>
</div>
<div
v-if="!isHangar && uav.network === 2"
class="control-item"
:class="showAlarmLamp ? 'active' : ''"
@click="onSwitchShow('showAlarmLamp')"
>
<img :class="{active:showAlarmLamp}" src="./assets/images/lamp.svg" />
<div v-if="!isHangar && uav.network === 2" class="control-item" :class="showAlarmLamp ? 'active' : ''"
@click="onSwitchShow('showAlarmLamp')">
<img :class="{ active: showAlarmLamp }" src="./assets/images/lamp.svg" />
<span class="">警灯</span>
</div>
<div
class="control-item"
:class="showViewLib ? 'active' : ''"
@click="onSwitchShow('showViewLib')"
>
<img :class="{active:showViewLib}" src="./assets/images/files.svg" />
<div class="control-item" :class="showViewLib ? 'active' : ''" @click="onSwitchShow('showViewLib')">
<img :class="{ active: showViewLib }" src="./assets/images/files.svg" />
<span class="">视图库</span>
</div>
<ViewLib v-if="showViewLib"></ViewLib>
</div>
<ControlList
@clearId="$emit('clearId')"
@closeIconShow="iconShow = false"
@exit="showControlList = false"
:show="showControlList"
:isHangar="isHangar"
></ControlList>
<ControlList @clearId="$emit('clearId')" @closeIconShow="iconShow = false" @exit="showControlList = false"
:show="showControlList" :isHangar="isHangar"></ControlList>
<Health v-if="showHealth" @exit="showHealth = false"></Health>
<Mount v-if="showMount" :show="showMount"></Mount>
<Mount v-if="showMount" :isHangar="isHangar" :show="showMount"></Mount>
<!-- 喊话器 -->
<MMCGimbalP1
class="PagerP1"
v-show="showMMCGimbalP1"
ref="MMCGimbalP1"
@close="showMMCGimbalP1 = false"
/>
<MountController
@webscoketFn="(data) => fun(data)"
v-if="uav && uav.deviceId"
ref="MountControllerRef"
/>
<MMCGimbalP1 class="PagerP1" v-show="showMMCGimbalP1" ref="MMCGimbalP1" @close="showMMCGimbalP1 = false" />
<MountController @webscoketFn="(data) => fun(data)" v-if="uav && uav.deviceId" ref="MountControllerRef" />
<AlarmLamp v-if="showAlarmLamp" :uav="uav" @close="showAlarmLamp = false" />
<slot name="dialog"></slot>
</div>
......@@ -118,8 +84,8 @@ export default {
},
watch: {
// 打开航线编辑时关闭所有窗口
showAirwayEdit(newVal){
if(newVal){
showAirwayEdit(newVal) {
if (newVal) {
this.showAlarmLamp = false;
this.showHealth = false;
this.showMMCGimbalP1 = false;
......@@ -130,6 +96,20 @@ export default {
}
},
methods: {
/**
* 接管判断, 机库模块中不需要判断接管
*/
async isTakeOver() {
if (this.isHangar) {
return await this.$store.dispatch(
"MMCFlightControlCenter/hangar/isTakeOver"
);
} else {
return await this.$store.dispatch(
"MMCFlightControlCenter/uav/isTakeOver"
);
}
},
hideAll(key) {
let arr = [
"showAlarmLamp",
......@@ -148,7 +128,15 @@ export default {
/**
* 切换展示
*/
onSwitchShow(key) {
async onSwitchShow(key) {
if (key == 'showHealth' && !this?.uav?.isOnline) {
return this.$message.info('无人机不在线!');
}
// 判断是否已接管
if (!(await this.isTakeOver())) {
this.$message.warning("请先接管设备");
return;
}
this.$emit("switchCallback");
this.hideAll(key);
this[key] = !this[key];
......@@ -185,7 +173,7 @@ export default {
box-sizing: border-box;
overflow: hidden;
> img {
>img {
width: 24px;
}
......@@ -197,6 +185,7 @@ export default {
border: 1px solid #3C3C3C;
color: #3388ff;
}
.active {
filter: drop-shadow(#3388ff 100px 0);
transform: translateX(-100px);
......
......@@ -481,6 +481,7 @@ export default {
align-items: center;
font-family: MicrosoftYaHei;
font-size: 16px;
z-index: 2;
color: #ffffff;
line-height: 21px;
padding: 0 4px;
......
# vue2
# node版本 >= 18.12.0
## Project setup
```
yarn install
......
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论