|
@@ -1,31 +1,405 @@
|
|
<template>
|
|
<template>
|
|
<div style="width: 100%; height: 800px">
|
|
<div style="width: 100%; height: 800px">
|
|
- <iframe v-bind:src="mapUrl" frameborder="0" style="width: 100%; height: 100%"></iframe>
|
|
|
|
|
|
+ <div v-if="mapUrl">
|
|
|
|
+ <iframe v-bind:src="mapUrl" frameborder="0" style="width: 100%; height: 100%"></iframe>
|
|
|
|
+ </div>
|
|
|
|
+
|
|
|
|
+ <div v-else>
|
|
|
|
+ <baidu-map v-if="isShow" style="height: 800px" :center="center" :zoom="zoom" scroll-wheel-zoom @ready="handler" @click="clickMap">
|
|
|
|
+ <bm-control>
|
|
|
|
+ <div style="margin: 20px">
|
|
|
|
+ <el-tooltip class="item" effect="dark" :content="$t('tcpType.LOCATION')" placement="right-start">
|
|
|
|
+ <el-button type="success" icon="el-icon-location-outline" :disabled="disable" circle plain @click="changeType(0)"></el-button>
|
|
|
|
+ </el-tooltip>
|
|
|
|
+ <el-tooltip class="item" effect="dark" content="刷新" placement="right-start">
|
|
|
|
+ <el-button type="primary" icon="el-icon-refresh-left" :disabled="disable" circle plain @click="changeType(1)"></el-button>
|
|
|
|
+ </el-tooltip>
|
|
|
|
+ <el-tooltip class="item" effect="dark" :content="$t('customerManage.footprint')" placement="right-start">
|
|
|
|
+ <el-button type="warning" icon="el-icon-rank" circle plain @click="changeType(-1)"></el-button>
|
|
|
|
+ </el-tooltip>
|
|
|
|
+ <el-tooltip class="item" effect="dark" content="安全围栏" placement="right-start">
|
|
|
|
+ <el-button type="danger" icon="el-icon-s-help" circle plain @click="changeType(2)"></el-button>
|
|
|
|
+ </el-tooltip>
|
|
|
|
+ </div>
|
|
|
|
+ </bm-control>
|
|
|
|
+<!-- <bm-control>-->
|
|
|
|
+<!-- <div style="margin: 20px">-->
|
|
|
|
+<!-- <button @click="addZoom(19)">缩放至最大</button>-->
|
|
|
|
+<!-- <button @click="addZoom(10)">还原</button>-->
|
|
|
|
+<!-- <button @click="addZoom(3)">缩放至最小</button>-->
|
|
|
|
+<!-- </div>-->
|
|
|
|
+<!-- </bm-control>-->
|
|
|
|
+
|
|
|
|
+ <div v-if="type === -1">
|
|
|
|
+ <!-- 轨迹 -->
|
|
|
|
+ <!-- 添加起点标记 -->
|
|
|
|
+ <bm-marker v-if="dataList.length > 1" :position="endPoint" @mouseover="clickMap">
|
|
|
|
+ <bm-label content="终点" :offset="{width: 0, height: 30}"/>
|
|
|
|
+ <bm-info-window v-if="myContent" :show="true" @close="infoWindowClose">
|
|
|
|
+ <p>{{ unixDateFormatter(dataList[dataList.length - 1].position_time) }}</p>
|
|
|
|
+ <p style="color: #4abe84">{{ myContent }}</p>
|
|
|
|
+ </bm-info-window></bm-marker>
|
|
|
|
+ <!-- 添加终点标记 -->
|
|
|
|
+ <bm-marker :position="markers[0]">
|
|
|
|
+ <bm-label content="起点" :offset="{width: 0, height: 30}"/>
|
|
|
|
+ </bm-marker>
|
|
|
|
+ <!-- 折线 -->
|
|
|
|
+ <bm-polyline :path="markers" stroke-color="#4aa4f3" :stroke-opacity="1" :stroke-weight="6" stroke-style="dashed"
|
|
|
|
+ @lineupdate="updatePolylinePath" />
|
|
|
|
+ <!-- <bm-polyline :path="markers" stroke-color="red" :stroke-opacity="0.5" :stroke-weight="2"></bm-polyline>-->
|
|
|
|
+ <bml-lushu @stop="reset" :path="markers" :icon="icon" :play="play" :autoView="true" :speed="700"></bml-lushu>
|
|
|
|
+ <!-- 轨迹 -->
|
|
|
|
+ </div>
|
|
|
|
+ <div v-else-if="type === 2">
|
|
|
|
+ <!-- 圆形围栏 -->
|
|
|
|
+ <bm-circle v-if="boolCircle" :center="circleCenter" :radius="securityFence.radius" stroke-color="red" :stroke-opacity="0.5" :stroke-weight="2" @lineupdate="updateCirclePath" :editing="editing"></bm-circle>
|
|
|
|
+ <bm-marker v-if="boolCircle" :position="circleCenter">
|
|
|
|
+ <bm-info-window :show="true">
|
|
|
|
+ <p>{{ securityFence.address }}</p>
|
|
|
|
+ <div style="color: #4abe84">半径:{{ securityFence.radius }} 米
|
|
|
|
+ <el-button type="primary" icon="el-icon-edit" size="mini" plain @click="API_SaveFence">保存</el-button>
|
|
|
|
+ <el-button v-if="securityFence.id" type="danger" icon="el-icon-delete" size="mini" plain @click="API_DelFence">删除</el-button>
|
|
|
|
+ </div>
|
|
|
|
+
|
|
|
|
+ </bm-info-window>
|
|
|
|
+ </bm-marker>
|
|
|
|
+ <!-- 圆形围栏 -->
|
|
|
|
+ </div>
|
|
|
|
+ <div v-else>
|
|
|
|
+ <bm-marker :position="markers[0]" animation="BMAP_ANIMATION_BOUNCE" @mouseover="mouseoverMap">
|
|
|
|
+ <bm-info-window v-if="myContent" :show="true" @close="infoWindowClose">
|
|
|
|
+ <p>{{ unixDateFormatter(dataList[0].position_time) }}</p>
|
|
|
|
+ <p style="color: #4abe84">{{ myContent }}</p>
|
|
|
|
+ </bm-info-window>
|
|
|
|
+ </bm-marker>
|
|
|
|
+ </div>
|
|
|
|
+
|
|
|
|
+ </baidu-map>
|
|
|
|
+ </div>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
</template>
|
|
|
|
|
|
<script>
|
|
<script>
|
|
|
|
+import walkImg from '@/icons/images/walk.png'
|
|
|
|
+import { BmlLushu } from 'vue-baidu-map'
|
|
|
|
+import { getLocationList } from '@/api/initialize'
|
|
|
|
+import { unix2Date } from '@/utils/Foundation'
|
|
|
|
+import * as API_MemberLocation from '@/api/member_location'
|
|
|
|
+import { getDeviceList } from '@/api/ncs_device'
|
|
|
|
+import { DEVICE_TYPE } from '@/utils/enum/DeviceTypeEnum'
|
|
|
|
+
|
|
export default {
|
|
export default {
|
|
name: "myMapHtml",
|
|
name: "myMapHtml",
|
|
- // props: {
|
|
|
|
- // mapUrl: {
|
|
|
|
- // type: String,
|
|
|
|
- // default: ''
|
|
|
|
- // }
|
|
|
|
- // },
|
|
|
|
|
|
+ components: {
|
|
|
|
+ BmlLushu
|
|
|
|
+ },
|
|
data() {
|
|
data() {
|
|
return {
|
|
return {
|
|
- mapUrl: null
|
|
|
|
|
|
+ mapUrl: null,
|
|
|
|
+ uuid: null,
|
|
|
|
+ frameId: null,
|
|
|
|
+ center: '北京',
|
|
|
|
+ zoom: 16,
|
|
|
|
+ isShow: false,
|
|
|
|
+ markers: [],
|
|
|
|
+ play: false, //是否行进
|
|
|
|
+ icon: { // 覆盖物的图标
|
|
|
|
+ url: walkImg,
|
|
|
|
+ size: { width: 220, height: 220 },
|
|
|
|
+ opts: { anchor: { width: 0, height: 113 } }
|
|
|
|
+ },
|
|
|
|
+ boolCircle: false,
|
|
|
|
+ type: 1,
|
|
|
|
+ myContent: '',
|
|
|
|
+ params: {
|
|
|
|
+ page_size: 1,
|
|
|
|
+ page_no: 1,
|
|
|
|
+ sort: 'position_time',
|
|
|
|
+ dir: 'desc',
|
|
|
|
+ },
|
|
|
|
+ dataList:[],
|
|
|
|
+ disable: false,
|
|
|
|
+ deviceList: [],
|
|
|
|
+ circleCenter: {
|
|
|
|
+ lng: 113.971151,
|
|
|
|
+ lat: 22.570388
|
|
|
|
+ },
|
|
|
|
+ securityFence: {
|
|
|
|
+ radius: 200
|
|
|
|
+ },
|
|
|
|
+ editing: false
|
|
}
|
|
}
|
|
},
|
|
},
|
|
created() {
|
|
created() {
|
|
},
|
|
},
|
|
|
|
+ computed: {
|
|
|
|
+ //终点计算
|
|
|
|
+ endPoint() {
|
|
|
|
+ if (this.markers && this.markers.length > 0) {
|
|
|
|
+ return this.markers[this.markers.length - 1]
|
|
|
|
+ }
|
|
|
|
+ return null;
|
|
|
|
+ }
|
|
|
|
+ },
|
|
mounted() {
|
|
mounted() {
|
|
this.mapUrl = this.$route.query.mapUrl
|
|
this.mapUrl = this.$route.query.mapUrl
|
|
|
|
+ if (!this.mapUrl) {
|
|
|
|
+ this.uuid = this.$route.query.uuid
|
|
|
|
+ this.frameId = this.$route.query.frameId
|
|
|
|
+ this.params.fixedCondition = " member_union_id = '" + this.uuid + "'"
|
|
|
|
+ this.handleMapData()
|
|
|
|
+ this.API_GetDeviceList()
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ methods: {
|
|
|
|
+ //处理数据
|
|
|
|
+ handleMapData() {
|
|
|
|
+ let markers = []
|
|
|
|
+ this.myContent = null
|
|
|
|
+ getLocationList(this.params).then(res => {
|
|
|
|
+ this.disable = false
|
|
|
|
+ this.dataList = res.data
|
|
|
|
+ this.dataList.sort(function (a, b) {
|
|
|
|
+ return a.position_time - b.position_time
|
|
|
|
+ })
|
|
|
|
+ if (res.data.length > 0) {
|
|
|
|
+ this.dataList.forEach(item => {
|
|
|
|
+ markers.push({lng: item.longitude, lat: item.latitude})
|
|
|
|
+ })
|
|
|
|
+ this.markers = markers
|
|
|
|
+ this.center = this.markers[0]
|
|
|
|
+ }
|
|
|
|
+ this.play = true
|
|
|
|
+ this.isShow = true
|
|
|
|
+ })
|
|
|
|
+ },
|
|
|
|
+ handler ({BMap, map}) {
|
|
|
|
+ if (this.markers.length > 0 && this.type !== 2) {
|
|
|
|
+ let view = map.getViewport(eval(this.markers))
|
|
|
|
+ this.zoom = view.zoom
|
|
|
|
+ console.log('zoom===', this.zoom)
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ async API_GetDeviceList() {
|
|
|
|
+ getDeviceList(this.frameId, DEVICE_TYPE.WATCH_IW).then(res => {
|
|
|
|
+ this.deviceList = res
|
|
|
|
+ })
|
|
|
|
+ },
|
|
|
|
+ // 停止本次移动
|
|
|
|
+ reset() {
|
|
|
|
+ this.play = false
|
|
|
|
+ },
|
|
|
|
+ // 覆盖物的属性发生变化时触发
|
|
|
|
+ updatePolylinePath(e) {
|
|
|
|
+ this.markers = e.target.getPath()
|
|
|
|
+ },
|
|
|
|
+ updateCirclePath (e) {
|
|
|
|
+ this.circleCenter = e.target.getCenter()
|
|
|
|
+ this.securityFence.radius = Math.ceil(e.target.getRadius())
|
|
|
|
+ console.log('修改围栏参数:', this.circleCenter, this.securityFence.radius)
|
|
|
|
+ },
|
|
|
|
+ mouseoverMap(e) {
|
|
|
|
+ if (this.myContent) {
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+ const geoCoder = new BMap.Geocoder()
|
|
|
|
+ // 利用坐标获取地址的详细信息
|
|
|
|
+ geoCoder.getLocation(e.point, (res) => {
|
|
|
|
+ console.log(res)
|
|
|
|
+ if (res.surroundingPois[0]) {
|
|
|
|
+ this.myContent = res.surroundingPois[0].title + '附近'
|
|
|
|
+ } else {
|
|
|
|
+ this.myContent = res.address + '附近'
|
|
|
|
+ }
|
|
|
|
+ console.log('地址为' + this.myContent)
|
|
|
|
+ })
|
|
|
|
+ },
|
|
|
|
+ clickMap(e) {
|
|
|
|
+ console.log(e.point)
|
|
|
|
+ if (this.type !== 2) {
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+ this.circleCenter = e.point
|
|
|
|
+ this.boolCircle = false
|
|
|
|
+ this.getAddress(e.point)
|
|
|
|
+ },
|
|
|
|
+ getAddress(point) {
|
|
|
|
+ const geoCoder = new BMap.Geocoder()
|
|
|
|
+ // 利用坐标获取地址的详细信息
|
|
|
|
+ geoCoder.getLocation(point, (res) => {
|
|
|
|
+ console.log(res)
|
|
|
|
+ if (res.surroundingPois[0]) {
|
|
|
|
+ this.securityFence.address = res.surroundingPois[0].title + '附近'
|
|
|
|
+ } else {
|
|
|
|
+ this.securityFence.address = res.address + '附近'
|
|
|
|
+ }
|
|
|
|
+ this.boolCircle = true
|
|
|
|
+ console.log('circleContent地址为' + this.securityFence.address)
|
|
|
|
+ })
|
|
|
|
+ const _this = this
|
|
|
|
+ if (!this.editing) {
|
|
|
|
+ setTimeout(() => {
|
|
|
|
+ _this.editing = true
|
|
|
|
+ }, 1000)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ },
|
|
|
|
+ changeType(type) {
|
|
|
|
+ switch (type) {
|
|
|
|
+ case 0:
|
|
|
|
+ this.type = 0
|
|
|
|
+ if (this.deviceList.length === 0) {
|
|
|
|
+ this.$message({
|
|
|
|
+ message: '没有定位设备',
|
|
|
|
+ type: 'info'
|
|
|
|
+ })
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+ this.disable = true
|
|
|
|
+ this.API_GetLocation()
|
|
|
|
+ break
|
|
|
|
+ case 1:
|
|
|
|
+ this.type = 1
|
|
|
|
+ this.disable = true
|
|
|
|
+ this.params.page_size = 1
|
|
|
|
+ this.isShow = false
|
|
|
|
+ this.handleMapData()
|
|
|
|
+ break
|
|
|
|
+ case 2:
|
|
|
|
+ if (this.deviceList.length === 0) {
|
|
|
|
+ this.$message({
|
|
|
|
+ message: '没有定位设备',
|
|
|
|
+ type: 'info'
|
|
|
|
+ })
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+ this.type = 2
|
|
|
|
+ this.boolCircle = true
|
|
|
|
+ this.API_GetFenceList()
|
|
|
|
+ break
|
|
|
|
+ default:
|
|
|
|
+ this.type = -1
|
|
|
|
+ this.params.page_size = 20
|
|
|
|
+ this.isShow = false
|
|
|
|
+ this.handleMapData()
|
|
|
|
+ break
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ infoWindowClose() {
|
|
|
|
+ this.myContent = null
|
|
|
|
+ this.circleCenter = null
|
|
|
|
+ },
|
|
|
|
+ /** 格式化时间函数 */
|
|
|
|
+ unixDateFormatter(time) {
|
|
|
|
+ return unix2Date(time * 1000)
|
|
|
|
+ },
|
|
|
|
+ API_GetLocation() {
|
|
|
|
+ API_MemberLocation.getLocation(this.deviceList[0].eth_mac).then(res => {
|
|
|
|
+ if (res.success) {
|
|
|
|
+ const data = JSON.parse(res.data)
|
|
|
|
+ if (data.Data.Code === 'iot.messagebroker.OFFLINE') {
|
|
|
|
+ this.$message({
|
|
|
|
+ message: '设备离线,操作失败',
|
|
|
|
+ type: 'info'
|
|
|
|
+ })
|
|
|
|
+ this.disable = false
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+ this.$message({
|
|
|
|
+ message: '正在定位,请稍后',
|
|
|
|
+ type: 'info'
|
|
|
|
+ })
|
|
|
|
+ const _this = this
|
|
|
|
+ setTimeout(() => {
|
|
|
|
+ _this.params.page_size = 1
|
|
|
|
+ _this.isShow = false
|
|
|
|
+ _this.handleMapData()
|
|
|
|
+ _this.disable = false
|
|
|
|
+ }, 15000)
|
|
|
|
+ } else {
|
|
|
|
+ this.$message.error(this.$t('action.handleFailed'))
|
|
|
|
+ this.disable = false
|
|
|
|
+ }
|
|
|
|
+ }).catch(err => {
|
|
|
|
+ console.log('定位异常...', err)
|
|
|
|
+ this.disable = false
|
|
|
|
+ })
|
|
|
|
+ },
|
|
|
|
+ API_GetFenceList() {
|
|
|
|
+ const data = {
|
|
|
|
+ unionId: this.uuid,
|
|
|
|
+ imei: this.deviceList[0].eth_mac,
|
|
|
|
+ type: 0
|
|
|
|
+ }
|
|
|
|
+ const _this = this
|
|
|
|
+ API_MemberLocation.getMemberSecurityFence(data).then(res => {
|
|
|
|
+ if (res.length > 0) {
|
|
|
|
+ _this.securityFence = res[0]
|
|
|
|
+ _this.circleCenter = { lng: _this.securityFence.longitude, lat: _this.securityFence.latitude }
|
|
|
|
+ _this.center = this.circleCenter
|
|
|
|
+ _this.boolCircle = true
|
|
|
|
+ } else {
|
|
|
|
+ _this.securityFence = {
|
|
|
|
+ radius: 200,
|
|
|
|
+ imei: _this.deviceList[0].eth_mac,
|
|
|
|
+ member_union_id: _this.uuid,
|
|
|
|
+ type: 0,
|
|
|
|
+ address: ''
|
|
|
|
+ }
|
|
|
|
+ if (_this.center) {
|
|
|
|
+ _this.circleCenter = _this.center
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ console.log('this.boolCircle==', _this.boolCircle, _this.circleCenter)
|
|
|
|
+ }).catch(err => {
|
|
|
|
+ console.log('获取围栏异常...', err)
|
|
|
|
+ })
|
|
|
|
+ },
|
|
|
|
+ API_SaveFence() {
|
|
|
|
+ if (this.securityFence.radius < 200) {
|
|
|
|
+ this.$message({
|
|
|
|
+ message: '围栏半径不能小于200',
|
|
|
|
+ type: 'info'
|
|
|
|
+ })
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+ if (this.securityFence.radius > 2000) {
|
|
|
|
+ this.$message({
|
|
|
|
+ message: '围栏半径不能超过2000米',
|
|
|
|
+ type: 'info'
|
|
|
|
+ })
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+ this.securityFence.longitude = this.circleCenter.lng
|
|
|
|
+ this.securityFence.latitude = this.circleCenter.lat
|
|
|
|
+ API_MemberLocation.saveMemberSecurityFence(this.securityFence).then(res => {
|
|
|
|
+ this.$message.success(this.$t('action.handleSuccess'))
|
|
|
|
+ }).catch(err => {
|
|
|
|
+ console.log('设置围栏异常...', err)
|
|
|
|
+ })
|
|
|
|
+ },
|
|
|
|
+ API_DelFence() {
|
|
|
|
+ this.$confirm(this.$t('action.sureDelete'), this.$t('action.waring'), {
|
|
|
|
+ confirmButtonText: this.$t('action.yes'),
|
|
|
|
+ cancelButtonText: this.$t('action.cancel'),
|
|
|
|
+ type: 'warning'
|
|
|
|
+ }).then(() => {
|
|
|
|
+ API_MemberLocation.delMemberSecurityFence(this.securityFence.id).then(res => {
|
|
|
|
+ this.$message.success(this.$t('action.handleSuccess'))
|
|
|
|
+ this.API_GetFenceList()
|
|
|
|
+ }).catch(err => {
|
|
|
|
+ console.log('删除围栏异常...', err)
|
|
|
|
+ })
|
|
|
|
+ }).catch(() => {
|
|
|
|
+ this.$message({
|
|
|
|
+ type: 'info',
|
|
|
|
+ message: this.$t('action.cancelDelete')
|
|
|
|
+ })
|
|
|
|
+ })
|
|
|
|
+ },
|
|
}
|
|
}
|
|
}
|
|
}
|
|
</script>
|
|
</script>
|
|
|
|
|
|
<style scoped>
|
|
<style scoped>
|
|
-
|
|
|
|
-</style>
|
|
|
|
|
|
+</style>
|