Files
dvcp_v2_webapp/packages/device/AppMonitor/AppMonitorMap.vue
2022-08-22 11:16:34 +08:00

212 lines
4.9 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>
<section class="AppMonitorMap">
<device-slider :show.sync="slider" :ins="instance" :dict="dict" @list="v=>list=v" @select="markerClickEvent"/>
<div id="amap"/>
<div ref="selectedInfoWin" class="selected">
<b>{{ selected.deviceName }}</b>
<div>{{ selected.lng }}{{ selected.lat }}</div>
<div v-if="selected.address">{{ selected.address }}</div>
<div btn @click="handleShowMonitor">查看监控</div>
</div>
<el-dialog class="monitorDialog" :modal="false" :visible.sync="dialog" :title="selected.deviceName||'视频监控'"
width="640px" @closed="monitor=''">
<iframe v-if="monitor" :src="monitor" allow="autoplay *; microphone *; fullscreen *" allowfullscreen
allowtransparency allowusermedia frameBorder="no"/>
</el-dialog>
</section>
</template>
<script>
import DeviceSlider from "./components/deviceSlider";
import AMapLoader from "@amap/amap-jsapi-loader";
export default {
name: "AppMonitorMap",
components: {DeviceSlider},
label: "监控地图",
props: {
instance: Function,
dict: Object,
permissions: Function
},
data() {
return {
slider: true,
AMap: null,
map: null,
selected: {},
list: [],
deviceToken: "",
dialog: false,
monitor: ""
}
},
watch: {
list: {
immediate: true,
handler(v) {
if (v.length > 0) {
this.renderDevicesOnMap()
}
}
}
},
methods: {
initMap() {
return new Promise(resolve => AMapLoader.load({
key: "b553334ba34f7ac3cd09df9bc8b539dc",
version: '2.0',
plugins: ['AMap.Marker', 'AMap.PlaceSearch'],
}).then(AMap => {
this.AMap = AMap
this.map = new this.AMap.Map('amap', {
zoom: 14,
})
resolve()
}))
},
renderDevicesOnMap() {
this.list?.map(e => {
if (this.AMap && e?.lat) {
e.marker = new this.AMap.Marker({
icon: this.$cdn + 'monitor/camera.png',
position: new this.AMap.LngLat(e.lng, e.lat)
}).on('click', () => this.markerClickEvent(e))
this.map.add(e.marker)
}
})
},
markerClickEvent(device) {
if (device?.marker) {
this.map?.setCenter(new this.AMap.LngLat(device.lng, device.lat))
device.marker.setIcon(this.$cdn + 'monitor/cameraSelected.png')
this.selected = device
let win = new this.AMap.InfoWindow({
isCustom: true,
autoMove: true,
closeWhenClickMap: true,
content: this.$refs.selectedInfoWin
}).on('close', () => {
device.marker.setIcon(this.$cdn + 'monitor/camera.png')
this.selected = {}
})
win.open(this.map, new this.AMap.LngLat(device.lng, device.lat))
}
},
getDeviceToken() {
this.instance.post("/app/appzyvideoequipment/getAppUserToken").then(res => {
if (res?.data) {
this.deviceToken = res.data
}
})
},
handleShowMonitor() {
this.dialog = true
this.instance.post("/app/appzyvideoequipment/getWebSdkUrl", null, {
params: {token: this.deviceToken, deviceId: this.selected.deviceId}
}).then(res => {
if (res?.data) {
let data = JSON.parse(res.data)
this.monitor = data.url
}
})
}
},
created() {
this.initMap().then(() => setTimeout(() => this.renderDevicesOnMap(), 1000))
}
}
</script>
<style lang="scss" scoped>
.AppMonitorMap {
background: #202330;
position: relative;
.deviceSlider {
position: absolute;
left: 0;
top: 0;
bottom: 0;
z-index: 66;
}
#amap {
width: 100%;
height: 100%;
}
.selected {
background: #fff;
min-width: 280px;
box-sizing: border-box;
box-shadow: 0 0 4px 0 rgba(0, 0, 0, 0.1);
padding: 12px;
color: #999;
font-size: 12px;
b {
color: #333;
font-size: 16px;
}
& > * + * {
margin-top: 4px;
}
div[btn] {
cursor: pointer;
color: #89b;
font-size: 14px;
}
}
::v-deep .monitorDialog {
.el-dialog__header {
font-size: 14px;
color: #FFF;
height: 40px;
padding: 0 16px;
background: linear-gradient(180deg, #313B5B 0%, #1B202F 100%);
display: flex;
align-items: center;
width: 100%;
box-sizing: border-box;
span {
color: #fff;
flex: 1;
min-width: 0;
}
.el-dialog__headerbtn {
position: relative;
top: unset;
right: unset;
}
}
.el-dialog__body {
padding: 0;
height: 360px;
}
iframe {
width: 100%;
height: 100%;
}
}
::v-deep .amap-logo, ::v-deep .amap-copyright {
display: none !important;
}
::v-deep .amap-marker-label {
border-color: transparent;
box-shadow: 1px 1px 0 0 rgba(#999, .2);
}
}
</style>