|
|
@@ -0,0 +1,317 @@
|
|
|
+<template>
|
|
|
+ <div class="hotspot-page detail-popup">
|
|
|
+ <template v-if="curList.length">
|
|
|
+ <el-image
|
|
|
+ v-if="myType === 'img'"
|
|
|
+ fit="contain"
|
|
|
+ :src="curList[0]"
|
|
|
+ :preview-src-list="curList"
|
|
|
+ />
|
|
|
+
|
|
|
+ <video v-else-if="myType === 'video'" ref="videos" controls :src="curList[0].url" />
|
|
|
+ </template>
|
|
|
+
|
|
|
+ <el-scrollbar class="detail-popup-container">
|
|
|
+ <h3>{{ myTitle }}</h3>
|
|
|
+ <div v-html="myTxt" />
|
|
|
+ </el-scrollbar>
|
|
|
+
|
|
|
+ <!-- 音频播放器 -->
|
|
|
+ <audio
|
|
|
+ id="myAudio"
|
|
|
+ v-if="audio"
|
|
|
+ ref="volumeRef"
|
|
|
+ v-show="isOneAduio"
|
|
|
+ :src="audio"
|
|
|
+ controls
|
|
|
+ ></audio>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script>
|
|
|
+ import { Swiper, SwiperSlide } from 'swiper/vue';
|
|
|
+ import { Navigation, Pagination } from 'swiper/modules';
|
|
|
+ import 'swiper/css';
|
|
|
+ import 'swiper/css/navigation';
|
|
|
+ import 'swiper/css/pagination';
|
|
|
+
|
|
|
+ import { parseUrlParams, judgeIsMobile } from '@/utils';
|
|
|
+ import { MESSAGE_KEY } from '@/types';
|
|
|
+
|
|
|
+ import ModelIcon from '@hotspot/assets/images/model-icon.png';
|
|
|
+ import ImageIcon from '@hotspot/assets/images/img-icon.png';
|
|
|
+ import VideoIcon from '@hotspot/assets/images/video-icon.png';
|
|
|
+ import VolumeOn from '@hotspot/assets/images/audio-icon.png';
|
|
|
+ import infoIcon from '@hotspot/assets/images/info-icon.png';
|
|
|
+
|
|
|
+ const urlParams = parseUrlParams(window.location.href);
|
|
|
+ const isMobile = judgeIsMobile();
|
|
|
+
|
|
|
+ export default {
|
|
|
+ name: 'hotspot',
|
|
|
+ components: {
|
|
|
+ Swiper,
|
|
|
+ SwiperSlide,
|
|
|
+ },
|
|
|
+ data() {
|
|
|
+ return {
|
|
|
+ isMobile,
|
|
|
+ VolumeOn,
|
|
|
+ m: urlParams.m,
|
|
|
+ id: urlParams.id,
|
|
|
+ // 音频地址
|
|
|
+ audio: '',
|
|
|
+ // 如果只有单独的音频
|
|
|
+ isOneAduio: false,
|
|
|
+ // 音频状态
|
|
|
+ audioSta: false,
|
|
|
+ swiperInited: false,
|
|
|
+
|
|
|
+ data: {
|
|
|
+ // 模型数组
|
|
|
+ model: [],
|
|
|
+ // 视频数组
|
|
|
+ video: [],
|
|
|
+ // 图片数组
|
|
|
+ img: [],
|
|
|
+ },
|
|
|
+ // 当前 type
|
|
|
+ myType: '',
|
|
|
+
|
|
|
+ // 当前索引
|
|
|
+ myInd: 0,
|
|
|
+
|
|
|
+ // 底部的tab
|
|
|
+ flooTab: [],
|
|
|
+
|
|
|
+ // 标题
|
|
|
+ myTitle: '',
|
|
|
+ // 内容
|
|
|
+ myTxt: '',
|
|
|
+ // 视频内容
|
|
|
+ videoTxt: [],
|
|
|
+ imgTxt: [],
|
|
|
+
|
|
|
+ // 只有标题和文字(没有视频,没有模型,没有图片)
|
|
|
+ oneTxt: false,
|
|
|
+
|
|
|
+ modules: [Navigation, Pagination],
|
|
|
+ };
|
|
|
+ },
|
|
|
+ computed: {
|
|
|
+ curList() {
|
|
|
+ return this.data[this.myType] || [];
|
|
|
+ },
|
|
|
+ isTextType() {
|
|
|
+ return this.myType === 'text';
|
|
|
+ },
|
|
|
+ },
|
|
|
+ watch: {
|
|
|
+ audioSta(val) {
|
|
|
+ if (!this.$refs.volumeRef) return;
|
|
|
+ if (val) {
|
|
|
+ this.$refs.volumeRef.play();
|
|
|
+ this.$refs.volumeRef.onended = () => {
|
|
|
+ // console.log("----音频播放完毕");
|
|
|
+ this.audioSta = false;
|
|
|
+ };
|
|
|
+ } else this.$refs.volumeRef.pause();
|
|
|
+ },
|
|
|
+ },
|
|
|
+ mounted() {
|
|
|
+ this.getData();
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ async getData() {
|
|
|
+ // https://www.4dmodel.com/
|
|
|
+ let url = `${
|
|
|
+ Boolean(Number(import.meta.env.VITE_APP_OFFLINE)) ? '.' : 'https://super.4dage.com'
|
|
|
+ }/data/${this.id}/hot/js/data.js?time=${Math.random()}`;
|
|
|
+ let result = await fetch(url).then((response) => response.json());
|
|
|
+ const resData = result[this.m];
|
|
|
+
|
|
|
+ if (resData) {
|
|
|
+ this.audio = resData.backgroundMusic;
|
|
|
+ // 只有单独的音频上传
|
|
|
+ if (resData.backgroundMusic && !resData.model && !resData.video && !resData.images) {
|
|
|
+ this.isOneAduio = true;
|
|
|
+ }
|
|
|
+ // 底部的tab
|
|
|
+ const arr = [];
|
|
|
+ const obj = {};
|
|
|
+ if (resData.images) {
|
|
|
+ obj.img = resData.images;
|
|
|
+ arr.push({ id: 3, type: 'img', name: '图片', icon: ImageIcon });
|
|
|
+ }
|
|
|
+ if (resData.video) {
|
|
|
+ obj.video = resData.video;
|
|
|
+ arr.push({ id: 2, type: 'video', name: '视频', icon: VideoIcon });
|
|
|
+ } else {
|
|
|
+ this.$nextTick(() => {
|
|
|
+ if (
|
|
|
+ !window.navigator.userAgent.match(
|
|
|
+ /(phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone)/i
|
|
|
+ )
|
|
|
+ ) {
|
|
|
+ this.audioSta = true;
|
|
|
+ this.$refs.volumeRef?.play();
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+ if (resData.model) {
|
|
|
+ obj.model = resData.model;
|
|
|
+ arr.push({ id: 1, type: 'model', name: '模型', icon: ModelIcon });
|
|
|
+ }
|
|
|
+ if (isMobile) {
|
|
|
+ arr.push({ id: 4, type: 'text', name: '介绍', icon: infoIcon });
|
|
|
+ }
|
|
|
+
|
|
|
+ this.flooTab = arr;
|
|
|
+ this.data = obj;
|
|
|
+
|
|
|
+ // 当前type的值 应该为
|
|
|
+ if (resData.images) this.myType = 'img';
|
|
|
+ else if (resData.model) this.myType = 'model';
|
|
|
+ else if (resData.video) {
|
|
|
+ this.myType = 'video';
|
|
|
+ this.$nextTick(() => {
|
|
|
+ this.handleVideoPlay(this.data.video[0].url);
|
|
|
+ });
|
|
|
+ } else this.myType = 'text';
|
|
|
+
|
|
|
+ this.myTitle = resData.title || '';
|
|
|
+ this.myTxt = resData.content || '';
|
|
|
+ this.videoTxt = resData.videosDesc || [];
|
|
|
+ this.imgTxt = resData.imagesDesc || [];
|
|
|
+
|
|
|
+ // 只有 标题和 文字介绍(没有视频,没有模型,没有图片)
|
|
|
+ if (!obj.model && !obj.video && !obj.img && !resData.backgroundMusic) {
|
|
|
+ this.oneTxt = true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+ handleTab(item) {
|
|
|
+ this.myInd = 0;
|
|
|
+ this.myType = item.type;
|
|
|
+ this.swiper?.slideTo(0);
|
|
|
+
|
|
|
+ switch (this.myType) {
|
|
|
+ case 'video':
|
|
|
+ this.$nextTick(() => {
|
|
|
+ this.handleVideoPlay(this.data.video[0].url);
|
|
|
+ });
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+ initSwiper(swiper) {
|
|
|
+ this.swiper = swiper;
|
|
|
+ this.swiperInited = true;
|
|
|
+ },
|
|
|
+ handleChange({ activeIndex }) {
|
|
|
+ this.myInd = activeIndex;
|
|
|
+
|
|
|
+ switch (this.myType) {
|
|
|
+ case 'video':
|
|
|
+ this.handleVideoPlay(this.data.video[activeIndex].url);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ },
|
|
|
+ handleVideoPlay(url) {
|
|
|
+ const video = this.$refs.videos?.find((i) => i.src === url);
|
|
|
+
|
|
|
+ this.lastVideo?.pause();
|
|
|
+ if (!video) return;
|
|
|
+
|
|
|
+ video.play();
|
|
|
+ this.lastVideo = video;
|
|
|
+ },
|
|
|
+ handlePreview(idx) {
|
|
|
+ window.parent.postMessage(
|
|
|
+ { type: MESSAGE_KEY.SHOW_VIEWER, images: [this.curList[idx]] },
|
|
|
+ '*'
|
|
|
+ );
|
|
|
+ },
|
|
|
+ },
|
|
|
+ };
|
|
|
+</script>
|
|
|
+
|
|
|
+<style lang="scss">
|
|
|
+ @use '@/assets/utils.scss';
|
|
|
+
|
|
|
+ .detail-popup {
|
|
|
+ height: 100%;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ gap: utils.vw-calc(200);
|
|
|
+
|
|
|
+ .el-image,
|
|
|
+ video {
|
|
|
+ max-width: utils.vw-calc(800);
|
|
|
+ height: utils.vh-calc(620);
|
|
|
+ background: black;
|
|
|
+ }
|
|
|
+ &-container {
|
|
|
+ flex-shrink: 0;
|
|
|
+ width: utils.vw-calc(638);
|
|
|
+ height: auto;
|
|
|
+ color: #e0b387;
|
|
|
+
|
|
|
+ h3 {
|
|
|
+ position: relative;
|
|
|
+ margin-bottom: utils.vh-calc(55);
|
|
|
+ font-size: utils.vh-calc(30);
|
|
|
+ line-height: utils.vh-calc(40);
|
|
|
+ text-align: center;
|
|
|
+
|
|
|
+ &::after {
|
|
|
+ content: '';
|
|
|
+ position: absolute;
|
|
|
+ bottom: utils.vh-calc(-22);
|
|
|
+ left: 50%;
|
|
|
+ transform: translateX(-50%);
|
|
|
+ width: utils.vw-calc(304);
|
|
|
+ height: utils.vw-calc(10);
|
|
|
+ background: url('@hotspot/assets/images/bd.png') no-repeat center / contain;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ > div {
|
|
|
+ font-size: utils.vh-calc(18);
|
|
|
+ line-height: utils.vh-calc(30);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @media only screen and (max-width: 600px) {
|
|
|
+ .detail-popup {
|
|
|
+ flex-direction: column;
|
|
|
+ gap: utils.vh-calc(60);
|
|
|
+
|
|
|
+ .el-image,
|
|
|
+ video {
|
|
|
+ margin-top: utils.vh-calc(120);
|
|
|
+ padding: 0 utils.vw-calc(45);
|
|
|
+ max-width: 100%;
|
|
|
+ width: 100%;
|
|
|
+ height: utils.vh-calc(674);
|
|
|
+ }
|
|
|
+ &-container {
|
|
|
+ flex: 1;
|
|
|
+ height: 0;
|
|
|
+ width: 100%;
|
|
|
+ padding: 0 utils.vw-calc(45) utils.vh-calc(158);
|
|
|
+
|
|
|
+ h3 {
|
|
|
+ font-size: utils.vh-calc(36);
|
|
|
+ line-height: utils.vh-calc(48);
|
|
|
+ }
|
|
|
+ > div {
|
|
|
+ font-size: utils.vh-calc(28);
|
|
|
+ line-height: utils.vh-calc(42);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+</style>
|