<template>
|
<div class="relate-camera">
|
<div class="part">
|
<div class="title">
|
<span>关联设备分组</span>
|
<el-button @click="newGroup" icon="el-icon-plus" size="mini" type="primary">新建分组</el-button>
|
</div>
|
<el-alert type="info" title="提示:请点击上方'新建分组'按钮建立分组" show-icon v-if="groupList.length==0"></el-alert>
|
<div class="flex-box" v-if="groupList.length!==0">
|
<div
|
class="group-card"
|
:class="{'checked':group.checked}"
|
v-for="(group,index) in groupList"
|
:key="index"
|
@click="checkCurrentGroup(group)"
|
>
|
<div class="top">
|
<div class="left">
|
<span class="icon el-icon-video-camera"></span>
|
</div>
|
<div class="right">
|
<div class="name">{{group.groupName}}</div>
|
<div class="details">
|
<label>摄像机:</label>
|
<span
|
class="sub"
|
v-for="(camera,index) in group.cameras"
|
:key="camera.id"
|
>{{camera.name}} {{index!==group.cameras.length-1?'/':''}}</span>
|
</div>
|
</div>
|
</div>
|
<div class="bottom">
|
<span @click.stop="editGroup(group)">编辑分组</span>
|
<el-popconfirm title="确定删除该分组吗?" @onConfirm="removeGroup(group)">
|
<el-button slot="reference" type="text">删除分组</el-button>
|
</el-popconfirm>
|
</div>
|
</div>
|
</div>
|
</div>
|
<!-- <div class="part" v-if="groupList.length"> -->
|
<div class="part" v-if="groupList.length!==0 && Object.keys(curGroup)">
|
<div class="title">绘制区域(用于算法分析)</div>
|
<div class="relative-partment" v-if="curGroup.cameras&&curGroup.cameras.length">
|
<div class="area-wrap" v-for="i in 2" :key="'sc'+i">
|
<slide-canvas :cameras="curGroup.cameras" @polygonDataUpdate="polygonUpdate"></slide-canvas>
|
</div>
|
</div>
|
</div>
|
<div class="part relative-config" v-if="Object.keys(curGroup)">
|
<div class="title">
|
<div class="left">
|
<span>关联区域配置</span>
|
</div>
|
<div class="right" v-if="curGroup.id">
|
<el-button icon="el-icon-plus" size="mini" type="primary" @click="addRelation">添加关联</el-button>
|
</div>
|
</div>
|
<div class="relative-list">
|
<div class="relative-item" v-for="(item,index) in relativeList" :key="item.id">
|
<div class="left">
|
<el-select v-model="item.sourceObj" value-key="polygonId" size="small">
|
<el-option
|
v-for="area in cameraAreas"
|
:key="area.polygonId"
|
:label="area.name"
|
:value="area"
|
></el-option>
|
</el-select>
|
<i class="el-icon-connection"></i>
|
<el-select v-model="item.targetObj" value-key="polygonId" size="small">
|
<el-option
|
v-for="area in cameraAreas"
|
:key="area.polygonId"
|
:label="area.name"
|
:value="area"
|
></el-option>
|
</el-select>
|
</div>
|
<div class="right">
|
<el-button type="text" @click="saveRelativePolygon(item)">保存</el-button>
|
|
<el-popconfirm title="确定删除该配置吗?" @onConfirm="delRelation(item)" v-if="item.id">
|
<el-button class="btn-del" slot="reference" type="text" icon="el-icon-delete"></el-button>
|
</el-popconfirm>
|
<el-button
|
@click="delRelation(item,index)"
|
class="btn-del"
|
slot="reference"
|
type="text"
|
icon="el-icon-delete"
|
v-else
|
></el-button>
|
</div>
|
</div>
|
</div>
|
<!-- <div class="btns">
|
<el-button size="small" >取消</el-button>
|
<el-button size="small" type="primary" @click="saveRelativeList">保存</el-button>
|
</div>-->
|
<el-dialog
|
class="dialog-group"
|
:title="groupForm.id?'编辑分组':'新建分组'"
|
:visible.sync="groupModelVisible"
|
>
|
<el-form :model="groupForm" ref="groupForm">
|
<el-form-item>
|
<label>分组名称</label>
|
<div>
|
<el-input v-model="groupForm.groupName"></el-input>
|
</div>
|
</el-form-item>
|
<el-form-item>
|
<label>选择摄像机</label>
|
<div>
|
<el-select v-model="groupForm.cameras" value-key="id" multiple>
|
<el-option
|
:label="camera.name"
|
:value="camera"
|
v-for="camera in cameraData"
|
:key="camera.id"
|
></el-option>
|
</el-select>
|
</div>
|
</el-form-item>
|
<div class="btns">
|
<el-button @click="groupModelVisible=false;">取消</el-button>
|
<el-button type="primary" @click="confirmGroupDialog">确定</el-button>
|
</div>
|
</el-form>
|
</el-dialog>
|
</div>
|
</div>
|
</template>
|
|
<script>
|
import { getCamerasByServer } from '@/api/pollConfig';
|
import { findCameraGroups, saveCameraGroupInfo, delCameraGroup } from '@/api/camera';
|
import { getAllPolygon, saveRelationPolygon, findByCamGroup, findByGroup, delRelation } from '@/api/polygon';
|
import SlideCanvas from './SlideCanvas';
|
|
export default {
|
components: { SlideCanvas },
|
data () {
|
return {
|
cameraData: [],
|
relativeList: [],
|
cameraAreas: [],
|
groupModelVisible: false,
|
groupList: [],
|
curGroup: {},
|
groupForm: {
|
groupName: '',
|
cameras: []
|
},
|
groupCameras: [],
|
groupCamera: {
|
|
},
|
cameraAndPolygonData: []
|
}
|
},
|
mounted () {
|
this.getAllCameraData();
|
},
|
methods: {
|
getAllCameraData () {
|
let _this = this;
|
getCamerasByServer().then(res => {
|
if (res.success) {
|
_this.cameraData = res.data;
|
_this.getAllGroups();
|
}
|
}).catch(e => {
|
console.log(e)
|
})
|
},
|
polygonUpdate () {
|
this.getAllGroups();
|
},
|
delRelation (item, index) {
|
let _this = this;
|
if (item.id) {
|
delRelation(item.id).then(res => {
|
if (res.success) {
|
this.$notify({
|
type: 'success',
|
message: res.data
|
});
|
_this.findRelationByGroup();
|
}
|
})
|
}else{
|
this.relativeList.splice(index,1);
|
}
|
|
},
|
findRelationByGroup () {
|
let _this = this;
|
findByGroup({ groupId: this.curGroup.id }).then(res => {
|
|
_this.relativeList = res.data.map(relation => {
|
let obj = { sourceObj: {}, targetObj: {} };
|
obj.sourceObj.cameraId = relation.source_camera_id;
|
obj.sourceObj.polygonId = relation.source_polygon_id;
|
obj.targetObj.cameraId = relation.target_camera_id;
|
obj.targetObj.polygonId = relation.target_polygon_id;
|
obj.sourceObj.name = relation.source_polygon.name;
|
obj.targetObj.name = relation.target_polygon.name;
|
obj.id = relation.id;
|
return obj;
|
})
|
})
|
},
|
saveRelativePolygon (item) {
|
// debugger
|
if (!item.sourceObj || !item.targetObj) {
|
this.$notify({
|
type: 'warning',
|
message: '请完善关联区域信息!'
|
});
|
return;
|
}
|
if (item.sourceObj.cameraId == item.targetObj.cameraId) {
|
this.$notify({
|
type: 'warning',
|
message: '相同摄像机不存在关联区域,请重新选择!'
|
});
|
return;
|
}
|
let _this = this;
|
let params = {
|
groupId: this.curGroup.id,
|
source_camera_id: item.sourceObj.cameraId,
|
target_camera_id: item.targetObj.cameraId,
|
source_polygon_id: item.sourceObj.polygonId,
|
target_polygon_id: item.targetObj.polygonId,
|
id: item.id || ''
|
}
|
|
saveRelationPolygon(params).then(res => {
|
if (res.success) {
|
this.$notify({
|
type: 'success',
|
message: '保存成功',
|
});
|
_this.findRelationByGroup()
|
}
|
})
|
},
|
|
async findPolygonByIds (cameras) {
|
for (var i = 0; i < cameras.length; i++) {
|
let res = await getAllPolygon({ cameraId: cameras[i].id });
|
cameras[i].canvasData = res.data;
|
}
|
return cameras
|
},
|
|
async getAllGroupInfo () {
|
let _this = this;
|
let res = await findCameraGroups();
|
let groupArr = res.data.map(item => {
|
let obj = {}; //group
|
obj.groupName = item.groupName;
|
obj.id = item.id;
|
let cameras = []; //cameras
|
item.cameraIds.forEach(id => {
|
let camera = {};
|
_this.cameraData.find(one => {
|
if (one.id == id) {
|
camera.name = one.name;
|
camera.id = id;
|
}
|
});
|
cameras.push(camera)
|
});
|
//cameras [{id,name}]
|
obj.cameras = cameras;
|
return obj;
|
|
});
|
return groupArr;
|
},
|
// async getAllGroups () {
|
// let _this = this;
|
// let groups = await this.getAllGroupInfo();
|
// let promiseArr = [];
|
// for (var i = 0; i < groups.length; i++) {
|
// let pro = new Promise(resolve => {
|
// resolve(_this.findPolygonByIds(groups[i].cameras))
|
// });
|
// promiseArr.push(pro)
|
// }
|
// Promise.allSettled(promiseArr).then(camerasArr => {
|
|
// for (var i = 0; i < camerasArr.length; i++) {
|
// groups[i].cameras = camerasArr[i].value
|
// }
|
// _this.groupList = groups;
|
// //选中第一个
|
// _this.checkCurrentGroup(_this.groupList[0]);
|
// })
|
// },
|
async getAllGroups () {
|
let _this = this;
|
let groups = await this.getAllGroupInfo();
|
for (var i = 0; i < groups.length; i++) {
|
groups[i].cameras = await _this.findPolygonByIds(groups[i].cameras)
|
}
|
this.groupList = groups;
|
this.groupList.reverse();
|
//如果刚新建则选中第一个,编辑则选中编辑的那条
|
if (!this.groupForm.id) {
|
this.groupList.length && this.checkCurrentGroup(_this.groupList[0]);
|
} else {
|
let group = this.groupList.find(one => one.id == this.groupForm.id);
|
if(group){
|
this.groupList.length && this.checkCurrentGroup(group);
|
}else{
|
this.groupList.length && this.checkCurrentGroup(_this.groupList[0]);
|
}
|
|
}
|
|
|
},
|
|
addRelation () {
|
let obj = { cameraArea1: '', cameraArea2: '' };
|
this.relativeList.push(obj)
|
},
|
|
editGroup (group) {
|
// debugger
|
this.groupModelVisible = true;
|
//this.$refs['groupForm'].resetFields();
|
//this.groupForm = group;
|
this.groupForm = JSON.parse(JSON.stringify(group));
|
},
|
removeGroup (group) {
|
let _this = this;
|
delCameraGroup(group.id).then(res => {
|
_this.getAllGroups()
|
})
|
},
|
checkCurrentGroup (group) {
|
this.groupList.forEach(group => {
|
group.checked = false;
|
});
|
this.curGroup = group;
|
this.groupForm = JSON.parse(JSON.stringify(group));
|
this.curGroup.checked = true;
|
this.findRelationByGroup();
|
//查询第一个分组下摄像机区域
|
findByCamGroup({ groupId: group.id }).then(res => {
|
let tempArr = [];
|
res.data.forEach(camera => {
|
let cameraArea = [];
|
camera.polygon.forEach(item => {
|
let area = {};
|
area.name = camera.camera_name + '' + item.name;
|
area.cameraId = camera.camera_id;
|
area.polygonId = item.id;
|
cameraArea.push(area);
|
});
|
camera.rect.forEach(item => {
|
let area = {};
|
area.name = camera.camera_name + '' + item.name;
|
area.cameraId = camera.camera_id;
|
area.polygonId = item.id;
|
cameraArea.push(area);
|
});
|
tempArr = tempArr.concat(cameraArea)
|
});
|
this.cameraAreas = tempArr;
|
console.log(this.cameraAreas)
|
})
|
},
|
confirmGroupDialog () {
|
//请求保存新建或编辑分组
|
let _this = this;
|
let params = {
|
cameraIds: [],
|
groupName: '',
|
id: ''
|
};
|
if (!this.groupForm.groupName.trim()) {
|
this.$notify({
|
type: 'warning',
|
message: '请输入分组名称'
|
});
|
return
|
}
|
if (this.groupForm.cameras.length < 2) {
|
this.$notify({
|
type: 'warning',
|
message: '请选择至少两个摄像机'
|
});
|
return
|
}
|
params.groupName = this.groupForm.groupName;
|
params.id = this.groupForm.id || '';
|
this.groupForm.cameras.forEach(camera => {
|
params.cameraIds.push(camera.id);
|
//根据分组内摄像机id查各自区域
|
getAllPolygon({ cameraId: camera.id }).then(res => {
|
_this.groupCameras.push(res.data);
|
}).catch(e => {
|
console.log(e)
|
});
|
})
|
//this.groupList.push(this.groupForm);
|
saveCameraGroupInfo(params).then(res => {
|
if(res.success){
|
this.$notify({
|
type: 'success',
|
message: '保存成功!'
|
})
|
}
|
_this.getAllGroups();
|
})
|
this.groupModelVisible = false;
|
|
},
|
newGroup () {
|
this.groupModelVisible = true;
|
this.$nextTick(() => {
|
this.$refs['groupForm'].resetFields();
|
})
|
this.groupForm = {
|
groupName: '',
|
cameras: []
|
}
|
}
|
}
|
}
|
</script>
|
|
<style lang="scss">
|
.relate-camera {
|
padding: 20px 30px;
|
.el-alert--info {
|
background: rgba(230, 247, 255, 1);
|
border-color: rgba(145, 213, 255, 1);
|
color: #666;
|
.el-alert__icon.el-icon-info {
|
color: #1890ff;
|
}
|
}
|
.title {
|
text-align: left;
|
font-size: 15px;
|
line-height: 40px;
|
.el-button {
|
margin-left: 14px;
|
}
|
}
|
.group-card {
|
cursor: pointer;
|
background: #fff;
|
width: 293px;
|
height: 153px;
|
margin-right: 10px;
|
box-shadow: 0px 0px 8px 0px rgba(0, 0, 0, 0.1);
|
border: 1px solid transparent;
|
&.checked {
|
border-color: #1890ff;
|
}
|
.top {
|
height: 104px;
|
display: flex;
|
padding: 20px 20px 0;
|
box-sizing: border-box;
|
//align-items: center;
|
.right {
|
text-align: left;
|
padding-left: 14px;
|
}
|
.icon {
|
font-size: 40px;
|
}
|
.name {
|
font-size: 16px;
|
margin-bottom: 10px;
|
font-weight: bold;
|
}
|
.details {
|
display: -webkit-box;
|
overflow: hidden;
|
text-overflow: ellipsis;
|
word-break: break-all;
|
-webkit-box-orient: vertical;
|
-webkit-line-clamp: 2;
|
//flex-wrap: wrap;
|
label {
|
width: 46px;
|
}
|
.sub {
|
}
|
}
|
}
|
.bottom {
|
border-top: 1px solid #e9e9e9;
|
height: 48px;
|
line-height: 48px;
|
background: #f7f9fa;
|
position: relative;
|
display: flex;
|
&:after {
|
content: '';
|
position: absolute;
|
font-size: 0;
|
width: 1px;
|
height: 14px;
|
background: #0000006d;
|
top: 50%;
|
left: 50%;
|
transform: translate(-50%, -50%);
|
}
|
span {
|
cursor: pointer;
|
width: 50%;
|
font-size: 14px;
|
color: #0000006d;
|
}
|
}
|
}
|
.part {
|
margin-bottom: 20px;
|
.relative-partment {
|
width: 1200px;
|
margin: 0 auto;
|
display: flex;
|
justify-content: space-between;
|
.area-wrap {
|
width: 576px;
|
}
|
}
|
}
|
.relative-config {
|
width: 700px;
|
.title {
|
display: flex;
|
justify-content: space-between;
|
}
|
.relative-list {
|
.relative-item {
|
width: 680px;
|
height: 48px;
|
padding-left: 20px;
|
background: #ecf2f5;
|
margin-bottom: 6px;
|
display: flex;
|
align-items: center;
|
.left {
|
width: 650px;
|
text-align: left;
|
}
|
.right {
|
display: flex;
|
align-items: center;
|
.el-button + .el-button{
|
margin-left: 0;
|
}
|
}
|
i {
|
font-size: 20px;
|
padding: 0 10px;
|
cursor: pointer;
|
}
|
}
|
}
|
}
|
.dialog-group {
|
.el-form {
|
.el-form-item__content {
|
display: flex;
|
label {
|
width: 80px;
|
text-align: left;
|
}
|
& > div {
|
flex: 1;
|
.el-select {
|
width: 100%;
|
}
|
}
|
}
|
}
|
}
|
}
|
</style>
|