357 lines
9.2 KiB
Vue
Raw Normal View History

2025-06-09 09:51:51 +08:00
<template>
<div class="map-content">
<div class="map-box" id="mapContainer" @drop="handleMapDrop" @dragover.prevent></div>
<div class="device-box">
<div class="box-content">
<div class="box-title">
<span>场内布点</span>
<el-button type="primary" @click="addPoint" size="medium">添加点位</el-button>
</div>
<!-- <vue-scroll :ops="{ scrollPanel: { overflowX: false } }">
<div style="margin: 5px 0"></div>
<div
v-for="item in pointList"
:key="item.devSn"
class="point-item"
draggable="true"
@dragstart="handleDragStart(item)"
@click="handleClick(item)"
>
<div class="point-name">{{ item.name }}</div>
<div @click="deletePoint(item)" class="delete-point" v-if="item.lng && item.lat">
<i class="el-icon-delete"></i>
清除位置
</div>
</div>
</vue-scroll> -->
<el-table :data="pointList">
<el-table-column label="点位名称" prop="name"></el-table-column>
<el-table-column label="图标" prop="coverImage" width="50px">
<template #default="scope">
<img
v-if="scope.row.coverImage"
:src="$store.state.FILEURL + scope.row.coverImage"
alt=""
style="width: 20px; height: 20px"
/>
</template>
</el-table-column>
<el-table-column label="备注" prop="remark"></el-table-column>
<el-table-column label="操作" prop="operation">
<template #default="scope">
<div class="operation-box">
<i class="el-icon-edit" @click="editPoint(scope.row)"></i>
<i class="el-icon-delete" @click="deletePoint(scope.row)"></i>
<el-link v-if="scope.row.lat && scope.row.lng" type="danger" :underline="false" @click="clearPoint(scope.row)"
>清除位置</el-link
>
<el-link v-else type="primary" :underline="false" @click="goPoint(scope.row)">去标点</el-link>
</div>
</template>
</el-table-column>
</el-table>
</div>
</div>
<add-point-dialog :visible.sync="dialogVisible" :data-info="dialogDataInfo" @refresh="getPointList()"></add-point-dialog>
</div>
</template>
<script>
import addPointDialog from './components/addPointDialog.vue'
import {
getDevListApi,
editDevicePositionApi,
clearLocateApi,
addDevicePositionApi,
deleteDevicePositionApi
} from '@/assets/js/api/smartSafeHat/smartSafeHat'
var mouseTool
var map
export default {
components: {
addPointDialog
},
data() {
return {
dialogVisible: false,
dialogDataInfo: null,
deviceType: 3, // 类别(1、视频监控2、扬尘设备3、场站11、塔吊12、架桥机13、龙门吊14、升降机)
addForm: {
locationList: [
{
fenceId: 0,
id: 0,
latitude: '',
longitude: '',
sortNum: 0
}
],
projectSn: '',
enterpriseId: ''
},
pointList: [],
markers: {},
curItem: {},
selectPointStatus: false
}
},
mounted() {
this.initMap()
this.getPointList(true)
},
methods: {
// 围栏定位地图
initMap() {
var that = this
//地图加载
map = new AMap.Map('mapContainer', {
resizeEnable: true
})
map.on('click', e => {
if (!this.selectPointStatus) {
return
}
console.log('您在 [ ' + e.lnglat.getLng() + ',' + e.lnglat.getLat() + ' ] 的位置单击了地图!')
this.curItem.lng = e.lnglat.getLng()
this.curItem.lat = e.lnglat.getLat()
this.addMarker(this.curItem)
this.savePointPosition(this.curItem)
console.log('当前位置列表', this.locationList)
})
},
addPoint() {
this.dialogVisible = true
this.dialogDataInfo = null
},
editPoint(data) {
this.dialogDataInfo = data
this.dialogVisible = true
},
handleClick(item) {
if (item.lng && item.lat) {
map.setCenter([item.lng, item.lat])
}
},
handleDragStart(item) {
// 将拖拽数据存储在事件中
event.dataTransfer.setData('text/plain', JSON.stringify(item))
},
handleMapDrop(event) {
// 获取拖拽数据
const item = JSON.parse(event.dataTransfer.getData('text/plain'))
// 获取地图坐标
const { lng, lat } = map.getCenter()
console.log('handleMapDrop', event, item)
// 检查是否已存在marker
if (this.markers[item.devSn]) {
this.$message.warning('设备已存在')
} else {
item.lng = lng
item.lat = lat
this.addMarker(item)
// 保存位置信息
this.savePointPosition(item)
}
},
async savePointPosition(item) {
const api = item.monitorId ? editDevicePositionApi : addDevicePositionApi
api({ ...item, projectSn: this.$store.state.projectSn }).then(res => {
if (res.success) {
this.$message.success(res.message)
this.getPointList()
}
})
},
deletePoint(item) {
deleteDevicePositionApi({ monitorId: item.monitorId }).then(res => {
if (res.success) {
this.$message.success(res.message)
if (this.markers[item.devSn]) {
map.remove(this.markers[item.devSn])
delete this.markers[item.devSn]
}
this.getPointList()
}
})
},
clearPoint(item) {
clearLocateApi({ monitorId: item.monitorId }).then(res => {
if (res.success) {
this.$message.success(res.message)
map.remove(this.markers[item.devSn])
delete this.markers[item.devSn]
this.getPointList()
}
})
},
goPoint(data) {
this.curItem = data
this.selectPointStatus = true
},
getPointList(loadMap = false) {
let data = {
category: this.deviceType,
projectSn: this.$store.state.projectSn
}
getDevListApi(data).then(res => {
if (res.success) {
this.pointList = res.result
console.log('围栏', this.pointList)
if (loadMap) {
this.markers = {}
this.clearFn()
this.initAllMarker()
}
}
})
},
//清空地图
clearFn() {
map.clearMap()
},
//添加点标记
addMarker(item) {
// 创建新marker
const marker = new AMap.Marker({
position: [item.lng, item.lat],
draggable: true
})
this.markers[item.devSn] = marker
marker.setMap(map)
marker.on('dragend', e => {
console.log('拖拽结束', e)
item.lng = e.lnglat.lng
item.lat = e.lnglat.lat
// 保存位置信息
this.savePointPosition(item)
})
marker.setLabel({
offset: new AMap.Pixel(0, -8), //设置文本标注偏移量
content: item.name, //设置文本标注内容
direction: 'top' //设置文本标注方位
})
this.selectPointStatus = false;
},
initAllMarker() {
this.pointList.forEach(item => {
if (item.lng && item.lat) {
this.addMarker(item)
}
})
map.setFitView()
}
}
}
</script>
<style lang="scss" scoped>
.map-content {
width: 100%;
height: 100%;
position: relative;
}
#mapContainer {
width: 100%;
height: 100%;
}
// 围栏弹窗
.device-box {
position: absolute;
background: #fff;
box-sizing: border-box;
padding: 25px;
left: 2%;
top: 20px;
width: 550px;
height: 500px;
z-index: 1;
.fence-dialog-modal {
position: absolute;
width: 100%;
height: 100%;
top: 0%;
left: 0%;
z-index: 3;
background: rgba(39, 45, 69, 0.5);
}
.close-icon {
position: absolute;
top: 0px;
right: 0px;
cursor: pointer;
}
.box-title {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20px;
span {
border-left: 4px solid #5c81ee;
font-size: 15px;
color: #272d45;
padding-left: 10px;
font-weight: 600;
font-family: Source Han Sans CN, Source Han Sans CN;
}
}
}
.box-content {
position: relative;
.fence-tool {
display: flex;
justify-content: space-around;
padding: 0 25px;
.tool {
display: flex;
align-items: center;
justify-content: center;
width: 80px;
height: 33px;
font-size: 14px;
cursor: pointer;
background: #ffffff;
color: #5181f6;
border-radius: 2px 2px 2px 2px;
border: 1px solid #5181f6;
}
}
.box-select {
margin: 15px 0;
}
.box-list {
height: 160px;
}
}
.point-item {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 10px;
cursor: move;
.point-name {
font-size: 14px;
color: #272d45;
flex: 1;
}
.delete-point {
font-size: 14px;
color: #ea3941;
cursor: pointer;
}
}
.operation-box {
display: flex;
align-items: center;
gap: 10px;
i {
cursor: pointer;
color: #5181f6;
}
}
</style>