hookehuyr

垂直标题点击弹框样式调整

......@@ -10,7 +10,11 @@ export {}
declare module '@vue/runtime-core' {
export interface GlobalComponents {
AudioBackground: typeof import('./src/components/audioBackground.vue')['default']
copy: typeof import('./src/components/InfoWindowWarn copy.vue')['default']
Floor: typeof import('./src/components/Floor/index.vue')['default']
InfoPopup: typeof import('./src/components/InfoPopup.vue')['default']
InfoPopupLite: typeof import('./src/components/InfoPopupLite.vue')['default']
InfoPopupWarn: typeof import('./src/components/InfoPopupWarn.vue')['default']
InfoWindow: typeof import('./src/components/InfoWindow.vue')['default']
InfoWindowLite: typeof import('./src/components/InfoWindowLite.vue')['default']
InfoWindowWarn: typeof import('./src/components/InfoWindowWarn.vue')['default']
......
<template>
<div style="position: relative;">
<!-- <div class="info-window-wrapper">
<div :style="{ width: (widow_info.width * 0.8) + 'px', overflow: 'auto' }">
<div class="hideScrollBar info-window-title">
<div v-for="(item, index) in info?.details" :key="index" @click="handleTitle(index)"
:class="[isActive === index ? 'checked' : '', 'item']">
<span>{{ item.name }}</span>
</div>
</div>
<div v-for="(item, index) in info?.details" :key="index">
<div v-if="isActive === index" :class=" [item.audio ? 'info-text-audio' : 'info-text', 'van-multi-ellipsis--l3'] ">{{ item.note }}</div>
<div v-if="isActive === index && item.audio" class="info-control">
<div v-if="!is_play" @click="play()" class="control-play">
<van-icon name="https://cdn.ipadbiz.cn/xys/map/%E6%92%AD%E6%94%BE%E6%9A%82%E5%81%9C@2x.png" size="3rem"
color="#FFF" style="margin-top: 0.5rem;" />
</div>
<div v-else @click="pause()" class="control-play" style="text-align: center;">
<van-icon name="https://cdn.ipadbiz.cn/xys/map/%E6%92%AD%E6%94%BE@2x.png" size="3rem" color="#FFF"
style="margin-top: 0.5rem;" />
</div>
<div>{{ play_time }}</div>
</div>
</div>
</div>
<div class="van-hairline--top" style="margin: 1rem 0;">
<div @click="goToUrl()" style="width: 50%; float: left; text-align: center; margin-top: 0.75rem;"
class="van-hairline--right">
<van-icon name="https://cdn.ipadbiz.cn/xys/map/%E8%AF%A6%E6%83%85@2x.png" size="1.25rem" color="#FFF"
style="vertical-align: sub;" />&nbsp;
<span style="color: #AB8F57; font-size: 1rem;">详情</span>
</div>
<div @click="goToLocation()" style="width: 50%; float: left; text-align: center; margin-top: 0.75rem;">
<van-icon name="https://cdn.ipadbiz.cn/xys/map/%E5%89%8D%E5%BE%80@2x.png" size="1.25rem" color="#FFF"
style="vertical-align: sub;" />&nbsp;
<span style="color: #AB8F57; font-size: 1rem;">前往</span>
</div>
</div>
</div>
<div class="leaflet-popup-tip-container" style="left: 50%; position: relative;">
<div class="leaflet-popup-tip"></div>
</div> -->
<van-popup teleport="body" v-model:show="show_popup" position="bottom" :overlay="true" :close-on-click-overlay="false"
:style="{ padding: '1rem', height: '50%' }">
<van-icon name="cross" size="1.35rem" @click="onClose" style="float: right; color: gray;" />
<div class="popup-wrapper">
<div class="info-window-wrapper1">
<div :style="{ width: (widow_info.width * 0.8) + 'px', overflow: 'auto' }">
<div class="hideScrollBar info-window-title">
<div v-for="(item, index) in info?.details" :key="index" @click="handleTitle(index)"
:class="[isActive === index ? 'checked' : '', 'item']">
<span>{{ item.name }}</span>
</div>
</div>
<div v-for="(item, index) in info?.details" :key="index">
<div v-if="isActive === index" :class=" [item.audio ? 'info-text-audio' : 'info-text', 'van-multi-ellipsis--l3'] ">{{ item.note }}</div>
<div v-if="isActive === index && item.audio" class="info-control">
<div v-if="!is_play" @click="play()" class="control-play">
<van-icon name="https://cdn.ipadbiz.cn/xys/map/%E6%92%AD%E6%94%BE%E6%9A%82%E5%81%9C@2x.png" size="3rem"
color="#FFF" style="margin-top: 0.5rem;" />
</div>
<div v-else @click="pause()" class="control-play" style="text-align: center;">
<van-icon name="https://cdn.ipadbiz.cn/xys/map/%E6%92%AD%E6%94%BE@2x.png" size="3rem" color="#FFF"
style="margin-top: 0.5rem;" />
</div>
<div>{{ play_time }}</div>
</div>
</div>
</div>
<!-- <div class="van-hairline--top" style="margin: 1rem 0;">
<div @click="goToUrl()" style="width: 50%; float: left; text-align: center; margin-top: 0.75rem;"
class="van-hairline--right">
<van-icon name="https://cdn.ipadbiz.cn/xys/map/%E8%AF%A6%E6%83%85@2x.png" size="1.25rem" color="#FFF"
style="vertical-align: sub;" />&nbsp;
<span style="color: #AB8F57; font-size: 1rem;">详情</span>
</div>
<div @click="goToLocation()" style="width: 50%; float: left; text-align: center; margin-top: 0.75rem;">
<van-icon name="https://cdn.ipadbiz.cn/xys/map/%E5%89%8D%E5%BE%80@2x.png" size="1.25rem" color="#FFF"
style="vertical-align: sub;" />&nbsp;
<span style="color: #AB8F57; font-size: 1rem;">前往</span>
</div>
</div> -->
</div>
<div class="van-hairline--top" style="margin: 1rem 0; position: absolute; bottom: 0; display: flex; width: 90%; justify-content: space-around;">
<div @click="goToUrl()" style="text-align: center; margin-top: 0.75rem;"
>
<van-icon name="https://cdn.ipadbiz.cn/xys/map/%E8%AF%A6%E6%83%85@2x.png" size="1.25rem" color="#FFF"
style="vertical-align: sub;" />&nbsp;
<span style="color: #AB8F57; font-size: 1rem;">详情</span>
</div>
<div class="van-hairline--right"></div>
<div @click="goToLocation()" style="text-align: center; margin-top: 0.75rem;">
<van-icon name="https://cdn.ipadbiz.cn/xys/map/%E5%89%8D%E5%BE%80@2x.png" size="1.25rem" color="#FFF"
style="vertical-align: sub;" />&nbsp;
<span style="color: #AB8F57; font-size: 1rem;">前往</span>
</div>
</div>
</div>
</van-popup>
</div>
</template>
<script>
import $ from 'jquery'
import { mapState, mapActions } from 'pinia'
import { mainStore } from '@/store'
export default {
props: {
infoWindow: {
type: Object,
default: () => { }
},
info: {
type: Object,
default: () => { }
},
rect: {
type: Object,
default: () => { }
},
show: {
type: Boolean,
default: false
}
},
mounted() {
},
computed: {
...mapState(mainStore, ['audio_entity', 'audio_src', 'audio_status'])
},
watch: {
show(val) {
this.show_popup = val;
},
rect(val) {
this.widow_info = val;
},
infoWindow(val) {
if (val) {
if (this.info?.details.length && this.info?.details[this.isActive]['audio']) { // 实体有音频时
// 存放到pinia里面控制
this.changeAudio(this.audio);
this.changeAudioStatus('pause');
// 加载录音
this.play_time = this.info?.details[this.isActive]['audio_time']
}
}
},
audio_status (v) {
if (v === 'pause') {
this.voice_pause()
}
}
},
data() {
return {
show_popup: false,
popup_title: '',
popup_content: '',
video_src: '',
ind: '',
is_play: false,
audio: new Audio(),
widow_info: {},
play_time: '00:00',
isActive: 0,
nav_scroll: false,
play_timer: null,
}
},
methods: {
...mapActions(mainStore, ['changeAudio', 'changeAudioSrc', 'changeAudioStatus']),
getAudioTime(audio) {
let time = Math.floor(audio);
var minute = time / 60;
var minutes = parseInt(minute);
if (minutes < 10) {
minutes = "0" + minutes;
}
//秒
var second = time % 60;
var seconds = Math.round(second);
if (seconds < 10) {
seconds = "0" + seconds;
}
return `${minutes}:${second}`;
},
calculateCurrentValue(currentTime) {
var current_hour = parseInt(+currentTime / 3600) % 24,
current_minute = parseInt(+currentTime / 60) % 60,
current_seconds_long = +currentTime % 60,
current_seconds = current_seconds_long.toFixed(),
current_time = (current_minute < 10 ? "0" + current_minute : current_minute) + ":" + (current_seconds < 10 ? "0" + current_seconds : current_seconds);
return current_time;
},
// 关闭
close() {
// 高德地图信息窗关闭的api
this.infoWindow.close()
// 处理音频
// TAG:临时屏蔽关闭窗口暂停音频播放测试
// this.voice_pause();
// this.audio.currentTime = 0
// 默认选中项
this.isActive = 0;
// 滚动状态
this.nav_scroll = false;
// 清空播放计时
clearInterval(this.play_timer)
},
showDetail() {
this.show_popup = true;
this.popup_title = '三宝楼';
this.popup_content = '尊敬的游客朋友们您好,欢迎来到西园寺,您现在所到的地方是“三宝楼......';
this.video_src = 'https://video.pearvideo.com/mp4/short/20200209/cont-1650197-14888002-hd.mp4'
},
play() {
this.voice_play(this.info.details[this.isActive]['audio'], 0)
this.changeAudioSrc(this.audio.src);
this.changeAudioStatus('play');
this.$emit('onPlay', this.info.name)
},
pause() {
this.voice_pause();
this.changeAudioStatus('pause');
this.$emit('onPause', this.info.name)
},
// 声音播放
voice_play(src, index) {
this.audio.src = src
if (this.ind) {
this.audio.currentTime = 0
this.ind = 0
return
}
this.ind = index
let play_status = this.audio.play() // 播放
if (play_status) {
this.is_play = true;
play_status.then(() => {
// 音频加载成功
setTimeout(() => { // 后续操作(同为播放完成)
this.ind = 0
}, this.audio.duration * 1000) // audio.duration 为音频的时长单位为秒
this.play_timer = setInterval(() => {
let timer = this.audio.duration - this.audio.currentTime;
if (isNaN(timer)) {
timer = 0
}
this.play_time = this.calculateCurrentValue(timer);
// 音频播放完毕
if (this.play_time === '00:00') {
clearInterval(this.play_timer);
this.is_play = false;
}
}, 1000);
}).catch((e) => {
// 失败
console.log('Operation is too fast, audio play fails')
})
}
},
voice_pause() {
this.audio.pause();
this.is_play = false;
this.changeAudioStatus('pause');
clearInterval(this.play_timer);
},
goToUrl(url) {
location.href = this.info.details[this.isActive].url;
},
handleTitle (index) {
this.isActive = index;
this.voice_pause()
// // 标题滚动
// if (index === 2 && this.info.details.length > 3) {
// this.handleNavScroll()
// }
clearInterval(this.play_timer)
this.play_time = this.info.details[this.isActive].audio_time;
},
handleNavScroll () { // 滚动标题
this.nav_scroll = !this.nav_scroll;
if (this.nav_scroll) {
setTimeout(() => {
$('.info-window-title').animate({
scrollLeft: $('.info-window-title').outerWidth()
}, 1000);
}, 100);
} else {
setTimeout(() => {
$('.info-window-title').animate({
scrollLeft: 0
}, 1000);
}, 100);
}
},
goToLocation () {
// this.$emit('onLocation', this.info.position)
this.$emit('onLocation', this.info.position)
},
onClose () {
this.$emit('onClose')
}
}
}
</script>
<style lang="less">
.info-window-wrapper1 {
background: #fff;
color: #333;
// -webkit-box-shadow: 0 3px 14px rgba(0, 0, 0, 0.4);
// box-shadow: 0 3px 14px rgba(0, 0, 0, 0.4);
// text-align: left;
// border-radius: 5px;
// padding: 1rem 1.25rem;
overflow: auto;
.info-text {
// width: 100%;
line-height: 1.5;
float: left;
color: #7A6C6C;
font-size: 0.9rem;
margin-top: 0.5rem;
}
.info-text-audio {
width: 80%;
line-height: 1.5;
float: left;
color: #7A6C6C;
font-size: 0.9rem;
margin-top: 0.5rem;
}
.info-control {
width: 20%;
float: left;
text-align: center;
color: #AB8F57;
.control-play {
text-align: center;
margin-bottom: 0.5rem;
i {
margin-top: 0 !important;
}
}
}
// .t-popup-content {
// position: relative;
// width: 25rem;
// padding: 0;
// margin: 0;
// border-radius: 0.1rem;
// background: rgba(255, 255, 255, 0.9);
// -webkit-box-shadow: 0 0.02rem 0.05rem 0 rgba(0, 0, 0, 0.1);
// box-shadow: 0 0.02rem 0.05rem 0 rgba(0, 0, 0, 0.1);
// line-height: 1.4;
// .view-name {
// margin: 0;
// padding: 0.5rem;
// width: 25rem;
// height: 2.5rem;
// font-size: 1.2rem;
// text-indent: 0.2rem;
// white-space: nowrap;
// text-overflow: ellipsis;
// color: #5b5b5b;
// -webkit-box-sizing: border-box;
// box-sizing: border-box;
// border-bottom: solid 1px #e8e8e8;
// border-radius: 0.1rem 0.1rem 0 0;
// background: #f7f7f7;
// overflow: hidden;
// }
// .view-photo {
// display: block;
// float: left;
// margin: 0.5rem;
// height: 100%;
// width: 9rem;
// height: 9rem;
// border-radius: 3px;
// }
// .introduction {
// float: left;
// margin: 0.2rem 0;
// width: 13.5rem;
// height: 6.75rem;
// font-size: 0.9rem;
// color: #202020;
// overflow: hidden;
// }
// // .control-play {
// // display: block;
// // float: left;
// // margin-right: 0.5rem;
// // width: 7rem;
// // height: 3rem;
// // border-radius: 2px;
// // background: #ffdd02 center no-repeat;
// // background-size: 6.5rem 3rem;
// // }
// .show-details {
// display: block;
// float: left;
// width: 7rem;
// height: 3rem;
// border-radius: 2px;
// background: #9196a9 center no-repeat;
// background-size: 6.5rem 3rem;
// }
// }
.info-window-title {
display: flex;
overflow-x: scroll;
overflow-y: hidden;
-webkit-overflow-scrolling: touch;
position: relative;
text-align: left;
.item {
width: 30%;
flex-shrink: 0;
color: #888;
font-size: 1.1rem;
margin-bottom: 0.75rem;
display: inline-block;
}
.checked {
color: #AB8F57;
span {
border-bottom: 1.5px solid #AB8F57; padding-bottom: 3px;
}
}
}
}
.leaflet-popup-tip-container { // 信息框箭头样式
margin-top: -1px;
width: 2rem;
height: 2rem;
margin-left: -10px;
overflow: hidden;
pointer-events: none;
}
.leaflet-popup-tip {
width: 1rem;
height: 1rem;
-webkit-transform: rotate(0);
transform: rotate(0);
background: transparent url(https://map.365daoyou.cn/web/images/info-sharp.png) center no-repeat;
background-size: 1rem 1rem;
box-shadow: none;
}
</style>
<template>
<div style="position: relative;">
<!-- <div class="info-window-lite-wrapper">
<div :style="{ width: (widow_info.width * 0.8) + 'px', overflow: 'auto' }">
<div class="hideScrollBar info-window-title">
<div class="checked">
<span>{{ info.name }}</span>
</div>
</div>
<div v-if="info?.details?.length > 3" @click="handleNavScroll()" style="position: fixed; right: 0.75rem; width: 1rem; background-color: #FFF;top: 1.5rem;">
<van-icon v-if="!nav_scroll" name="arrow" color="#888" size="1.25rem" style="vertical-align: sub;" />
<van-icon v-else name="arrow-left" color="#888" size="1.25rem" style="vertical-align: sub;" />
</div>
</div>
<div class="van-hairline--top" style="margin: 1rem 0;">
<div @click="goToLocation()" style="width: 100%; float: left; text-align: center; margin-top: 1rem;">
<van-icon name="https://cdn.ipadbiz.cn/xys/map/%E5%89%8D%E5%BE%80@2x.png" size="1.25rem" color="#FFF"
style="vertical-align: bottom;" />&nbsp;
<span style="color: #AB8F57; font-size: 1rem;">前往</span>
</div>
</div>
</div>
<div class="leaflet-popup-tip-container" style="left: 50%; position: relative;">
<div class="leaflet-popup-tip"></div>
</div> -->
<van-popup teleport="body" v-model:show="show_popup" position="bottom" :overlay="true" :close-on-click-overlay="false"
:style="{ padding: '1rem', height: '50%' }">
<van-icon name="cross" size="1.35rem" @click="show_popup = false" style="float: right; color: gray;" />
<div class="popup-wrapper">
<div class="info-window-lite-wrapper1">
<div :style="{ width: (widow_info.width * 0.8) + 'px', overflow: 'auto' }">
<div class="hideScrollBar info-window-title">
<div class="checked">
<span>{{ info.name }}</span>
</div>
</div>
<div v-if="info?.details?.length > 3" @click="handleNavScroll()" style="position: fixed; right: 0.75rem; width: 1rem; background-color: #FFF;top: 1.5rem;">
<van-icon v-if="!nav_scroll" name="arrow" color="#888" size="1.25rem" style="vertical-align: sub;" />
<van-icon v-else name="arrow-left" color="#888" size="1.25rem" style="vertical-align: sub;" />
</div>
</div>
<div class="van-hairline--top" style="margin: 1rem 0;">
<div @click="goToLocation()" style="width: 100%; float: left; text-align: center; margin-top: 1rem;">
<van-icon name="https://cdn.ipadbiz.cn/xys/map/%E5%89%8D%E5%BE%80@2x.png" size="1.25rem" color="#FFF"
style="vertical-align: bottom;" />&nbsp;
<span style="color: #AB8F57; font-size: 1rem;">前往</span>
</div>
</div>
</div>
</div>
</van-popup>
</div>
</template>
<script>
import $ from 'jquery'
export default {
props: {
infoWindow: {
type: Object,
default: () => { }
},
info: {
type: Object,
default: () => { }
},
rect: {
type: Object,
default: () => { }
},
show: {
type: Boolean,
default: false
}
},
mounted() {
},
watch: {
show(val) {
this.show_popup = val;
},
rect(val) {
this.widow_info = val;
},
},
data() {
return {
show_popup: false,
popup_title: '',
popup_content: '',
video_src: '',
ind: '',
is_play: false,
audio: new Audio(),
widow_info: {},
play_time: '00:00',
isActive: 0,
nav_scroll: false,
}
},
methods: {
// 关闭
close() {
// 高德地图信息窗关闭的api
this.infoWindow.close()
},
showDetail() {
this.show_popup = true;
this.popup_title = '三宝楼';
this.popup_content = '尊敬的游客朋友们您好,欢迎来到西园寺,您现在所到的地方是“三宝楼......';
this.video_src = 'https://video.pearvideo.com/mp4/short/20200209/cont-1650197-14888002-hd.mp4'
},
goTo(url) {
location.href = this.info.details[this.isActive].url;
},
goToLocation() {
// this.$emit('onLocation', this.info.position)
this.$emit('onLocation', this.info.position)
},
onClose () {
this.$emit('onClose')
}
}
}
</script>
<style lang="less">
.info-window-lite-wrapper1 {
background: #fff;
color: #333;
// -webkit-box-shadow: 0 3px 14px rgba(0, 0, 0, 0.4);
// box-shadow: 0 3px 14px rgba(0, 0, 0, 0.4);
// text-align: left;
// border-radius: 5px;
// padding: 1rem 1.25rem;
overflow: auto;
.info-text {
// width: 100%;
line-height: 1.5;
float: left;
color: #7A6C6C;
font-size: 0.9rem;
margin-top: 0.5rem;
}
.info-text-audio {
width: 80%;
line-height: 1.5;
float: left;
color: #7A6C6C;
}
.info-control {
width: 20%;
float: left;
text-align: center;
color: #AB8F57;
.control-play {
text-align: center;
margin-bottom: 0.5rem;
i {
margin-top: 0 !important;
}
}
}
// .t-popup-content {
// position: relative;
// width: 25rem;
// padding: 0;
// margin: 0;
// border-radius: 0.1rem;
// background: rgba(255, 255, 255, 0.9);
// -webkit-box-shadow: 0 0.02rem 0.05rem 0 rgba(0, 0, 0, 0.1);
// box-shadow: 0 0.02rem 0.05rem 0 rgba(0, 0, 0, 0.1);
// line-height: 1.4;
// .view-name {
// margin: 0;
// padding: 0.5rem;
// width: 25rem;
// height: 2.5rem;
// font-size: 1.2rem;
// text-indent: 0.2rem;
// white-space: nowrap;
// text-overflow: ellipsis;
// color: #5b5b5b;
// -webkit-box-sizing: border-box;
// box-sizing: border-box;
// border-bottom: solid 1px #e8e8e8;
// border-radius: 0.1rem 0.1rem 0 0;
// background: #f7f7f7;
// overflow: hidden;
// }
// .view-photo {
// display: block;
// float: left;
// margin: 0.5rem;
// height: 100%;
// width: 9rem;
// height: 9rem;
// border-radius: 3px;
// }
// .introduction {
// float: left;
// margin: 0.2rem 0;
// width: 13.5rem;
// height: 6.75rem;
// font-size: 0.9rem;
// color: #202020;
// overflow: hidden;
// }
// // .control-play {
// // display: block;
// // float: left;
// // margin-right: 0.5rem;
// // width: 7rem;
// // height: 3rem;
// // border-radius: 2px;
// // background: #ffdd02 center no-repeat;
// // background-size: 6.5rem 3rem;
// // }
// .show-details {
// display: block;
// float: left;
// width: 7rem;
// height: 3rem;
// border-radius: 2px;
// background: #9196a9 center no-repeat;
// background-size: 6.5rem 3rem;
// }
// }
.info-window-title {
display: flex;
overflow-x: scroll;
overflow-y: hidden;
-webkit-overflow-scrolling: touch;
position: relative;
text-align: left;
.item {
width: 33.333%;
flex-shrink: 0;
color: #888;
font-size: 1.1rem;
margin-bottom: 0.75rem;
display: inline-block;
}
.checked {
color: #AB8F57;
span {
border-bottom: 1.5px solid #AB8F57; padding-bottom: 3px;
}
}
}
}
.leaflet-popup-tip-container {
margin-top: -1px;
width: 2rem;
height: 2rem;
margin-left: -10px;
overflow: hidden;
pointer-events: none;
}
.leaflet-popup-tip {
width: 1rem;
height: 1rem;
-webkit-transform: rotate(0);
transform: rotate(0);
background: transparent url(https://map.365daoyou.cn/web/images/info-sharp.png) center no-repeat;
background-size: 1rem 1rem;
box-shadow: none;
}
</style>
<template>
<div style="position: relative;">
<!--<div class="info-window-warn-wrapper">
<div :style="{ width: (widow_info.width * 0.8) + 'px', overflow: 'auto' }">
<div class="hideScrollBar info-window-title">
<!~~ <div class="checked item">
<span>{{ warn_info.name }}</span>
</div>
<div style="width: 66.66%; text-align: right; margin-bottom: 0.75rem; display: inline-block; color: #888; font-size: 0.9rem;">
<van-icon name="https://cdn.ipadbiz.cn/xys/map/%E5%BC%82%E5%B8%B8@2x.png" size="1.25rem"
color="#FFF" style="vertical-align: sub;" />&nbsp; <span>烟感异常</span>
</div> ~~>
<div v-for="(item, index) in info?.details" :key="index" @click="handleTitle(index)"
:class="[isActive === index ? 'checked' : '', 'item']">
<span>
{{ item.event_name }}
</span>
</div>
</div>
<!~~ <div v-if="info?.details?.length > 3" @click="handleNavScroll()" style="position: fixed; right: 0.75rem; width: 1rem; background-color: #FFF;top: 1rem;">
<van-icon v-if="!nav_scroll" name="arrow" color="#888" size="1.25rem" style="vertical-align: sub;" />
<van-icon v-else name="arrow-left" color="#888" size="1.25rem" style="vertical-align: sub;" />
</div> ~~>
<div>
<div style="width: 80%; float: left; color: #888; line-height: 1.75;">
<div>建筑: {{ warn_info.name }}</div>
<div>设备名称:{{ warn_info.eq_name }}</div>
<div>设备型号:{{ warn_info.eq_model }}</div>
<div>回路地址号:{{ warn_info.eq_address }}</div>
<div v-if="warn_info.type === 'fire'">类型:{{ warn_info.alert_type }}</div>
<div v-if="warn_info.type === 'water'">报警值:{{ warn_info.alarm_num }}</div>
<div v-if="warn_info.type === 'water'">设定值:{{ warn_info.set_num }}</div>
<div>报警时间:{{ warn_info.datetime }}</div>
</div>
<div v-if="warn_info.cctv_url" @click="goToWatch(warn_info.cctv_url)" class="info-control">
<div class="control-play">
<van-icon name="https://cdn.ipadbiz.cn/xys/map/%E6%92%AD%E6%94%BE%E6%9A%82%E5%81%9C@2x.png" size="3rem"
color="#FFF" style="margin-top: 0.5rem;" />
</div>
<div>监控</div>
</div>
</div>
</div>
<div class="van-hairline--top warn-button-wrapper">
<div v-if="warn_info.case_url" @click="goToCase(warn_info.case_url)"
style="text-align: center; margin-top: 1rem;">
<van-icon name="https://cdn.ipadbiz.cn/xys/map/%E9%A2%84%E6%A1%88@2x.png" size="1.25rem" color="#FFF"
style="vertical-align: bottom;" />&nbsp;
<span style="color: #AB8F57; font-size: 1rem;">预案</span>
</div>
<div v-if="warn_span1" class="van-hairline--right f-line"></div>
<div v-if="warn_info.notice_url" @click="goToList(warn_info.id)" style="text-align: center; margin-top: 1rem;">
<van-icon name="https://cdn.ipadbiz.cn/xys/map/%E9%80%9A%E7%9F%A5@2x.png" size="1.25rem" color="#FFF"
style="vertical-align: bottom;" />&nbsp;
<span style="color: #AB8F57; font-size: 1rem;">通知</span>
</div>
<div v-if="warn_span2" class="van-hairline--right f-line"></div>
<div v-if="warn_info.handle_url" @click="goToHandle(warn_info.handle_url)"
style="text-align: center; margin-top: 1rem;">
<van-icon name="https://cdn.ipadbiz.cn/xys/map/%E5%A4%84%E7%90%86@2x.png" size="1.25rem" color="#FFF"
style="vertical-align: bottom;" />&nbsp;
<span style="color: #AB8F57; font-size: 1rem;">处理</span>
</div>
</div>
</div>
<div class="leaflet-popup-tip-container" style="left: 50%; position: relative;">
<div class="leaflet-popup-tip"></div>
</div>-->
<van-popup teleport="body" v-model:show="show_popup" position="bottom" :overlay="true" :close-on-click-overlay="false"
:style="{ padding: '1rem', height: '50%' }">
<van-icon name="cross" size="1.35rem" @click="show_popup = false" style="float: right; color: gray;" />
<div class="popup-wrapper">
<div class="info-window-warn-wrapper1">
<div :style="{ width: (widow_info.width * 0.8) + 'px', overflow: 'auto' }">
<div class="hideScrollBar info-window-title">
<!-- <div class="checked item">
<span>{{ warn_info.name }}</span>
</div>
<div style="width: 66.66%; text-align: right; margin-bottom: 0.75rem; display: inline-block; color: #888; font-size: 0.9rem;">
<van-icon name="https://cdn.ipadbiz.cn/xys/map/%E5%BC%82%E5%B8%B8@2x.png" size="1.25rem"
color="#FFF" style="vertical-align: sub;" />&nbsp; <span>烟感异常</span>
</div> -->
<div v-for="(item, index) in info?.details" :key="index" @click="handleTitle(index)"
:class="[isActive === index ? 'checked' : '', 'item']">
<span>
{{ item.event_name }}
</span>
</div>
</div>
<!-- <div v-if="info?.details?.length > 3" @click="handleNavScroll()" style="position: fixed; right: 0.75rem; width: 1rem; background-color: #FFF;top: 1rem;">
<van-icon v-if="!nav_scroll" name="arrow" color="#888" size="1.25rem" style="vertical-align: sub;" />
<van-icon v-else name="arrow-left" color="#888" size="1.25rem" style="vertical-align: sub;" />
</div> -->
<div>
<div style="width: 80%; float: left; color: #888; line-height: 1.75;">
<div>建筑: {{ warn_info.name }}</div>
<div>设备名称:{{ warn_info.eq_name }}</div>
<div>设备型号:{{ warn_info.eq_model }}</div>
<div>回路地址号:{{ warn_info.eq_address }}</div>
<div v-if="warn_info.type === 'fire'">类型:{{ warn_info.alert_type }}</div>
<div v-if="warn_info.type === 'water'">报警值:{{ warn_info.alarm_num }}</div>
<div v-if="warn_info.type === 'water'">设定值:{{ warn_info.set_num }}</div>
<div>报警时间:{{ warn_info.datetime }}</div>
</div>
<div v-if="warn_info.cctv_url" @click="goToWatch(warn_info.cctv_url)" class="info-control">
<div class="control-play">
<van-icon name="https://cdn.ipadbiz.cn/xys/map/%E6%92%AD%E6%94%BE%E6%9A%82%E5%81%9C@2x.png" size="3rem"
color="#FFF" style="margin-top: 0.5rem;" />
</div>
<div>监控</div>
</div>
</div>
</div>
<div class="van-hairline--top warn-button-wrapper">
<div v-if="warn_info.case_url" @click="goToCase(warn_info.case_url)"
style="text-align: center; margin-top: 1rem;">
<van-icon name="https://cdn.ipadbiz.cn/xys/map/%E9%A2%84%E6%A1%88@2x.png" size="1.25rem" color="#FFF"
style="vertical-align: bottom;" />&nbsp;
<span style="color: #AB8F57; font-size: 1rem;">预案</span>
</div>
<div v-if="warn_span1" class="van-hairline--right f-line"></div>
<div v-if="warn_info.notice_url" @click="goToList(warn_info.id)" style="text-align: center; margin-top: 1rem;">
<van-icon name="https://cdn.ipadbiz.cn/xys/map/%E9%80%9A%E7%9F%A5@2x.png" size="1.25rem" color="#FFF"
style="vertical-align: bottom;" />&nbsp;
<span style="color: #AB8F57; font-size: 1rem;">通知</span>
</div>
<div v-if="warn_span2" class="van-hairline--right f-line"></div>
<div v-if="warn_info.handle_url" @click="goToHandle(warn_info.handle_url)"
style="text-align: center; margin-top: 1rem;">
<van-icon name="https://cdn.ipadbiz.cn/xys/map/%E5%A4%84%E7%90%86@2x.png" size="1.25rem" color="#FFF"
style="vertical-align: bottom;" />&nbsp;
<span style="color: #AB8F57; font-size: 1rem;">处理</span>
</div>
</div>
</div>
</div>
</van-popup>
</div>
</template>
<script>
import $ from 'jquery'
export default {
props: {
infoWindow: {
type: Object,
default: () => { }
},
info: {
type: Object,
default: () => { }
},
rect: {
type: Object,
default: () => { }
},
show: {
type: Boolean,
default: false
}
},
mounted() {
},
computed: {
warn_span1() {
let flag = false;
if (this.warn_info.case_url) {
if (this.warn_info.notice_url || this.warn_info.handle_url) {
flag = true
}
}
return flag;
},
warn_span2() {
let flag = false;
if (this.warn_info.notice_url) {
if (this.warn_info.handle_url) {
flag = true
}
}
return flag;
},
},
watch: {
show(val) {
this.show_popup = val;
},
rect(val) {
this.widow_info = val;
},
infoWindow(val) {
if (val) {
this.warn_info = this.info.details[0]
// // 加载录音
// this.audio.src = this.info?.details[this.isActive]['audio'];
// let play_status = this.audio.play() // 播放
// if (play_status) {
// play_status.then(() => {
// // 音频的播放需要耗时
// this.audio.pause();
// this.play_time = this.getAudioTime(this.audio.duration)
// }).catch((e) => {
// // 失败
// console.log('Operation is too fast, audio play fails')
// })
// }
}
}
},
data() {
return {
show_popup: false,
popup_title: '',
popup_content: '',
video_src: '',
ind: '',
is_play: false,
audio: new Audio(),
widow_info: {},
play_time: '00:00',
isActive: 0,
nav_scroll: false,
warn_info: {}
}
},
methods: {
getAudioTime(audio) {
let time = Math.floor(audio);
var minute = time / 60;
var minutes = parseInt(minute);
if (minutes < 10) {
minutes = "0" + minutes;
}
//秒
var second = time % 60;
var seconds = Math.round(second);
if (seconds < 10) {
seconds = "0" + seconds;
}
return `${minutes}:${second}`;
},
calculateCurrentValue(currentTime) {
var current_hour = parseInt(currentTime / 3600) % 24,
current_minute = parseInt(currentTime / 60) % 60,
current_seconds_long = currentTime % 60,
current_seconds = current_seconds_long.toFixed(),
current_time = (current_minute < 10 ? "0" + current_minute : current_minute) + ":" + (current_seconds < 10 ? "0" + current_seconds : current_seconds);
return current_time;
},
// 关闭
close() {
// 高德地图信息窗关闭的api
this.infoWindow.close()
// 处理音频
this.voice_pause();
this.audio.currentTime = 0
// 默认选中项
this.isActive = 0;
// 滚动状态
this.nav_scroll = false;
},
// showDetail() {
// this.show_popup = true;
// this.popup_title = '三宝楼';
// this.popup_content = '尊敬的游客朋友们您好,欢迎来到西园寺,您现在所到的地方是“三宝楼......';
// this.video_src = 'https://video.pearvideo.com/mp4/short/20200209/cont-1650197-14888002-hd.mp4'
// },
play() {
this.voice_play(this.info.details[this.isActive]['audio'], 0)
},
pause() {
this.voice_pause()
},
// 声音播放
voice_play(src, index) {
this.audio.src = src
if (this.ind) {
this.audio.currentTime = 0
this.ind = 0
return
}
this.ind = index
let play_status = this.audio.play() // 播放
if (play_status) {
this.is_play = true;
play_status.then(() => {
// 音频加载成功
setTimeout(() => { // 后续操作(同为播放完成)
this.ind = 0
}, this.audio.duration * 1000) // audio.duration 为音频的时长单位为秒
setInterval(() => {
let timer = this.audio.duration - this.audio.currentTime;
if (isNaN(timer)) {
timer = 0
}
this.play_time = this.calculateCurrentValue(timer)
}, 1000);
}).catch((e) => {
// 失败
console.log('Operation is too fast, audio play fails')
})
}
},
voice_pause() {
this.audio.pause();
this.is_play = false;
},
goToCase(url) {
if (url) {
location.href = url;
}
},
goToList(id) {
this.$router.push({
path: '/noticeList',
query: {
id
}
})
},
goToHandle(url) {
// if (url) {
// location.href = url;
// }
},
goToWatch(url) {
// this.show_popup = true;
if (url) {
location.href = url;
}
},
handleTitle(index) {
this.isActive = index;
this.voice_pause()
// // 标题滚动
// if (index === 2 && this.info.details.length > 3) {
// this.handleNavScroll()
// }
this.warn_info = this.info.details[index]
},
handleNavScroll() { // 滚动标题
this.nav_scroll = !this.nav_scroll;
if (this.nav_scroll) {
setTimeout(() => {
$('.info-window-title').animate({
scrollLeft: $('.info-window-title .item').outerWidth() * 3
}, 1000);
}, 100);
} else {
setTimeout(() => {
$('.info-window-title').animate({
scrollLeft: 0
}, 1000);
}, 100);
}
},
onClose () {
this.$emit('onClose')
}
}
}
</script>
<style lang="less">
.info-window-warn-wrapper {
background: #fff;
color: #333;
// -webkit-box-shadow: 0 3px 14px rgba(0, 0, 0, 0.4);
// box-shadow: 0 3px 14px rgba(0, 0, 0, 0.4);
// text-align: left;
// border-radius: 5px;
// padding: 1.5rem 1.25rem;
overflow: auto;
.info-text {
width: 100%;
line-height: 1.5;
float: left;
color: #7A6C6C;
}
.info-text-audio {
width: 80%;
line-height: 1.5;
float: left;
color: #7A6C6C;
}
.info-control {
width: 20%;
float: left;
text-align: center;
color: #AB8F57;
.control-play {
text-align: center;
margin-bottom: 0.5rem;
i {
margin-top: 0 !important;
}
}
}
// .t-popup-content {
// position: relative;
// width: 25rem;
// padding: 0;
// margin: 0;
// border-radius: 0.1rem;
// background: rgba(255, 255, 255, 0.9);
// -webkit-box-shadow: 0 0.02rem 0.05rem 0 rgba(0, 0, 0, 0.1);
// box-shadow: 0 0.02rem 0.05rem 0 rgba(0, 0, 0, 0.1);
// line-height: 1.4;
// .view-name {
// margin: 0;
// padding: 0.5rem;
// width: 25rem;
// height: 2.5rem;
// font-size: 1.2rem;
// text-indent: 0.2rem;
// white-space: nowrap;
// text-overflow: ellipsis;
// color: #5b5b5b;
// -webkit-box-sizing: border-box;
// box-sizing: border-box;
// border-bottom: solid 1px #e8e8e8;
// border-radius: 0.1rem 0.1rem 0 0;
// background: #f7f7f7;
// overflow: hidden;
// }
// .view-photo {
// display: block;
// float: left;
// margin: 0.5rem;
// height: 100%;
// width: 9rem;
// height: 9rem;
// border-radius: 3px;
// }
// .introduction {
// float: left;
// margin: 0.2rem 0;
// width: 13.5rem;
// height: 6.75rem;
// font-size: 0.9rem;
// color: #202020;
// overflow: hidden;
// }
// // .control-play {
// // display: block;
// // float: left;
// // margin-right: 0.5rem;
// // width: 7rem;
// // height: 3rem;
// // border-radius: 2px;
// // background: #ffdd02 center no-repeat;
// // background-size: 6.5rem 3rem;
// // }
// .show-details {
// display: block;
// float: left;
// width: 7rem;
// height: 3rem;
// border-radius: 2px;
// background: #9196a9 center no-repeat;
// background-size: 6.5rem 3rem;
// }
// }
.info-window-title {
display: flex;
overflow-x: scroll;
overflow-y: hidden;
-webkit-overflow-scrolling: touch;
position: relative;
text-align: left;
.item {
width: 30%;
flex-shrink: 0;
color: #888;
font-size: 1.1rem;
margin-bottom: 0.75rem;
display: inline-block;
}
.checked {
color: #AB8F57;
span {
// border-bottom: 1.5px solid #AB8F57;
padding-bottom: 3px;
}
}
}
}
.leaflet-popup-tip-container {
margin-top: -1px;
width: 2rem;
height: 2rem;
margin-left: -20px;
overflow: hidden;
pointer-events: none;
}
.leaflet-popup-tip {
width: 1rem;
height: 1rem;
-webkit-transform: rotate(0);
transform: rotate(0);
background: transparent url(https://map.365daoyou.cn/web/images/info-sharp.png) center no-repeat;
background-size: 1rem 1rem;
box-shadow: none;
}
.warn-button-wrapper {
margin-top: 1rem;
display: flex;
justify-content: space-around;
.f-line {
text-align: center;
margin-top: 1rem;
}
}
.hideScrollBar::-webkit-scrollbar {
display: none;
}
.hideScrollBar {
-ms-overflow-style: none;
overflow: -moz-scrollbars-none;
}
</style>
<!--
* @Date: 2023-05-19 14:54:27
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2024-09-10 17:37:37
* @LastEditTime: 2024-09-11 18:17:44
* @FilePath: /map-demo/src/views/index.vue
* @Description: 公众地图主体页面
-->
......@@ -70,7 +70,7 @@
关闭步行导航
</div>
<!-- <van-popup v-model:show="show_popup" position="bottom" :overlay="true" :style="{ padding: '1rem', height: '100%' }">
<!-- <van-popup v-model:show="show_popup" position="bottom" :overlay="true" teleport="body" :close-on-click-overlay="false" :style="{ padding: '1rem', height: '50%' }">
<van-icon name="cross" size="1.35rem" @click="show_popup = false" style="float: right; color: gray;" />
<div class="popup-wrapper">
<div class="title">
......@@ -97,6 +97,11 @@
:rect="rect"></InfoWindowWarn>
<audioBackground></audioBackground>
<InfoPopup :show="showInfoPopup" :info-window="infoWindow" :info="itemInfo"
@onLocation="infoWindowLocation" @onPlay="onPlay" @onPause="onPause" @onClose="onClose"></InfoPopup>
<InfoPopupLite :show="showInfoLitePopup" :info="itemInfo" @onClose="onLiteClose"></InfoPopupLite>
<InfoPopupWarn :show="showInfoWarnPopup" :info="itemInfo" @onClose="onWarnClose"></InfoPopupWarn>
</div>
</template>
......@@ -116,6 +121,9 @@ import audioBackground from '@/components/audioBackground'
import { useRect } from '@vant/use';
import { mapAPI } from '@/api/map.js'
import wx from 'weixin-js-sdk'
import InfoPopup from '@/components/InfoPopup'
import InfoPopupLite from '@/components/InfoPopupLite'
import InfoPopupWarn from '@/components/InfoPopupWarn'
const GPS = {
PI: 3.14159265358979324,
......@@ -174,7 +182,7 @@ const GPS = {
};
export default {
components: { InfoWindow, InfoWindowLite, InfoWindowWarn, audioBackground },
components: { InfoWindow, InfoWindowLite, InfoWindowWarn, audioBackground, InfoPopup, InfoPopupLite, InfoPopupWarn },
data() {
return {
map: '',
......@@ -204,7 +212,7 @@ export default {
current_lat: '',
current_route: '',
current_safe_route: [],
// show_popup: false,
show_popup: false,
dialog_show: false,
dialog_text: '',
walk_route: '',
......@@ -250,6 +258,9 @@ export default {
data_rotation: 0, // 接口获取-地图旋转角度
data_paths: {}, // 接口获取-地图导航路径
data_path_list: [], // 接口获取-地图导航路径
showInfoPopup: false,
showInfoLitePopup: false,
showInfoWarnPopup: false,
}
},
async mounted() {
......@@ -449,6 +460,22 @@ export default {
},
position: entity_info[i].position, //点标记在地图上显示的位置
});
if (clickListener) {
textMarker.off('click', clickListener)
}
// 绑定景点的点击事件 - 文字出现才能触发
var clickListener = textMarker.on('click', (e) => {
console.warn(e);
this.itemInfo = entity_info[i];
// 不同弹框类型
if (entity_info[i].window_type === 'normal') {
this.showInfoPopup = true;
} else if (entity_info[i].window_type === 'lite') {
this.showInfoLitePopup = true;
} else if (entity_info[i].window_type === 'warn') {
this.showInfoWarnPopup = true;
}
})
textMarker.setMap(this.map); //将文本标记设置到地图上
} else { // 默认方向
// 创建一个 LabelMarker 实例
......@@ -1277,6 +1304,15 @@ export default {
// this.map.add(this.spotInfo);
},
onPause(name) { },
onClose () {
this.showInfoPopup = false;
},
onLiteClose () {
this.showInfoLitePopup = false;
},
onWarnClose () {
this.showInfoWarnPopup = false;
},
}
}
</script>
......