<template>
<el-dialog :visible.sync="show" width="1000px" title="设备分布设置">
<section class="btns">
<div class="upload">
<input type="file" @change="upload">
上传图片
</div>
<el-button type="success" size="small" @click="send">提交设置</el-button>
<el-button type="danger" size="small" @click="markers = []">清除设置</el-button>
</section>
<section class="content">
<div class="imgBox">
<el-tooltip placement="top" v-for="(item, key) in markers" :key=key>
<div slot="content" class="tips">{{item.deviceName}}<i class="el-icon-circle-close" @click="remove(key)"></i>
</div>
<i class="marker" @mousedown="move($event, key)" :style="{left: item.left, top: item.top}">{{key + 1}}
</i>
</el-tooltip>
<img :src="`${url}file/download/${imageId}`" alt="" @load="imgload" ref="img" draggable="false" v-if="imageId">
</div>
<div class="list">
<header>选择设备</header>
<div v-for="(item, key) in list" :key=key class="item">
<span>{{item.deviceName}}</span> <i class="el-icon-circle-plus" @click="add(item, key)"></i>
</div>
</div>
</section>
</el-dialog>
</template>
<script>
import common from '@/api/common'
import device from '@/api/device/device'
import monitorPoint from '@/api/monitor/monitorPoint'
export default {
name: 'deviceSet',
data() {
return {
url: process.env.VUE_APP_BASE_API,
monitorPointId: '',
imageId: '',
show: false,
list: [],
markers: [],
height: 0
}
},
created() { },
methods: {
init(data = {}) {
this.list = []
this.markers = []
this.imageId = ''
this.monitorPointId = data.id
monitorPoint.getAssignPic(this.monitorPointId).then(({ flag, object }) => {
if (flag == '0') {
this.imageId = object.id
}
})
device.getList({
monitorPointId: this.monitorPointId
}).then(res => {
res.forEach(item => {
if (item.leftPos || item.topPos) {
this.markers.push({
id: item.id,
deviceName: item.deviceName,
left: item.leftPos + '%',
top: item.topPos + '%',
})
} else {
this.list.push({
id: item.id,
deviceName: item.deviceName
})
}
})
})
this.show = true
},
imgload() {
this.height = this.$refs.img.height
},
upload(e) {
const files = e.target.files
let param = new FormData()
param.append('file', files[0])
common.upload(param).then(({ flag, object, msg }) => {
if (flag == 0) {
this.imageId = object[0].id
}
})
e.target.value = null
},
send() {
if (!this.imageId) {
this.$fns.error('请先上传图片!')
return;
}
if (this.markers.length == 0) {
this.$fns.error('请先设置一个设备!')
return;
}
const data = this.markers.map(item => {
return {
id: item.id,
leftPos: item.positon ? item.positon.left : item.left.slice(0, -1) * 1,
topPos: item.positon ? item.positon.top : item.top.slice(0, -1) * 1
}
})
const load = this.$fns.loading()
device.savePos({
monitorPointId: this.monitorPointId,
assignPic: this.imageId,
posList: data
}).then(({ flag, msg }) => {
load.close()
if (flag == 0) {
this.$fns.success(msg, false)
this.show = false
}
})
},
add(item, i) {
if (!this.imageId) {
this.$fns.error('请先上传图片')
return;
}
this.list.splice(i, 1)
this.markers.push({
id: item.id,
deviceName: item.deviceName,
left: 0,
top: 0
})
},
remove(i) {
this.list.push(this.markers[i])
this.markers.splice(i, 1)
},
move(e, i) {
const self = this
let odiv = e.target;
let disX = e.clientX - odiv.offsetLeft
let disY = e.clientY - odiv.offsetTop
document.onmousemove = (e) => {
let left = e.clientX - disX;
let top = e.clientY - disY;
self.markers[i].left = left + 'px'
self.markers[i].top = top + 'px'
self.markers[i].positon = {
top: top / self.height * 100,
left: left / 7.2,
}
}
document.onmouseup = (e) => {
document.onmousemove = null
document.onmouseup = null
}
}
}
}
</script>
<style lang="scss" scoped>
section.btns {
display: flex;
align-items: center;
}
.upload {
margin-right: 10px;
font-size: 12px;
border-radius: 3px;
color: #fff;
background-color: #409eff;
border-color: #409eff;
height: 32px;
width: 80px;
display: flex;
justify-content: center;
align-items: center;
position: relative;
overflow: hidden;
&:hover {
background: #66b1ff;
border-color: #66b1ff;
color: #fff;
}
input {
cursor: pointer;
position: absolute;
left: 0;
top: 0;
opacity: 0;
width: 100%;
height: 100%;
}
}
.content {
margin-top: 15px;
display: flex;
.imgBox {
width: 720px;
position: relative;
img {
width: 100%;
pointer-events: none;
}
.marker {
position: absolute;
display: flex;
flex-direction: column;
align-items: center;
width: 20px;
height: 20px;
background-color: #f00;
border-radius: 50px;
cursor: pointer;
outline: none;
border: 2px solid #fff;
color: #fff;
font-weight: bold;
}
}
.list {
flex: 1;
margin-left: 10px;
border: 1px solid #ebeef5;
display: flex;
flex-direction: column;
header {
background-color: #f9f9f9;
padding: 10px;
line-height: 22px;
color: #909399;
font-weight: bold;
border-bottom: 1px solid #ebeef5;
}
.item {
display: flex;
align-items: center;
justify-content: space-between;
height: 42px;
padding: 0 8px;
border-bottom: 1px solid #ebeef5;
i {
cursor: pointer;
}
}
}
}
</style>
img的数据格式
右侧list的数据格式;
根据 leftPos 和 topPos , 计算 红色标记在图片上的位置