2025-06-09 09:51:51 +08:00

357 lines
9.2 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<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>