提交 8cd66e52 作者: 翁进城

Merge branch 'v4' into v4_master

......@@ -233,8 +233,6 @@ export default {
</script>
<style lang="scss" scoped>
.cesium_layerBox {
}
.cpt-cesium_layer::v-deep {
width: 100%;
......@@ -254,6 +252,10 @@ export default {
.cesium-viewer-navigationContainer {
display: none;
}
.cesium-credit-logoContainer {
display: none;
}
}
.videoWallMapStyle {
......
<template>
<div class="car dialog1027" v-interact>
<div class="dialog-header">
<div class="dialog-header__icon" />
<div class="dialog-header__title">
快速建模
</div>
<div class="dialog-header_close" style="color:#fff" @click="() => $emit('close')">关闭</div>
</div>
<div class="dialog-content w267">
<el-cascader size="mini" filterable popper-class="cpt-observe-mspace-dashboard-airway_popper" v-model="taskCateId"
:options="airway_list" clearable :show-all-levels="false" placeholder="请选择任务" :props="{
children: 'children',
label: 'taskTitle',
value: 'id',
emitPath: false,
}">
<template slot-scope="{ data }">
<el-tooltip :disabled="data.taskTitle.length < 11" class="item" effect="dark" :content="data.taskTitle"
placement="top-start">
<span>{{ data.taskTitle }}</span>
</el-tooltip>
</template>
</el-cascader>
<el-select class="mt10" v-model="type" size="mini" placeholder="请选择类型">
<el-option label="图片" :value="0"></el-option>
<el-option label="视频" :value="1"></el-option>
</el-select>
<div class="jcsb w267 h30 mt30">
<div class="dec mt5">1</div><span class="dib cf ml10 lh30"> 快速建模</span>
<div class="btn fr cf h30 lh30 w80 cp" @click="jmFn(1)">启动</div>
</div>
<div class="jcsb mt18 w267 h30">
<div class="dec mt5">2</div><span class="dib cf lh30 ml10">数据处理</span>
<div class="btn fr cf h30 lh30 w80 cp" @click="jmFn(2)">启动</div>
</div>
</div>
</div>
</template>
<script>
// import API from '@/api';
export default {
props: {
device: {
type: Object,
default: () => ({})
},
},
data() {
return {
imgUrl: process.env.VUE_APP_IMG_URL,
list: [],
type: null,
taskCateId: null,
airway_list: []
}
},
created() {
this.list_airway();
},
methods: {
jmFn(num) {
let { deviceHardId } = this.device
if (num == 1) {
let a = document.createElement("a");
a.href = `MMCEagleEye:// `
a.click()
}
else {
if(!this.taskCateId) return this.$message.warning('请选择任务!')
if(this.type==null ) return this.$message.warning('请选择类型!')
let a = document.createElement("a");
a.href = `MMCPosTool://&deviceId=${deviceHardId}enddeviceId&taskId=${this.taskCateId}endtaskId&type=${this.type}endtype`
a.click()
}
},
async list_airway() {
/* let res = await API.AIRWAY.getApprovedTask();
if (res) {
let jqList = [],
ctList = [],
lsList = [];
for (let i = 0; i < res.length; i++) {
if (res[i].taskCateId == 1) {
jqList.push(res[i]);
}
if (res[i].taskCateId == 2) {
ctList.push(res[i]);
}
if (res[i].taskCateId == 3) {
lsList.push(res[i]);
}
}
let airway_list = [
{
id: "警情任务",
taskTitle: "警情任务",
children: jqList,
},
{
id: "常态任务",
taskTitle: "常态任务",
children: ctList,
},
{
id: "临时任务",
taskTitle: "临时任务",
children: lsList,
},
];
this.airway_list = airway_list;
} */
},
}
}
</script>
<style lang="scss" scoped>
.car {
width: 268px;
}
.dialog-content {
padding: 20px 14px 12px;
max-height: 461px;
overflow: auto;
.dec {
width: 20px;
height: 20px;
line-height: 20px;
text-align: center;
border-radius: 50%;
background: #06199b;
}
.btn {
text-align: center;
border: 1px #315ec7 solid;
border-radius: 3px;
background-color: #02173d;
font-size: 14px;
font-family: MicrosoftYaHei;
color: #D2D9FF;
cursor: pointer;
}
.btn:hover {
background: #06199b;
}
}
.car-img {
position: relative;
width: 100%;
height: 135px;
.car-img__img {
width: 100%;
height: 100%;
}
.car-img__label {
position: absolute;
bottom: 0;
width: 100%;
height: 28px;
display: flex;
justify-content: center;
align-items: center;
font-size: 14px;
color: #aee9ff;
font-family: MicrosoftYaHeiUI;
}
}
.car-form {
padding: 10px 0 0;
font-size: 14px;
font-family: MicrosoftYaHei;
color: #fff;
>div {
margin-bottom: 8px;
&:last-child {
margin-bottom: 0;
}
}
}
.car-item {
margin-bottom: 24px;
}
</style>
\ No newline at end of file
......@@ -264,10 +264,10 @@ export default {
speed: point.speed,
pointActionSaveReqVOS: point.waypointActions.map((action) => {
let actionValue = [];
actionValue.push(`param1:${action.param1 || ""}`);
actionValue.push(`param2:${action.param2 || ""}`);
actionValue.push(`param3:${action.param3 || ""}`);
actionValue.push(`param4:${action.param4 || ""}`);
action.param1 && actionValue.push(`param1:${action.param1 || ""}`);
action.param2 && actionValue.push(`param2:${action.param2 || ""}`);
action.param3 && actionValue.push(`param3:${action.param3 || ""}`);
action.param4 && actionValue.push(`param4:${action.param4 || ""}`);
return {
actionType: action.actionType,
actionValue: actionValue.join(";"),
......
<template>
<div class="car dialog1027" v-interact>
<div class="dialog-header">
<div class="dialog-header__icon" />
<div class="dialog-header__title">
车辆识别
</div>
<div class="dialog-header_close" style="color:#fff" @click="()=>$emit('close')">关闭</div>
</div>
<div class="dialog-content" v-infinite-scroll="load">
<template v-if="list.length > 0" >
<div v-for="(item, i) in list" :key="i" class="car-item">
<div class="car-img">
<img class="car-img__img" :src="imgUrl + item.imageUrl" />
<div class="car-img__label">{{ item.plateNum || '暂无' }}</div>
</div>
<div class="car-form">
<div>地点:{{ item.addr || item.findAddress || '暂无' }}</div>
<div>时间:{{ item.findTime || '暂无' }}</div>
</div>
</div>
</template>
<template v-else>
<div style="text-align: center; width: 100%;">暂无数据</div>
</template>
</div>
</div>
</template>
<script>
// import API from '@/api';
export default {
props: {
uavId: {
type: String,
default: ''
}
},
data(){
return {
imgUrl: process.env.VUE_APP_IMG_URL,
list: [],
pageNo: 1,
pageSize: 3,
}
},
created(){
this.getCarList()
},
methods: {
async load(){
this.pageNo++
/* let res = await API.HOME.getflightvideoMsg({
uavId: this.uavId,
pageNo: this.pageNo,
pageSize: this.pageSize
})
for(let i = 0; i < res.length; i++){
let item = res[i];
if(item.lon){
let address = await API.MAP.AiRegeo({
location: `${item.lon},${item.lat}`
})
item.addr = address.province.value + address.city.value + address.dist.value + address.road.roadname + address.poi;
}
this.list.push(res[i])
}
console.log(this.list,"list"); */
},
async getCarList(){
if(!this.uavId){
this.$message.error('请选择无人机');
return;
}
let res = await API.HOME.getflightvideoMsg({
uavId: this.uavId,
pageNo: this.pageNo,
pageSize: this.pageSize
})
for(let i = 0; i < res.length; i++){
let item = res[i];
if(item.lon){
let address = await API.MAP.AiRegeo({
location: `${item.lon},${item.lat}`
})
item.addr = address.province.value + address.city.value + address.dist.value + address.road.roadname + address.poi;
}
this.list.push(res[i])
}
// this.list = res || [];
}
}
}
</script>
<style lang="scss" scoped>
.car{
width: 268px;
}
.dialog-content{
padding: 20px 14px 12px;
max-height: 461px;
overflow: auto;
}
.car-img{
position: relative;
width: 100%;
height: 135px;
.car-img__img {
width: 100%;
height: 100%;
}
.car-img__label {
position: absolute;
bottom: 0;
width: 100%;
height: 28px;
display: flex;
justify-content: center;
align-items: center;
font-size: 14px;
color: #aee9ff;
font-family: MicrosoftYaHeiUI;
}
}
.car-form{
padding: 10px 0 0;
font-size: 14px;
font-family: MicrosoftYaHei;
color: #fff;
>div {
margin-bottom: 8px;
&:last-child {
margin-bottom: 0;
}
}
}
.car-item{
margin-bottom: 24px;
}
</style>
\ No newline at end of file
<template>
<div class="face dialog1027" v-interact>
<div class="dialog-header">
<div class="dialog-header__icon" />
<div class="dialog-header__title">
人脸识别
</div>
<div class="dialog-header_close" style="color:#fff" @click="()=>$emit('close')">关闭</div>
</div>
<div class="dialog-content" v-infinite-scroll="load">
<template v-if="list.length > 0">
<div class="result" v-for="(item, i) in list" :key="i">
<div class="rate-box">
<div class="rate-img">
<img :src="imgUrl + item.recordImageUrl" />
</div>
<div class="rate-round">
<div class="rate-round__value">{{ Number(item.similarity).toFixed(2) }}%</div>
<div class="rate-routd__text" @click="onDetail(item)">详情</div>
</div>
<div class="rate-img rate-img--contrary">
<img :src="imgUrl + item.snapImageUrl" />
</div>
</div>
<div class="rate-form" v-if="item.show">
<div class="rate-form-item">
<div class="rate-form-item__label">
姓名:
</div>
<div class="rate=form-item__value">
{{ item.userName || '暂无' }}
</div>
</div>
<div class="rate-form-item">
<div class="rate-form-item__label">
出生年份:
</div>
<div class="rate=form-item__value">
{{ item.birthday || '暂无' }}
</div>
</div>
<div class="rate-form-item">
<div class="rate-form-item__label">
发现时间:
</div>
<div class="rate=form-item__value">
{{ item.occurTime || '暂无' }}
</div>
</div>
<div class="rate-form-item">
<div class="rate-form-item__label">
发现地点:
</div>
<div class="rate=form-item__value">
{{ item.addr || item.address || '暂无' }}
</div>
</div>
<div class="rate-form-item">
<div class="rate-form-item__label">
身份证号:
</div>
<div class="rate=form-item__value">
{{ item.idCard || '暂无' }}
</div>
</div>
<div class="rate-form-item">
<div class="rate-form-item__label">
AI识别:
</div>
<div class="rate=form-item__value">
<template v-if="item.labels && item.labels.length">
<div class="round-border" v-for="(label, j) in item.labels" :key="j" >
{{label}}
</div>
</template>
<template v-else>
暂无
</template>
</div>
</div>
</div>
</div>
</template>
<template v-else>
<div style="text-align: center; width: 100%;">暂无数据</div>
</template>
</div>
</div>
</template>
<script>
// import API from '@/api';
export default {
props: {
uavId: {
type: String,
default: ''
}
},
data(){
return {
imgUrl: process.env.VUE_APP_IMG_URL,
list: [
/* {
userName: '人热二',
birthday: '1888-02-11',
occurTime: '2022-02-30 08:22:14',
address: '深圳市南山区',
idCard: '112313123123',
labels: ['省内人员'],
similarity: '63',
img: '',
imgs: '',
show: true
} */
],
pageNo: 1,
pageSize: 4,
}
},
created(){
this.getFaceList();
},
methods: {
async load(){
this.pageNo++
/* let res = await API.HOME.getFaceuavvideoMsg({
uavId: this.uavId,
pageNo: this.pageNo,
pageSize: this.pageSize
})
for(let i = 0; i < res.length; i++){
let item = res[i];
if(item.longi){
let address = await API.MAP.AiRegeo({
location: `${item.longi},${item.lati}`
})
item.addr = address.province.value + address.city.value + address.dist.value + address.road.roadname + address.poi;
}
this.list.push(res[i])
}
console.log(this.list,"list"); */
},
async getFaceList(){
if(!this.uavId){
this.$message.error('请选择无人机');
return;
}
let res = await API.HOME.getFaceuavvideoMsg({
uavId: this.uavId,
pageNo: this.pageNo,
pageSize: this.pageSize
}) || [];
for(let i = 0; i < res.length; i++){
let item = res[i];
if(item.longi){
let address = await API.MAP.AiRegeo({
location: `${item.longi},${item.lati}`
})
item.addr = address.province.value + address.city.value + address.dist.value + address.road.roadname + address.poi;
}
this.list.push(res[i])
}
// this.list = res || [];
},
onDetail(item){
this.$set(item, 'show', !item.show);
}
}
}
</script>
<style lang="scss" scoped>
.face{
width: 268px;
}
.dialog-content{
padding: 14px;
cursor: initial;
max-height: 461px;
overflow-y: auto;
}
.result{
width: 100%;
margin-top: 27px;
&:first-child {
margin-top: 0;
}
}
.rate-box{
display: flex;
align-items: center;
position: relative;
width: 100%;
.rate-img{
flex: 1;
height: 75px;
background-image: url('../../assets/images/faceAI_border1.png');
background-size: 100% 100%;
padding: 7px;
display: flex;
align-items: center;
&.rate-img--contrary {
background-image: url('../../assets/images/faceAI_border2.png');
justify-content: right;
}
img {
width: 70px;
height: 70px;
border-radius: 7px;
overflow: hidden;
}
}
.rate-round{
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
.rate-round__value{
color: #fb799d;
font-size: 14px;
font-family: MicrosoftYaHei;
}
.rate-routd__text{
cursor: pointer;
font-size: 12px;
color: #b9d7f0;
font-family: MicrosoftYaHei;
transform: scale(0.9);
margin-top: 3px;
}
}
}
.rate-form{
margin-top: 10px;
font-size: 14px;
font-family: MicrosoftYaHei;
color: #fff;
.rate-form-item {
margin-bottom: 12px;
display: flex;
&:last-child {
margin-bottom: 0;
}
.rate-form-item__label {
width: 70px;
text-align: right;
flex-shrink: 0;
}
.rate-form-item__value {
}
}
}
.round-border{
padding: 2px 8px;
border-radius: 11px;
border: 1px solid #ff4a4a;
color: #ff4a4a;
font-size: 14px;
font-family: MicrosoftYaHei;
}
</style>
\ No newline at end of file
......@@ -35,7 +35,7 @@ export default {
// console.log('livenvr', value)
if (newVal ) {
this.$nextTick(() => {
this.$refs["livePlayer"].play();
this.$refs["livePlayer"]?.play();
});
}
},
......
......@@ -17,13 +17,12 @@ export default {
computed: {
...mapState("MMCFlightControlCenter/hangar", ["hangar"]),
name() {
return `${this.hangar?.name || ""}机库`
// return `${this.hangar?.name || ""}机库无人机`;
return `${this.hangar?.name || ""}`;
},
url() {
let find = this.hangar?.streamConfiguration
?.find((v) => v.urlType === 1)
return find?.originalUrl || '';
return find?.originalUrl || find?.lowLatencyUrl || find?.fluencyUrl || '';
},
},
};
......
......@@ -17,13 +17,12 @@ export default {
computed: {
...mapState("MMCFlightControlCenter/hangar", ["hangar"]),
name() {
return `${this.hangar?.name || ""}机库`;
// return `${this.hangar?.name || ""}机库无人机`;
return `${this.hangar?.name || ""}`;
},
url() {
let find = this.hangar?.streamConfiguration
?.find((v) => v.urlType === 2)
return find?.originalUrl || '';
return find?.originalUrl || find?.lowLatencyUrl || find?.fluencyUrl || '';
},
},
methods: {},
......
......@@ -41,8 +41,7 @@ export default {
]),
...mapState("MMCFlightControlCenter/uav", ["uav"]),
name() {
return `${this.hangar?.name || ""}机库`;
// return `${this.hangar?.name || ""}机库无人机`;
return `${this.uav?.name || ""}`;
},
label() {
return this.hangar?.uav?.organizationName || "";
......
<template>
<div class="traffic dialog1027" v-interact>
<div class="dialog-header">
<div class="dialog-header__icon" />
<div class="dialog-header__title">交通指引</div>
<div class="dialog-header_close" style="color:#fff" @click="()=>$emit('close')">关闭</div>
</div>
<div class="dialog-content">
<div class="step active">
<div class="step-box">
<div class="step-icon">1</div>
<div class="step-desc">无人机飞往交通事故现场进行拍摄取证</div>
</div>
<div class="btn-box1027">
<div class="btn1027" @click="onTakePhoto">取证</div>
</div>
<div class="imgList mt8" v-if="xcimg">
<el-image
style="width: 110px;height: 88px"
:src="imgApi + xcimg"
fit="cover"
:preview-src-list="[imgApi + xcimg]"
></el-image>
</div>
</div>
<div class="step">
<div class="step-box">
<div class="step-icon">2</div>
<div class="step-desc">激活事故绘制软件并上传事故图</div>
</div>
<div class="btn-box1027">
<div class="btn1027" @click="onActiveApp">激活软件</div>
<el-upload
class="dib"
accept=".png, .jpg, .image, .jpeg"
:action="upLoadApi + '/upload/v2_uploads'"
:on-success="onSuccess"
multiple
name="uploadFiles"
:show-file-list="false"
>
<div class="btn1027" style="margin-right: 0">上传事故图</div>
</el-upload>
</div>
<div class="imgList mt8" v-if="image">
<el-image
style="width: 110px;height: 88px"
:src="imgApi + image"
fit="cover"
:preview-src-list="[imgApi + image]"
></el-image>
</div>
</div>
<div class="step">
<div class="step-box">
<div class="step-icon">3</div>
<div class="step-desc">生成交通事故报告</div>
</div>
<div class="btn-box1027">
<div class="btn1027" @click="onExportReport">导出报告</div>
</div>
</div>
</div>
</div>
</template>
<script>
// import Bus from "@/assets/ligature.js";
import { saveAs } from "file-saver";
import Moment from "moment";
// import API from "@/api";
export default {
props: {
uavId: {
type: String,
default: ""
}
},
data() {
return {
upLoadApi: process.env.VUE_APP_UPLOADS_URL,
imgApi: process.env.VUE_APP_IMG_URL,
imageUrl: [],
imageName: [],
baseList: [],
image: null,
xcimg: null
};
},
computed: {
taskId() {
return this.$store.state.fckernel.taskId;
},
user_info() {
return this.$store.state.user.user_info;
}
},
methods: {
//拍照
async onTakePhoto() {
console.log("uav_take_photo emit");
Bus.$emit("uav_take_photo", {
callback: async blob => {
console.log("uav_take_photo callback");
const moment = new Moment();
const dateTime = moment.format("yyyyMMddhhmmss");
saveAs(blob, `${dateTime}.jpg`);
let fd2 = new FormData();
fd2.append("uploadFile", blob, `拍照.png`);
fd2.append("taskId", this.taskId);
fd2.append("deviceHardId", this.uavId);
let res2 = await API.FCKERNEL.Upload(fd2);
console.log(res2,"urlrel");
this.xcimg = '/uploads'+ res2.fileKey;
this.$message.success("取证成功!");
this.imageUrl.push(this.xcimg);
this.imageName.push('拍照.png');
let res1 = await API.ACCIDENT.createTaskWord({
imageUrl: this.imageUrl,
imageName: this.imageName,
taskId: this.taskId,
baseList: null
});
this.imageName = [];
this.imageUrl = [];
}
});
},
//激活程序
onActiveApp() {
window.open(`TrafficAccident://`, "_blank");
},
//导出报告
onExportReport() {
let url = `${process.env.VUE_APP_BASE_URL}/hawksystemserver/task/exportTaskWord?id=${this.taskId}&FLYINGSESSIONID=${this.user_info.FLYINGSESSIONID}&mmc-identity=${this.user_info["mmc-identity"]}`;
const fileName = url;
window.open(fileName);
},
//图片上传成功
async onSuccess(res, file, fileList) {
console.log("onSuccess", res);
if (res.status == 1) {
this.imageUrl.push(res.data[0].url);
this.imageName.push(res.data[0].name);
this.baseList.push(res.data[0].encode);
this.image = res.data[0].url;
let res1 = await API.ACCIDENT.createTaskWord({
imageUrl: this.imageUrl,
imageName: this.imageName,
taskId: this.taskId,
baseList: this.baseList
});
this.imageName = [];
this.imageUrl = [];
this.baseList = [];
this.$message.success("上传成功");
} else {
this.$message.error(res.msg || "上传失败");
}
}
}
};
</script>
<style lang="scss" scoped>
.traffic {
width: 268px;
}
.dialog-content {
padding: 16px !important;
height: initial !important;
}
.step {
font-size: 14px;
font-family: SourceHanSansCN-Medium, SourceHanSansCN;
font-weight: 500;
color: #fff;
width: 100%;
margin-bottom: 24px;
&:last-child {
margin-bottom: 0;
}
&.active {
.step-icon {
background: #1439ff;
}
}
.step-box {
display: flex;
// justify-content: space-between;
align-items: baseline;
}
.step-icon {
width: 18px;
height: 18px;
background: #515050;
display: flex;
justify-content: center;
align-items: center;
border-radius: 50%;
margin-right: 8px;
flex-shrink: 0;
}
.step-desc {
height: 40px;
line-height: 20px;
}
}
.btn-box1027 {
padding: 0 !important;
justify-content: right;
}
.btn1027 {
padding: 3px 8px;
min-width: 64px;
}
</style>
\ No newline at end of file
<template>
<div class="vm-switch" @mousemove="onMousemove" @mouseleave="onMouseleave">
<div class="vm-switch-btn"></div>
<div class="vm-switch-list" v-show="showMenu">
<div
class="vm-switch-item uav"
:class="{ active: activeIndex === 0 }"
@click="onClickItem(0)"
></div>
<div class="vm-switch-item" :class="{ active: activeIndex === 1 }" @click="onClickItem(1)">舱内</div>
<div class="vm-switch-item" :class="{ active: activeIndex === 2 }" @click="onClickItem(2)">舱外</div>
</div>
</div>
</template>
<script>
export default {
name: "VideoMapSwitch",
data() {
return {
showMenu: false,
activeIndex: -1, // 激活项
};
},
beforeDestroy(){
console.log('hangar videoMapSwitch beforeDestroy');
this.reset();
},
methods: {
onMousemove() {
this.showMenu = true;
clearTimeout(this.handler);
},
onMouseleave() {
this.handler = setTimeout(() => {
this.showMenu = false;
}, 300);
},
onClickItem(i) {
this.reset();
if (this.activeIndex === i) {
this.activeIndex = -1;
} else {
this.activeIndex = i;
let cesiumParentEl = document.querySelector("#layer-container");
let cesiumEl = document.querySelector(".cesium-viewer");
cesiumParentEl.removeChild(cesiumEl);
let parentEl;
let el;
switch (i) {
case 0:
parentEl = document.querySelector("#playerUavParent");
el = document.querySelector("#playerUav");
break;
case 1:
parentEl = document.querySelector("#playInnerParent");
el = document.querySelector("#playInner");
break;
case 2:
parentEl = document.querySelector("#playOutParent");
el = document.querySelector("#playerOuter");
break;
}
parentEl.removeChild(el);
parentEl.appendChild(cesiumEl);
cesiumParentEl.appendChild(el);
}
},
reset() {
let cesiumEl = document.querySelector(".cesium-viewer");
// 判断cesium的父元素是否是layer-container来确定当前是否已经切换, 未切换就退出
if(cesiumEl.parentElement.id === 'layer-container'){
return;
}
let cesiumParentEl = document.querySelector("#layer-container");
let uavParentEl = document.querySelector("#playerUavParent");
let uavEl = document.querySelector("#playerUav");
let innerParentEl = document.querySelector("#playInnerParent");
let innerEl = document.querySelector("#playInner");
let outParentEl = document.querySelector("#playOutParent");
let outEl = document.querySelector("#playerOuter");
cesiumParentEl.innerHTML = "";
uavParentEl.innerHTML = "";
innerParentEl.innerHTML = "";
outParentEl.innerHTML = "";
cesiumParentEl.append(cesiumEl);
uavParentEl.append(uavEl);
innerParentEl.append(innerEl);
outParentEl.append(outEl);
},
},
};
</script>
<style lang="scss" scoped>
.vm-switch {
position: fixed;
left: 73px;
bottom: 30px;
display: flex;
align-items: center;
.vm-switch-btn {
box-sizing: border-box;
width: 48px;
height: 48px;
background-color: #000;
border-radius: 50%;
border: 2px solid #fff;
background-image: url("./assets/images/btn.png");
background-size: 26px 26px;
background-repeat: no-repeat;
background-position: center;
cursor: pointer;
&:hover {
background-image: url("./assets/images/btn-active.png");
}
}
.vm-switch-list {
background: #ffffff;
border-radius: 4px;
gap: 10px;
padding: 7px 9px;
position: relative;
margin-left: 6px;
height: fit-content;
display: flex;
&::before {
content: "";
position: absolute;
left: -6px;
top: 50%;
transform: translate(0, -50%) rotate(-90deg);
background-color: transparent;
width: 0;
height: 0;
border-left: 3px solid transparent;
border-right: 3px solid transparent;
border-bottom: 6px solid #fff;
}
.vm-switch-item {
width: 34px;
height: 34px;
background-color: #000;
font-size: 10px;
display: flex;
justify-content: center;
align-items: center;
color: #fff;
background-repeat: no-repeat;
background-position: center;
border-radius: 2px;
cursor: pointer;
&.active {
color: #3388ff;
}
&.uav {
background-image: url("./assets/images/uav.png");
background-size: 24px 24px;
&.active {
background-image: url("./assets/images/uav-active.png");
}
}
}
}
}
</style>
\ No newline at end of file
......@@ -5,30 +5,6 @@
<div class="left-bar-item__text">任务</div>
</div>
<AirwayList class="task-list" v-if="openTask"></AirwayList>
<!-- <div class="left-bar-item item" @click="onClickAI">
<img class="left-bar-item__icon" src="./assets/images/ai.svg" />
<div class="left-bar-item__text">智能识别</div>
</div>
<div class="ai-list" :class="{ active: openAIList }">
<div class="left-bar-item item" @click.stop="switchAI(0)">
<img class="left-bar-item__icon" src="./assets/images/face.svg" />
<div class="left-bar-item__text">人脸识别</div>
</div>
<div class="left-bar-item item" @click.stop="switchAI(1)">
<img class="left-bar-item__icon" src="./assets/images/car.svg" />
<div class="left-bar-item__text">车辆识别</div>
</div>
<Face v-if="openFace" class="ai-dialog" :uavId="uav.deviceId" @close="openFace = false" />
<Car v-if="openPlate" class="ai-dialog" :uavId="uav.deviceId" @close="openPlate = false" />
<Traffic
v-if="openTraffic"
class="ai-dialog"
:uavId="uav.deviceId"
@close="openTraffic = false"
/>
<Jm v-if="openModeling" :device="device" class="jm-dialog" @close="openModeling = false"></Jm>
</div> -->
<!-- 展示视频 -->
<div class="left-video" :class="{collapse: playerCollapse}" v-if="hangar && showPanel && listCollapse">
<div class="collapse-btn" @click="playerCollapse = !playerCollapse">
......@@ -36,58 +12,48 @@
</div>
<div class="left-video-header">
<div class="left-video-header__title" @click="listCollapse = false">机库列表</div>
<div class="left-video-header__title" @click="openList">机库列表</div>
<div class="nest-name">
<span class="nest-name__text">{{ hangar.name }}</span>
<span class="nest-name__text">{{ hangar.name }}</span>
</div>
</div>
<div class="left-video-nest">
<div class="player1">
<PlayerInner />
<div id="playInnerParent" class="player1">
<PlayerInner id="playInner" />
</div>
<div class="player2">
<PlayerOuter />
<div id="playOutParent" class="player2">
<PlayerOuter id="playerOuter" />
</div>
<div class="player3">
<PlayerUav />
<div id="playerUavParent" class="player3">
<PlayerUav id="playerUav" />
</div>
</div>
</div>
<VideoMapSwitch ref="videoMapSwitch"></VideoMapSwitch>
</div>
</template>
<script>
import { mapState } from "vuex";
import Car from "./components/car";
import Face from "./components/face";
import Jm from "./components/Jm";
import AirwayList from "./components/airwayList";
import Traffic from "./components/traffic";
import PlayerInner from "./components/player/inner";
import PlayerOuter from "./components/player/outer";
import PlayerUav from "./components/player/uav";
import VideoMapSwitch from './components/videoMapSwitch';
export default {
name: "ControlLeft",
components: {
Car,
Jm,
AirwayList,
Traffic,
Face,
PlayerInner,
PlayerOuter,
PlayerUav,
VideoMapSwitch
},
data() {
return {
openTask: true, //打开任务
openAIList: false, //打开AI列表
openTraffic: false, //打开交通指引
openFace: false, //打开人脸识别
openPlate: false, //车牌识别
openModeling: false, //打开建模
playerCollapse: false, //收起播放器
};
},
......@@ -110,7 +76,6 @@ export default {
watch: {
hangar(){
this.openTask = false;
this.openAIList = false;
this.$nextTick(() => {
this.openTask = true;
})
......@@ -122,52 +87,11 @@ export default {
methods: {
onClickTask() {
this.openTask = !this.openTask;
this.openAIList = false;
this.closeAI();
},
onClickAI() {
this.openTask = false;
this.openAIList = !this.openAIList;
this.closeAI();
},
/**
* 切换AI功能
*/
switchAI(type) {
this.openFace = false;
this.openPlate = false;
this.openTraffic = false;
this.openModeling = false;
switch (type) {
case 0:
this.openFace = !this.openFace;
break;
case 1:
this.openPlate = !this.openPlate;
break;
case 2:
if (this.taskId == null) {
return this.$message.error("暂无绑定任务!");
}
this.openTraffic = !this.openTraffic;
break;
case 3:
this.openModeling = !this.openModeling;
break;
}
},
/**
* 关闭所有ai
*/
closeAI() {
this.openFace = false;
this.openPlate = false;
this.openTraffic = false;
this.openModeling = false;
},
openList(){
this.listCollapse = false;
this.$refs.videoMapSwitch.reset();
}
},
};
</script>
......@@ -176,14 +100,14 @@ export default {
.task-list {
position: absolute;
left: 60px;
top: -30px;
top: 0px;
cursor: initial;
}
.control-left {
position: absolute;
z-index: 2;
left: 430px;
top: 13%;
top: 28px;
transition: 0.3s;
&.collapse {
......@@ -369,7 +293,7 @@ export default {
}
.player3 {
width: 100%;
height: 240;
height: 235px;
}
}
}
......
<!-- 飞控地图选择 -->
<template>
<div class="map-switch">
<div class="map-switch-wrap cp" @click="change" @mouseout="likai">
<div class="map-item map-item-satellite"></div>
<div class="map-switch" @mousemove="onMousemove" @mouseleave="onMouseleave">
<div class="map-switch-btn">
<div class="map-item" :class="selectIconClass"></div>
</div>
<div class="changeMapBox pa cp">
<div class="dise" @mouseout="likai">
<div class="map-list" v-show="showMenu">
<div class="map-item">
<div
class="bai"
class="dim"
:class="{ active: !is_3d }"
v-show="!is_3d"
@click="handle_change_3d(true)"
>2D</div>
<div
class="bai"
class="dim"
:class="{ active: is_3d }"
v-show="is_3d"
@click="handle_change_3d(false)"
>3D</div>
</div>
<div v-for="item in tabs" :key="item.id" class="dise" @mousemove="jinru(item.id)">
<div
:class="{
'map-item': 1,
[item.class_name]: 1,
}"
@click="handle_change(item.id)"
style="position: relative; overflow: hidden"
>
<div class="zimu" :class="{ sh: numId == item.id + 1 }">{{ item.name }}</div>
</div>
<div v-for="item in tabs" :key="item.id" class="map-item" @click="onSelect(item.class_name)">
<el-tooltip effect="dark" :content="item.name" placement="top-start">
<div
class="map-item"
:class="item.class_name"
@click="handle_change(item.id)"
style="position: relative; overflow: hidden"
></div>
</el-tooltip>
</div>
</div>
</div>
......@@ -42,8 +40,8 @@ export default {
components: {},
data() {
return {
numId: null, //鼠标悬浮效果
active: false,
selectIconClass: "map-item-satellite",
showMenu: false,
is_3d: true,
current: 1,
tabs: [
......@@ -68,6 +66,7 @@ export default {
class_name: "map-item-night-blue",
},
],
handler: null,
};
},
computed: {
......@@ -85,12 +84,18 @@ export default {
},
watch: {},
methods: {
// 鼠标悬浮效果
jinru(id) {
this.numId = id + 1;
onMousemove() {
this.showMenu = true;
clearTimeout(this.handler);
},
onMouseleave() {
this.handler = setTimeout(() => {
this.showMenu = false;
}, 300);
},
likai() {
this.numId = null;
// 选中的图标
onSelect(className) {
this.selectIconClass = className;
},
handle_change_3d(bool) {
this.is_3d = bool;
......@@ -118,16 +123,6 @@ export default {
}
console.log("this.cesiumImagesLayers", this.cesiumImagesLayers, id);
},
change() {
this.active = !this.active;
// global_leyers.forEach(promise => {
// promise.then((layer) =>{
// layer.visible = this.active;
// });
// })
// base_layer.BASIC && (base_layer.BASIC.show = !this.active)
// base_layer.SATELLITE && (base_layer.SATELLITE.show = this.active)
},
},
};
</script>
......@@ -136,89 +131,40 @@ export default {
.map-switch {
z-index: 1;
bottom: 30px;
.changeMapBox {
position: absolute;
width: 201px;
height: 48px;
background: rgba(9, 32, 87, 0.7);
border: 1px solid #43deff;
left: -159px;
margin-top: 3px;
display: none;
justify-content: space-around;
align-items: center;
// display: flex;
.map-item {
width: 30px;
height: 30px;
color: #04d5da;
text-align: right;
line-height: 49px;
// margin-top: 5px;
border-radius: 4px;
font-size: 9px;
border: 1px solid #eee;
cursor: pointer;
}
.map-item-satellite {
background: url(./assets/images/3d.png) center no-repeat;
}
.map-item-street {
background: url(./assets/images/2d.png) center no-repeat;
}
.map-item-night-blue {
background: url(./assets/images/night-blue.png) center no-repeat;
}
.map-item-3d {
background: url(./assets/images/3d.png) center no-repeat;
}
.map-item-2d {
background: url(./assets/images/2d.png) center no-repeat;
}
}
position: absolute;
right: 14px;
width: 104px;
height: 78px;
width: 48px;
height: 48px;
transition: 0.2s;
transform: translateX(0);
.map-switch-wrap {
.map-switch-btn {
cursor: pointer;
position: absolute;
right: 0;
min-width: 52px;
height: 52px;
width: 100%;
height: 100%;
border-radius: 2px;
overflow: hidden;
display: flex;
justify-content: center;
align-items: center;
transition: width 0.25s;
&.active {
width: 166px;
}
.map-item {
width: 52px;
height: 52px;
box-sizing: border-box;
border-radius: 50%;
border: 3px solid #fff;
position: relative;
width: 100%;
height: 100%;
&.map-item-satellite {
// background: url(./assets/images/3d.png) center no-repeat;
background: url("./assets/images/ditu_icon.png") center no-repeat;
background: url(./assets/images/3d.png) center no-repeat;
// background: url("./assets/images/ditu_icon.png") center no-repeat;
background-size: 112% 112%;
}
......@@ -259,103 +205,56 @@ export default {
}
}
.waterbox {
height: 48px;
width: 48px;
.map-list {
position: absolute;
top: 130px;
right: 0px;
border: 1px solid #04d5da;
background: rgba(22, 29, 45, 0.7);
color: #43deff;
font-size: 20px;
line-height: 48px;
}
.water_quality {
width: 459px;
height: 418px;
background: rgba(0, 23, 79, 0.7);
box-shadow: 0 2px 4px 0 rgba(1, 162, 255, 0.35),
inset 0 0 40px 0 rgba(0, 184, 255, 0.5);
border-radius: 13px;
}
}
.map-switch:hover {
.changeMapBox {
background: #fff;
right: 60px;
display: flex;
}
}
justify-content: space-around;
align-items: center;
padding: 6px;
gap: 6px;
.dise {
width: 34px;
height: 34px;
border-radius: 4px;
display: flex;
align-items: center;
justify-content: center;
background: #fff;
}
// display: flex;
.map-item {
width: 42px;
height: 36px;
cursor: pointer;
.bai {
text-align: center;
line-height: 30px;
font-size: 14px;
color: #ffffff !important;
font-weight: 700;
width: 30px;
height: 30px;
// border: 2px solid #fff;
border-radius: 4px;
// margin: 5px 0 0 0;
background: #000000;
cursor: pointer;
}
.dim {
width: 100%;
height: 100%;
font-size: 14px;
color: #ffffff;
font-weight: 700;
border-radius: 4px;
background: #000000;
cursor: pointer;
display: flex;
justify-content: center;
align-items: center;
}
}
.zimu {
position: absolute;
left: 0;
bottom: 0;
height: 18px;
opacity: 0.64;
background: #fff;
border-radius: 0 0 4px 4px;
width: 100%;
text-align: center;
font-size: 12px;
font-family: MicrosoftYaHei;
color: #000;
line-height: 16px;
font-weight: 400;
display: none;
pointer-events: auto;
}
.map-item-satellite {
background: url(./assets/images/3d.png) center no-repeat;
}
@keyframes fr {
from {
bottom: -60%;
}
.map-item-street {
background: url(./assets/images/2d.png) center no-repeat;
}
to {
bottom: 0%;
}
}
.map-item-night-blue {
background: url(./assets/images/night-blue.png) center no-repeat;
}
.sh {
display: block;
animation: fr 1s linear;
animation-fill-mode: forwards;
pointer-events: auto;
}
.map-item-3d {
background: url(./assets/images/3d.png) center no-repeat;
}
.anniu {
width: 48px;
height: 48px;
background: #fff;
border-radius: 50%;
display: flex;
justify-content: center;
align-content: center;
.map-item-2d {
background: url(./assets/images/2d.png) center no-repeat;
}
}
}
</style>
\ No newline at end of file
<template>
<div class="car dialog1027" v-interact>
<div class="dialog-header">
<div class="dialog-header__icon" />
<div class="dialog-header__title">
快速建模
</div>
<div class="dialog-header_close" style="color:#fff" @click="() => $emit('close')">关闭</div>
</div>
<div class="dialog-content w267">
<el-cascader size="mini" filterable popper-class="cpt-observe-mspace-dashboard-airway_popper" v-model="taskCateId"
:options="airway_list" clearable :show-all-levels="false" placeholder="请选择任务" :props="{
children: 'children',
label: 'taskTitle',
value: 'id',
emitPath: false,
}">
<template slot-scope="{ data }">
<el-tooltip :disabled="data.taskTitle.length < 11" class="item" effect="dark" :content="data.taskTitle"
placement="top-start">
<span>{{ data.taskTitle }}</span>
</el-tooltip>
</template>
</el-cascader>
<el-select class="mt10" v-model="type" size="mini" placeholder="请选择类型">
<el-option label="图片" :value="0"></el-option>
<el-option label="视频" :value="1"></el-option>
</el-select>
<div class="jcsb w267 h30 mt30">
<div class="dec mt5">1</div><span class="dib cf ml10 lh30"> 快速建模</span>
<div class="btn fr cf h30 lh30 w80 cp" @click="jmFn(1)">启动</div>
</div>
<div class="jcsb mt18 w267 h30">
<div class="dec mt5">2</div><span class="dib cf lh30 ml10">数据处理</span>
<div class="btn fr cf h30 lh30 w80 cp" @click="jmFn(2)">启动</div>
</div>
</div>
</div>
</template>
<script>
// import API from '@/api';
export default {
props: {
device: {
type: Object,
default: () => ({})
},
},
data() {
return {
imgUrl: process.env.VUE_APP_IMG_URL,
list: [],
type: null,
taskCateId: null,
airway_list: []
}
},
created() {
this.list_airway();
},
methods: {
jmFn(num) {
let { deviceHardId } = this.device
if (num == 1) {
let a = document.createElement("a");
a.href = `MMCEagleEye:// `
a.click()
}
else {
if(!this.taskCateId) return this.$message.warning('请选择任务!')
if(this.type==null ) return this.$message.warning('请选择类型!')
let a = document.createElement("a");
a.href = `MMCPosTool://&deviceId=${deviceHardId}enddeviceId&taskId=${this.taskCateId}endtaskId&type=${this.type}endtype`
a.click()
}
},
async list_airway() {
/* let res = await API.AIRWAY.getApprovedTask();
if (res) {
let jqList = [],
ctList = [],
lsList = [];
for (let i = 0; i < res.length; i++) {
if (res[i].taskCateId == 1) {
jqList.push(res[i]);
}
if (res[i].taskCateId == 2) {
ctList.push(res[i]);
}
if (res[i].taskCateId == 3) {
lsList.push(res[i]);
}
}
let airway_list = [
{
id: "警情任务",
taskTitle: "警情任务",
children: jqList,
},
{
id: "常态任务",
taskTitle: "常态任务",
children: ctList,
},
{
id: "临时任务",
taskTitle: "临时任务",
children: lsList,
},
];
this.airway_list = airway_list;
} */
},
}
}
</script>
<style lang="scss" scoped>
.car {
width: 268px;
}
.dialog-content {
padding: 20px 14px 12px;
max-height: 461px;
overflow: auto;
.dec {
width: 20px;
height: 20px;
line-height: 20px;
text-align: center;
border-radius: 50%;
background: #06199b;
}
.btn {
text-align: center;
border: 1px #315ec7 solid;
border-radius: 3px;
background-color: #02173d;
font-size: 14px;
font-family: MicrosoftYaHei;
color: #D2D9FF;
cursor: pointer;
}
.btn:hover {
background: #06199b;
}
}
.car-img {
position: relative;
width: 100%;
height: 135px;
.car-img__img {
width: 100%;
height: 100%;
}
.car-img__label {
position: absolute;
bottom: 0;
width: 100%;
height: 28px;
display: flex;
justify-content: center;
align-items: center;
font-size: 14px;
color: #aee9ff;
font-family: MicrosoftYaHeiUI;
}
}
.car-form {
padding: 10px 0 0;
font-size: 14px;
font-family: MicrosoftYaHei;
color: #fff;
>div {
margin-bottom: 8px;
&:last-child {
margin-bottom: 0;
}
}
}
.car-item {
margin-bottom: 24px;
}
</style>
\ No newline at end of file
<template>
<div class="car dialog1027" v-interact>
<div class="dialog-header">
<div class="dialog-header__icon" />
<div class="dialog-header__title">
车辆识别
</div>
<div class="dialog-header_close" style="color:#fff" @click="()=>$emit('close')">关闭</div>
</div>
<div class="dialog-content" v-infinite-scroll="load">
<template v-if="list.length > 0" >
<div v-for="(item, i) in list" :key="i" class="car-item">
<div class="car-img">
<img class="car-img__img" :src="imgUrl + item.imageUrl" />
<div class="car-img__label">{{ item.plateNum || '暂无' }}</div>
</div>
<div class="car-form">
<div>地点:{{ item.addr || item.findAddress || '暂无' }}</div>
<div>时间:{{ item.findTime || '暂无' }}</div>
</div>
</div>
</template>
<template v-else>
<div style="text-align: center; width: 100%;">暂无数据</div>
</template>
</div>
</div>
</template>
<script>
// import API from '@/api';
export default {
props: {
uavId: {
type: String,
default: ''
}
},
data(){
return {
imgUrl: process.env.VUE_APP_IMG_URL,
list: [],
pageNo: 1,
pageSize: 3,
}
},
created(){
this.getCarList()
},
methods: {
async load(){
this.pageNo++
/* let res = await API.HOME.getflightvideoMsg({
uavId: this.uavId,
pageNo: this.pageNo,
pageSize: this.pageSize
})
for(let i = 0; i < res.length; i++){
let item = res[i];
if(item.lon){
let address = await API.MAP.AiRegeo({
location: `${item.lon},${item.lat}`
})
item.addr = address.province.value + address.city.value + address.dist.value + address.road.roadname + address.poi;
}
this.list.push(res[i])
}
console.log(this.list,"list"); */
},
async getCarList(){
if(!this.uavId){
this.$message.error('请选择无人机');
return;
}
let res = await API.HOME.getflightvideoMsg({
uavId: this.uavId,
pageNo: this.pageNo,
pageSize: this.pageSize
})
for(let i = 0; i < res.length; i++){
let item = res[i];
if(item.lon){
let address = await API.MAP.AiRegeo({
location: `${item.lon},${item.lat}`
})
item.addr = address.province.value + address.city.value + address.dist.value + address.road.roadname + address.poi;
}
this.list.push(res[i])
}
// this.list = res || [];
}
}
}
</script>
<style lang="scss" scoped>
.car{
width: 268px;
}
.dialog-content{
padding: 20px 14px 12px;
max-height: 461px;
overflow: auto;
}
.car-img{
position: relative;
width: 100%;
height: 135px;
.car-img__img {
width: 100%;
height: 100%;
}
.car-img__label {
position: absolute;
bottom: 0;
width: 100%;
height: 28px;
display: flex;
justify-content: center;
align-items: center;
font-size: 14px;
color: #aee9ff;
font-family: MicrosoftYaHeiUI;
}
}
.car-form{
padding: 10px 0 0;
font-size: 14px;
font-family: MicrosoftYaHei;
color: #fff;
>div {
margin-bottom: 8px;
&:last-child {
margin-bottom: 0;
}
}
}
.car-item{
margin-bottom: 24px;
}
</style>
\ No newline at end of file
<template>
<div class="face dialog1027" v-interact>
<div class="dialog-header">
<div class="dialog-header__icon" />
<div class="dialog-header__title">
人脸识别
</div>
<div class="dialog-header_close" style="color:#fff" @click="()=>$emit('close')">关闭</div>
</div>
<div class="dialog-content" v-infinite-scroll="load">
<template v-if="list.length > 0">
<div class="result" v-for="(item, i) in list" :key="i">
<div class="rate-box">
<div class="rate-img">
<img :src="imgUrl + item.recordImageUrl" />
</div>
<div class="rate-round">
<div class="rate-round__value">{{ Number(item.similarity).toFixed(2) }}%</div>
<div class="rate-routd__text" @click="onDetail(item)">详情</div>
</div>
<div class="rate-img rate-img--contrary">
<img :src="imgUrl + item.snapImageUrl" />
</div>
</div>
<div class="rate-form" v-if="item.show">
<div class="rate-form-item">
<div class="rate-form-item__label">
姓名:
</div>
<div class="rate=form-item__value">
{{ item.userName || '暂无' }}
</div>
</div>
<div class="rate-form-item">
<div class="rate-form-item__label">
出生年份:
</div>
<div class="rate=form-item__value">
{{ item.birthday || '暂无' }}
</div>
</div>
<div class="rate-form-item">
<div class="rate-form-item__label">
发现时间:
</div>
<div class="rate=form-item__value">
{{ item.occurTime || '暂无' }}
</div>
</div>
<div class="rate-form-item">
<div class="rate-form-item__label">
发现地点:
</div>
<div class="rate=form-item__value">
{{ item.addr || item.address || '暂无' }}
</div>
</div>
<div class="rate-form-item">
<div class="rate-form-item__label">
身份证号:
</div>
<div class="rate=form-item__value">
{{ item.idCard || '暂无' }}
</div>
</div>
<div class="rate-form-item">
<div class="rate-form-item__label">
AI识别:
</div>
<div class="rate=form-item__value">
<template v-if="item.labels && item.labels.length">
<div class="round-border" v-for="(label, j) in item.labels" :key="j" >
{{label}}
</div>
</template>
<template v-else>
暂无
</template>
</div>
</div>
</div>
</div>
</template>
<template v-else>
<div style="text-align: center; width: 100%;">暂无数据</div>
</template>
</div>
</div>
</template>
<script>
// import API from '@/api';
export default {
props: {
uavId: {
type: String,
default: ''
}
},
data(){
return {
imgUrl: process.env.VUE_APP_IMG_URL,
list: [
/* {
userName: '人热二',
birthday: '1888-02-11',
occurTime: '2022-02-30 08:22:14',
address: '深圳市南山区',
idCard: '112313123123',
labels: ['省内人员'],
similarity: '63',
img: '',
imgs: '',
show: true
} */
],
pageNo: 1,
pageSize: 4,
}
},
created(){
this.getFaceList();
},
methods: {
async load(){
this.pageNo++
/* let res = await API.HOME.getFaceuavvideoMsg({
uavId: this.uavId,
pageNo: this.pageNo,
pageSize: this.pageSize
})
for(let i = 0; i < res.length; i++){
let item = res[i];
if(item.longi){
let address = await API.MAP.AiRegeo({
location: `${item.longi},${item.lati}`
})
item.addr = address.province.value + address.city.value + address.dist.value + address.road.roadname + address.poi;
}
this.list.push(res[i])
}
console.log(this.list,"list"); */
},
async getFaceList(){
if(!this.uavId){
this.$message.error('请选择无人机');
return;
}
let res = await API.HOME.getFaceuavvideoMsg({
uavId: this.uavId,
pageNo: this.pageNo,
pageSize: this.pageSize
}) || [];
for(let i = 0; i < res.length; i++){
let item = res[i];
if(item.longi){
let address = await API.MAP.AiRegeo({
location: `${item.longi},${item.lati}`
})
item.addr = address.province.value + address.city.value + address.dist.value + address.road.roadname + address.poi;
}
this.list.push(res[i])
}
// this.list = res || [];
},
onDetail(item){
this.$set(item, 'show', !item.show);
}
}
}
</script>
<style lang="scss" scoped>
.face{
width: 268px;
}
.dialog-content{
padding: 14px;
cursor: initial;
max-height: 461px;
overflow-y: auto;
}
.result{
width: 100%;
margin-top: 27px;
&:first-child {
margin-top: 0;
}
}
.rate-box{
display: flex;
align-items: center;
position: relative;
width: 100%;
.rate-img{
flex: 1;
height: 75px;
background-image: url('../../assets/images/faceAI_border1.png');
background-size: 100% 100%;
padding: 7px;
display: flex;
align-items: center;
&.rate-img--contrary {
background-image: url('../../assets/images/faceAI_border2.png');
justify-content: right;
}
img {
width: 70px;
height: 70px;
border-radius: 7px;
overflow: hidden;
}
}
.rate-round{
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
.rate-round__value{
color: #fb799d;
font-size: 14px;
font-family: MicrosoftYaHei;
}
.rate-routd__text{
cursor: pointer;
font-size: 12px;
color: #b9d7f0;
font-family: MicrosoftYaHei;
transform: scale(0.9);
margin-top: 3px;
}
}
}
.rate-form{
margin-top: 10px;
font-size: 14px;
font-family: MicrosoftYaHei;
color: #fff;
.rate-form-item {
margin-bottom: 12px;
display: flex;
&:last-child {
margin-bottom: 0;
}
.rate-form-item__label {
width: 70px;
text-align: right;
flex-shrink: 0;
}
.rate-form-item__value {
}
}
}
.round-border{
padding: 2px 8px;
border-radius: 11px;
border: 1px solid #ff4a4a;
color: #ff4a4a;
font-size: 14px;
font-family: MicrosoftYaHei;
}
</style>
\ No newline at end of file
<template>
<div class="traffic dialog1027" v-interact>
<div class="dialog-header">
<div class="dialog-header__icon" />
<div class="dialog-header__title">交通指引</div>
<div class="dialog-header_close" style="color:#fff" @click="()=>$emit('close')">关闭</div>
</div>
<div class="dialog-content">
<div class="step active">
<div class="step-box">
<div class="step-icon">1</div>
<div class="step-desc">无人机飞往交通事故现场进行拍摄取证</div>
</div>
<div class="btn-box1027">
<div class="btn1027" @click="onTakePhoto">取证</div>
</div>
<div class="imgList mt8" v-if="xcimg">
<el-image
style="width: 110px;height: 88px"
:src="imgApi + xcimg"
fit="cover"
:preview-src-list="[imgApi + xcimg]"
></el-image>
</div>
</div>
<div class="step">
<div class="step-box">
<div class="step-icon">2</div>
<div class="step-desc">激活事故绘制软件并上传事故图</div>
</div>
<div class="btn-box1027">
<div class="btn1027" @click="onActiveApp">激活软件</div>
<el-upload
class="dib"
accept=".png, .jpg, .image, .jpeg"
:action="upLoadApi + '/upload/v2_uploads'"
:on-success="onSuccess"
multiple
name="uploadFiles"
:show-file-list="false"
>
<div class="btn1027" style="margin-right: 0">上传事故图</div>
</el-upload>
</div>
<div class="imgList mt8" v-if="image">
<el-image
style="width: 110px;height: 88px"
:src="imgApi + image"
fit="cover"
:preview-src-list="[imgApi + image]"
></el-image>
</div>
</div>
<div class="step">
<div class="step-box">
<div class="step-icon">3</div>
<div class="step-desc">生成交通事故报告</div>
</div>
<div class="btn-box1027">
<div class="btn1027" @click="onExportReport">导出报告</div>
</div>
</div>
</div>
</div>
</template>
<script>
// import Bus from "@/assets/ligature.js";
import { saveAs } from "file-saver";
import Moment from "moment";
// import API from "@/api";
export default {
props: {
uavId: {
type: String,
default: ""
}
},
data() {
return {
upLoadApi: process.env.VUE_APP_UPLOADS_URL,
imgApi: process.env.VUE_APP_IMG_URL,
imageUrl: [],
imageName: [],
baseList: [],
image: null,
xcimg: null
};
},
computed: {
taskId() {
return this.$store.state.fckernel.taskId;
},
user_info() {
return this.$store.state.user.user_info;
}
},
methods: {
//拍照
async onTakePhoto() {
console.log("uav_take_photo emit");
Bus.$emit("uav_take_photo", {
callback: async blob => {
console.log("uav_take_photo callback");
const moment = new Moment();
const dateTime = moment.format("yyyyMMddhhmmss");
saveAs(blob, `${dateTime}.jpg`);
let fd2 = new FormData();
fd2.append("uploadFile", blob, `拍照.png`);
fd2.append("taskId", this.taskId);
fd2.append("deviceHardId", this.uavId);
let res2 = await API.FCKERNEL.Upload(fd2);
console.log(res2,"urlrel");
this.xcimg = '/uploads'+ res2.fileKey;
this.$message.success("取证成功!");
this.imageUrl.push(this.xcimg);
this.imageName.push('拍照.png');
let res1 = await API.ACCIDENT.createTaskWord({
imageUrl: this.imageUrl,
imageName: this.imageName,
taskId: this.taskId,
baseList: null
});
this.imageName = [];
this.imageUrl = [];
}
});
},
//激活程序
onActiveApp() {
window.open(`TrafficAccident://`, "_blank");
},
//导出报告
onExportReport() {
let url = `${process.env.VUE_APP_BASE_URL}/hawksystemserver/task/exportTaskWord?id=${this.taskId}&FLYINGSESSIONID=${this.user_info.FLYINGSESSIONID}&mmc-identity=${this.user_info["mmc-identity"]}`;
const fileName = url;
window.open(fileName);
},
//图片上传成功
async onSuccess(res, file, fileList) {
console.log("onSuccess", res);
if (res.status == 1) {
this.imageUrl.push(res.data[0].url);
this.imageName.push(res.data[0].name);
this.baseList.push(res.data[0].encode);
this.image = res.data[0].url;
let res1 = await API.ACCIDENT.createTaskWord({
imageUrl: this.imageUrl,
imageName: this.imageName,
taskId: this.taskId,
baseList: this.baseList
});
this.imageName = [];
this.imageUrl = [];
this.baseList = [];
this.$message.success("上传成功");
} else {
this.$message.error(res.msg || "上传失败");
}
}
}
};
</script>
<style lang="scss" scoped>
.traffic {
width: 268px;
}
.dialog-content {
padding: 16px !important;
height: initial !important;
}
.step {
font-size: 14px;
font-family: SourceHanSansCN-Medium, SourceHanSansCN;
font-weight: 500;
color: #fff;
width: 100%;
margin-bottom: 24px;
&:last-child {
margin-bottom: 0;
}
&.active {
.step-icon {
background: #1439ff;
}
}
.step-box {
display: flex;
// justify-content: space-between;
align-items: baseline;
}
.step-icon {
width: 18px;
height: 18px;
background: #515050;
display: flex;
justify-content: center;
align-items: center;
border-radius: 50%;
margin-right: 8px;
flex-shrink: 0;
}
.step-desc {
height: 40px;
line-height: 20px;
}
}
.btn-box1027 {
padding: 0 !important;
justify-content: right;
}
.btn1027 {
padding: 3px 8px;
min-width: 64px;
}
</style>
\ No newline at end of file
<template>
<div class="vm-switch" @mousemove="onMousemove" @mouseleave="onMouseleave">
<div class="vm-switch-btn"></div>
<div class="vm-switch-list" v-show="showMenu">
<div
class="vm-switch-item uav"
:class="{ active: activeIndex === 0 }"
@click="onClickItem(0)"
></div>
</div>
<div id="uavPlayerParent" v-show="activeIndex === 0" class="uav-video"></div>
</div>
</template>
<script>
export default {
name: "VideoMapSwitch",
data() {
return {
showMenu: false,
activeIndex: -1,
};
},
beforeDestroy(){
console.log('uav videoMapSwitch beforeDestroy');
this.reset();
},
methods: {
onMousemove() {
this.showMenu = true;
clearTimeout(this.handler);
},
onMouseleave() {
this.handler = setTimeout(() => {
this.showMenu = false;
}, 300);
},
onClickItem(i) {
this.reset();
if (this.activeIndex === i) {
this.activeIndex = -1;
} else {
this.activeIndex = i;
let cesiumParentEl = document.querySelector("#layer-container");
let cesiumEl = document.querySelector(".cesium-viewer");
cesiumParentEl.removeChild(cesiumEl);
let parentEl;
let el;
switch (i) {
case 0:
parentEl = document.querySelector("#uavPlayerParent");
el = document.querySelector("#uavPlayer");
uavPlayerWrap.style.display = 'none';
break;
}
parentEl.appendChild(cesiumEl);
cesiumParentEl.appendChild(el);
}
},
reset() {
let cesiumEl = document.querySelector(".cesium-viewer");
// 判断cesium的父元素是否是layer-container来确定当前是否已经切换, 未切换就退出
if(cesiumEl.parentElement.id === 'layer-container'){
return;
}
let cesiumParentEl = document.querySelector("#layer-container");
let uavParentEl = document.querySelector("#uavPlayerParent");
let uavEl = document.querySelector("#uavPlayer");
let uavPlayerWrap = document.querySelector('#uavPlayerWrap');
let uavPlayerParent = uavPlayerWrap?.querySelector('.cpt_video');
cesiumParentEl.innerHTML = "";
uavParentEl.innerHTML = "";
cesiumParentEl.append(cesiumEl);
uavPlayerParent.append(uavEl);
uavPlayerWrap.style.display = '';
},
},
};
</script>
<style lang="scss" scoped>
.vm-switch {
position: fixed;
left: 73px;
bottom: 30px;
display: flex;
align-items: center;
.vm-switch-btn {
box-sizing: border-box;
width: 48px;
height: 48px;
background-color: #000;
border-radius: 50%;
border: 2px solid #fff;
background-image: url("./assets/images/btn.png");
background-size: 26px 26px;
background-repeat: no-repeat;
background-position: center;
cursor: pointer;
&:hover {
background-image: url("./assets/images/btn-active.png");
}
}
.vm-switch-list {
background: #ffffff;
border-radius: 4px;
gap: 10px;
padding: 7px 9px;
position: relative;
margin-left: 6px;
height: fit-content;
display: flex;
&::before {
content: "";
position: absolute;
left: -6px;
top: 50%;
transform: translate(0, -50%) rotate(-90deg);
background-color: transparent;
width: 0;
height: 0;
border-left: 3px solid transparent;
border-right: 3px solid transparent;
border-bottom: 6px solid #fff;
}
.vm-switch-item {
width: 34px;
height: 34px;
background-color: #000;
font-size: 10px;
display: flex;
justify-content: center;
align-items: center;
color: #fff;
background-repeat: no-repeat;
background-position: center;
border-radius: 2px;
cursor: pointer;
&.active {
color: #3388ff;
}
&.uav {
background-image: url("./assets/images/uav.png");
background-size: 24px 24px;
&.active {
background-image: url("./assets/images/uav-active.png");
}
}
}
}
.uav-video {
position: absolute;
bottom: 100px;
left: 0px;
width: 388px;
height: 220px;
}
}
</style>
\ No newline at end of file
......@@ -6,50 +6,22 @@
</div>
<TaskList class="task-list" v-if="!useAirway && openTask"></TaskList>
<AirwayList class="task-list" v-if="useAirway && openTask"></AirwayList>
<!-- <div class="left-bar-item item" @click="onClickAI">
<img class="left-bar-item__icon" src="./assets/images/ai.svg" />
<div class="left-bar-item__text">智能识别</div>
</div>
<div class="ai-list" :class="{ active: openAIList }">
<div class="left-bar-item item" @click.stop="switchAI(0)">
<img class="left-bar-item__icon" src="./assets/images/face.svg" />
<div class="left-bar-item__text">人脸识别</div>
</div>
<div class="left-bar-item item" @click.stop="switchAI(1)">
<img class="left-bar-item__icon" src="./assets/images/car.svg" />
<div class="left-bar-item__text">车辆识别</div>
</div>
<Face v-if="openFace" class="ai-dialog" :uavId="uav.deviceId" @close="openFace = false" />
<Car v-if="openPlate" class="ai-dialog" :uavId="uav.deviceId" @close="openPlate = false" />
<Traffic
v-if="openTraffic"
class="ai-dialog"
:uavId="uav.deviceId"
@close="openTraffic = false"
/>
<Jm v-if="openModeling" :device="device" class="jm-dialog" @close="openModeling = false"></Jm>
</div> -->
<VideoMapSwitch ref="videoMapSwitch"></VideoMapSwitch>
</div>
</template>
<script>
import { mapState } from "vuex";
import Car from "./components/car";
import Face from "./components/face";
import Jm from "./components/Jm";
import TaskList from "./components/taskList";
import AirwayList from "./components/airwayList";
import Traffic from "./components/traffic";
import VideoMapSwitch from './components/videoMapSwitch';
export default {
name: "ControlLeft",
components: {
Car,
Jm,
TaskList,
AirwayList,
Traffic,
Face,
VideoMapSwitch
},
data() {
return {
......@@ -85,6 +57,9 @@ export default {
this.openTask = true;
});
},
listCollapse(){
this.$refs.videoMapSwitch.reset();
}
},
methods: {
onClickTask() {
......
......@@ -86,10 +86,10 @@ export default {
if (value.vUrl == oldVal?.vUrl) {
return;
}
// console.log('livenvr', value)
console.log('livenvr', value, oldVal)
if (value && value.vUrl) {
this.$nextTick(() => {
this.$refs["livePlayer"].play();
this.$refs["livePlayer"]?.play();
});
}
},
......
<template>
<!-- 清流融合 -->
<div class="player" :class="big" v-interact>
<div id="uavPlayerWrap" class="player" :class="big" v-interact>
<div ref="video" class="video-wrap" @dblclick="screen">
<div class="cpt_video" @click="lensControl" v-if="showPlayer">
<Obstacle v-if="!isStatus"></Obstacle>
......@@ -21,6 +21,7 @@
></videoModelChange>-->
<components
id="uavPlayer"
:is="playerCom"
:smallFPV="smallFPV"
:isStatus="isStatus"
......
import axios from 'axios';
// import API from "../../../../../api";
export default {
interfaceAI(url) {
let blob = this.screenShot();
let data = {
image: null
}
blobToBase64(blob, async (base64DataUrl) => {
data.image = base64DataUrl
let res = await axios.post("http://32.128.6.151:9090/api/inflet/v1/tasks/3b2c435f-0652-418c-82d0-37efed27e9c1/predict", data)
// console.log(res);
console.log(res.data.data,"swiming");
// if(this.indexswim == 10){
if (res.data.data.targets && res.data.data.targets.length > 0) {
clearInterval(this.AISetInterval)
this.AISetInterval = null
// this.$emit("fn", {data: "POSITION",type: 513});
// if (this.lineLableName.includes("河道")) {
this.$emit("AIDialog", true, "当前区域发现疑似游泳人员")
// }
let fd = new FormData();
fd.append("uploadFiles", blob, `下载.jpeg`);
let res2 = await API.MAPMANAGE.fileUpload(fd);
let data2 = {
imageUrl: res2[0].storage,
deviceHardId: this.device.deviceHardId,
jsonData: JSON.stringify(res.data.data)
}
let swimres = await API.FCKERNEL.insertSwimmingMonitor(data2)
// process.env.VUE_APP_IMG_URL +
let imgshowurl = process.env.VUE_APP_IMG_URL + res2[0].url;
this.$emit("imgUrl", imgshowurl,4,JSON.stringify(res.data.data));
}
});
function blobToBase64(blob, callback) {
let reader = new FileReader()
reader.onload = () => {
callback(reader.result)
}
reader.readAsDataURL(blob)
}
},
//人流识别
async setIntervalFrame() {
let blob = this.screenShot();
let fd = new FormData();
fd.append("uploadFiles", blob, `下载.jpeg`);
let res = await API.MAPMANAGE.fileUpload(fd);
let data = {
// imageUrl:"http://32.128.6.52:9000/uploads/2023/05/26/2f183488-ad62-41c2-bb89-736ade5d8f36.png",
imageUrl: res[0].storage,
deviceHardId: this.device.deviceHardId,
};
let res2 = await API.FCKERNEL.crowdDensity(data);
if (res2.total && res2.total > 20) {
clearInterval(this.AISetInterval)
this.AISetInterval = null
this.$emit("fn", {
data: "POSITION",
type: 513
});
this.$emit("AIDialog", true, "当前区域人流聚集")
}
},
}
\ No newline at end of file
......@@ -638,5 +638,21 @@ export default {
background: transparent !important;
}
}
.cesium-viewer-bottom {
display: none;
}
.cesium-viewer-zoomIndicatorContainer {
display: none;
}
.cesium-viewer-navigationContainer {
display: none;
}
.cesium-credit-logoContainer {
display: none;
}
}
</style>
\ No newline at end of file
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论