From a3e27f5cab583debe11a9c62d8cc0115783b0791 Mon Sep 17 00:00:00 2001 From: Gary Gu <garygu@Garydebijibendiannao.local> Date: Wed, 28 May 2025 16:59:43 +0800 Subject: [PATCH] fix: 优化实况UI放大缩小 --- src/views/Home.vue | 1350 +++++++++++++++++++++++++++++++++------------------------ 1 files changed, 778 insertions(+), 572 deletions(-) diff --git a/src/views/Home.vue b/src/views/Home.vue index fc41987..5e01235 100644 --- a/src/views/Home.vue +++ b/src/views/Home.vue @@ -1,39 +1,82 @@ <template> -<div class="home-container"> - <!-- 顶部导航 --> - <div class="top-nav"> - <div class="nav-items"> - <div class="nav-item mr-[8px]" :class="{ active: currentView === 'model' }" @click="handleChange('model')">模型</div> - <div class="nav-item mr-[8px]" :class="{ active: currentView === '720' }" @click="handleChange('720')">720全景</div> - <div class="nav-item" :class="{ active: currentView === 'project' }" @click="handleChange('project')">项目实况</div> - </div> - <div class="time-info"> - <div class="time-info-item"> - <i class="el-icon-date" style="color: #FFBF00;font-size: 20px;"></i> - <div class="text-white text-[16px] ml-[4px]">工程倒计时/天</div> - <div class="text-[#FFBF00] text-[24px] font-bold ml-[28px]">{{endDate}}</div> - </div> - <div class="time-line"> - </div> - </div> - </div> - <div class="bottom-nav"> - <div class="content-wrapper mb-[20px]"> - <!-- 720菜单 --> - <div class="side-menu z-[100]" v-if="currentView === '720'"> - <el-cascader popper-class="custom-dropdown" v-model="panoValue" :options="panoList" @change="handlePanoChange" :props="{ value: 'id',label: 'label',children: 'Children'}"> - </el-cascader> - </div> - - <!-- 主要内容区域 --> - <div class="main-content" :style="isFullScreen ? fullScreenStyle : ''" v-loading="isLoading"> - <!-- 模型 / 720 --> - <div class="w-full h-full" :style="isFullScreen ? fullScreenStyle : 'width: 100%; height: 100%;'" v-if="currentView === '720' || currentView === 'model'"> - <iframe id="model-iframe" class="content-frame w-full h-full" src="" frameborder="0" :style="isFullScreen ? fullScreenModelStyle : ''" v-if="currentView === 'model'"></iframe> - <iframe ref="panoiframe" id="panoviewpreview" class="pano-frame w-full h-full" :style="isFullScreen ? fullScreenPanoStyle : ''" v-if="currentView === '720'"></iframe> + <div class="home-container"> + <!-- 顶部导航 --> + <div class="top-nav"> + <div class="nav-items"> + <div class="nav-item mr-[8px]" :class="{ active: currentView === 'model' }" @click="handleChange('model')">模型</div> + <div class="nav-item mr-[8px]" :class="{ active: currentView === '720' }" @click="handleChange('720')">720全景</div> + <div class="nav-item" :class="{ active: currentView === 'project' }" @click="handleChange('project')">项目实况</div> + </div> + <div class="time-info"> + <div class="time-info-item"> + <i class="el-icon-date" style="color: #ffbf00; font-size: 20px"></i> + <div class="text-white text-[16px] ml-[4px]">工程倒计时/天</div> + <div class="text-[#FFBF00] text-[24px] font-bold ml-[28px]">{{ endDate }}</div> + </div> + <div class="time-line"> </div> + </div> </div> - <!-- 720全景图版本选择 --> - <!--<div class="w-full h-[120px] bg-[rgba(19,40,64,0.8)] absolute bottom-0 left-0 right-0 flex items-center py-[10px]" :style="isFullScreen ? 'z-index: 100; height:' : ''" v-if="currentView === '720'"> + <div class="bottom-nav"> + <div class="content-wrapper mb-[20px]"> + <!-- 720菜单 --> + <div class="side-menu z-[100]" v-if="currentView === '720'"> + <el-cascader + popper-class="custom-dropdown" + v-model="panoValue" + :options="panoList" + @change="handlePanoChange" + :props="{ value: 'id', label: 'label', children: 'Children' }" + /> + </div> + <!-- 项目实况--> + <div class="side-menu z-[100]" v-if="currentView === 'project'"> + <el-cascader + popper-class="custom-dropdown" + v-model="liveValue" + :options="liveList" + @change="handleLiveChange" + :props="{ value: 'id', label: 'label', children: 'JSCProjectMonitorList' }" + /> + </div> + + <!-- 主要内容区域 --> + <div class="main-content" :style="isFullScreen ? fullScreenStyle : ''" v-loading="isLoading"> + <!-- 模型 / 720 --> + <div + class="w-full h-full" + :style="isFullScreen ? fullScreenStyle : 'width: 100%; height: 100%;'" + v-if="currentView === '720' || currentView === 'model'" + > + <iframe + id="model-iframe" + class="content-frame w-full h-full" + src="" + frameborder="0" + :style="isFullScreen ? fullScreenModelStyle : ''" + v-if="currentView === 'model'" + ></iframe> + <iframe + ref="panoiframe" + id="panoviewpreview" + class="pano-frame w-full h-full" + :style="isFullScreen ? fullScreenPanoStyle : ''" + v-if="currentView === '720'" + ></iframe> + </div> + <!-- 项目 --> + <div class="w-full h-full" ref="videoWrapper" v-if="currentView === 'project'"> + <video + controls + muted + controlslist="nodownload" + autoplay + class="video-box" + ref="videoElement" + :style="'width: 100%; height: 450px;background-color: #000'" + ></video> + </div> + <!-- 720全景图版本选择 --> + <!--<div class="w-full h-[120px] bg-[rgba(19,40,64,0.8)] absolute bottom-0 left-0 right-0 flex items-center py-[10px]" :style="isFullScreen ? 'z-index: 100; height:' : ''" v-if="currentView === '720'"> <div v-for="item in panoVersionList" :key="item.value" :style="isFullScreen ? 'z-index: 100;' : ''"> <div class="w-[160px] h-[100px] mr-[10px] ml-[10px] cursor-pointer border-[1px] border-[#3068A5] rounded-[2px]" @click="panoPreview(panoObj, item)"> <img :src="getItemImg(item)" alt="全景图" class="w-full h-full" /> @@ -41,568 +84,731 @@ </div> </div>--> - <!-- 放大镜 --> - <div class="w-[80px] h-[80px] bg-[#008C99] absolute top-[-40px] right-[-40px] rounded-[50%] z-[100]" v-if="currentView === 'model' || currentView === '720'" @click="handleZoomOut"> - <img src="../assets/images/backgrounds/zoomin.png" alt="放大" class="w-[16px] h-[16px] mt-[50px] ml-[15px] cursor-pointer" v-if="isFullScreen" /> - <img src="../assets/images/backgrounds/zoomout.png" alt="缩小" class="w-[16px] h-[16px] mt-[50px] ml-[15px] cursor-pointer" v-else /> - </div> + <!-- 放大镜 --> + <div + class="w-[80px] h-[80px] bg-[#008C99] absolute top-[-40px] right-[-40px] rounded-[50%] z-[100]" + v-if="currentView === 'model' || currentView === '720'" + @click="handleZoomOut" + > + <img src="../assets/images/backgrounds/zoomin.png" alt="放大" class="w-[16px] h-[16px] mt-[50px] ml-[15px] cursor-pointer" v-if="isFullScreen" /> + <img src="../assets/images/backgrounds/zoomout.png" alt="缩小" class="w-[16px] h-[16px] mt-[50px] ml-[15px] cursor-pointer" v-else /> + </div> + </div> + </div> </div> - <!-- 项目 --> - <div class="w-full h-full" v-if="currentView === 'project'"> - <iframe id="scene-iframe" frameborder='0' allowfullscreen class="scene-frame w-full h-full"></iframe> - </div> - </div> - - </div> - <div class="chart-content"> - <div class="w-full h-[4vh] mb-[1vh]" :style="{ + <div class="chart-content"> + <div + class="w-full h-[4vh] mb-[1vh]" + :style="{ backgroundImage: `url(${bottomImage})`, backgroundRepeat: 'no-repeat', backgroundPosition: 'center center', - backgroundSize: '100% 100%' - }"> - </div> - <div class="chart-container" :style="sectionStyle"> - <img src="../assets/images/backgrounds/shigongjinduchart.png" alt="施工进度" class="w-full h-full" /> - </div> + backgroundSize: '100% 100%', + }" + > + </div> + <div class="chart-container" :style="sectionStyle"> + <Gantt /> + </div> + </div> </div> - </div> - -</div> </template> <script> -import { - nextTick -} from 'vue' -import { - HomeAPI -} from "../api/home"; -import { - getProjectId, - getToken, - getProjectEndDate -} from "../utils/getToken.js"; -export default { - name: 'Home', - components: {}, - data() { - return { - currentView: 'model', - chartOptions: { - id: 'shigongjinduChart', - options: { - title: { - text: '施工进度' - } - } - }, - bottomImage: new URL('@/assets/images/titles/shigong.png', - import.meta.url).href, - isLoading: false, - panoVersionList: [], - isFullScreen: false, - fullScreenStyle: '', - fullScreenPanoStyle: '', - fullScreenModelStyle: '', - panoList: [{ - value: 'zhinan', - label: '指南', - children: [{ - value: 'shejiyuanze', - label: '设计原则' - }, { - value: 'daohang', - label: '导航' - }] - }, { - value: 'zujian', - label: '组件', - children: [{ - value: 'basic', - label: 'Basic', - }, { - value: 'form', - label: 'Form', - }, { - value: 'data', - label: 'Data', - }, { - value: 'notice', - label: 'Notice', - }, { - value: 'navigation', - label: 'Navigation', - }, { - value: 'others', - label: 'Others', - }], - }], - panoValue: [], - backgroundImage: new URL('@/assets/images/backgrounds/cover_bg.png', - import.meta.url).href, - endDate: 0, - } - }, - watch: { - projectEndDate:{ - deep: true, - handler (newVal) { - console.log('newVal', newVal) - const date = new Date(newVal); - // 获取当前日期作为Date对象 - const now = new Date(); - // 计算两个日期的差异(毫秒) - const diffTime = Math.abs(now - date); - // 将毫秒转换为天数 - const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24)); - this.endDate = diffDays - } - } - }, - computed: { - sectionStyle() { - return { - backgroundImage: `url(${this.backgroundImage})`, - backgroundRepeat: 'no-repeat', - backgroundPosition: 'center center', - backgroundSize: '100% 100%' - } - }, - projectId() { - return getProjectId() - }, - projectEndDate() { - return getProjectEndDate() - } - }, - mounted() { - setTimeout(() => { - console.log('projectEndDate', getProjectEndDate()) - this.modelShow() - }, 1000) - }, - updated() { - if (this.$refs.panoiframe) { - // IE - if (this.$refs.panoiframe.attachEvent) { - this.$refs.panoiframe.attachEvent('onload', () => { - console.log('loading') - // 加载成功 - this.isLoading = false; - }); - } else { - this.$refs.panoiframe.onload = () => { - console.log('loading2') - // 加载成功 - this.isLoading = false; + import flvjs from "flv.js"; + import { nextTick } from "vue"; + import { HomeAPI } from "../api/home"; + import { getProjectId, getToken, getProjectEndDate } from "../utils/getToken.js"; + import Gantt from "@/components/Gantt.vue"; + export default { + name: "Home", + components: { Gantt }, + props: { + selectedId: { + type: String, + default: "", + }, + isFullScreen: { + type: Boolean, + default: false, + }, + }, + data() { + return { + liveValue: [], + playerStatus: "未就绪", + errorMessage: "", + flvPlayer: null, + videoSrc: "", + currentView: "model", + chartOptions: { + id: "shigongjinduChart", + options: { + title: { + text: "施工进度", + }, + }, + }, + bottomImage: new URL("@/assets/images/titles/shigong.png", import.meta.url).href, + isLoading: false, + panoVersionList: [], + isFullScreen: false, + fullScreenStyle: "", + fullScreenPanoStyle: "", + fullScreenModelStyle: "", + panoList: [ + { + value: "zhinan", + label: "指南", + children: [ + { + value: "shejiyuanze", + label: "设计原则", + }, + { + value: "daohang", + label: "导航", + }, + ], + }, + { + value: "zujian", + label: "组件", + children: [ + { + value: "basic", + label: "Basic", + }, + { + value: "form", + label: "Form", + }, + { + value: "data", + label: "Data", + }, + { + value: "notice", + label: "Notice", + }, + { + value: "navigation", + label: "Navigation", + }, + { + value: "others", + label: "Others", + }, + ], + }, + ], + panoValue: [], + liveList: [], + backgroundImage: new URL("@/assets/images/backgrounds/cover_bg.png", import.meta.url).href, + endDate: 0, }; - } - } -}, - - methods: { - getItemImg (item) { - return `${window.ProjectConfig.panoBaseUrl}/Panorama${this.panoObj.PbUrl}/vtour/panos/${item.PsScenename}.tiles/thumb.jpg` - }, - handleZoomOut() { - console.log('放大') - this.isFullScreen = !this.isFullScreen - if (this.isFullScreen) { - const clientX = document.documentElement.clientWidth || document.body.clientWidth - const clientY = document.documentElement.clientHeight || document.body.clientHeight - this.fullScreenStyle = `width: ${clientX - 40}px; height: ${clientY - 120}px; margin:20px; position: fixed; top: 80px; left: 0;z-index: 100;background-color: #fff;overflow: hidden;` - if (this.currentView === '720') { - this.fullScreenPanoStyle = `width: 100%; height: 100%; z-index: 100; ` - } else if(this.currentView === 'model'){ - this.fullScreenModelStyle = `width: ${clientX - 40}px; height: ${clientY - 120}px; margin:20px; position: fixed; top: 80px; left: 0;z-index: 100;background-color: #fff;overflow: hidden;` + }, + computed: { + sectionStyle() { + return { + backgroundImage: `url(${this.backgroundImage})`, + backgroundRepeat: "no-repeat", + backgroundPosition: "center center", + backgroundSize: "100% 100%", + }; + }, + projectId() { + return getProjectId(); + }, + projectEndDate() { + return getProjectEndDate(); + }, + }, + watch: { + projectEndDate: { + deep: true, + handler(newVal) { + console.log("newVal", newVal); + const date = new Date(newVal); + // 获取当前日期作为Date对象 + const now = new Date(); + // 计算两个日期的差异(毫秒) + const diffTime = Math.abs(now - date); + // 将毫秒转换为天数 + const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24)); + this.endDate = diffDays; + }, + }, + selectedId: { + handler(newVal) { + console.log("实况界面接收到的数据:", newVal); + // 处理数据变化的逻辑 + this.getProjectLive(newVal); + }, + deep: true, // 深度监听对象内部变化 + immediate: true, // 立即执行一次 + }, + isFullScreen: { + handler(newVal) { + console.log("实况界面接收到的数据:", newVal); + // 处理数据变化的逻辑 + if (newVal) { + this.$refs.videoElement.style.height = "100%"; + } else { + this.$refs.videoElement.style.height = "450px"; + } + }, + deep: true, // 深度监听对象内部变化 + immediate: true, // 立即执行一次 + }, + }, + mounted() { + setTimeout(() => { + console.log("projectEndDate", getProjectEndDate()); + this.modelShow(); + }, 1000); + }, + updated() { + if (this.$refs.panoiframe) { + // IE + if (this.$refs.panoiframe.attachEvent) { + this.$refs.panoiframe.attachEvent("onload", () => { + console.log("loading"); + // 加载成功 + this.isLoading = false; + }); + } else { + this.$refs.panoiframe.onload = () => { + console.log("loading2"); + // 加载成功 + this.isLoading = false; + }; + } } - } - }, - handleChange(view) { - this.isLoading = true - this.currentView = view - if (view === 'model') { - nextTick(() => { - this.modelShow() - }) - } else if (view === '720') { - nextTick(() => { - this.panoShow() - }) - } else if (view === 'project') { - nextTick(() => { - this.sceneShow() - }) - } - }, - handlePanoChange(value) { - console.log('value', value) - this.isLoading = true - this.panoList.forEach(item => { - if (item.LabelId === value[0]) { - item.Children.forEach(item2 => { - if (item2.PbGuid === value[1]) { - this.panoObj = item2 - console.log('panoObj', this.panoObj) - this.getPanoPhase(item2) - } - }) - } - }) - }, - modelShow() { - const iframe = document.getElementById('model-iframe') - const token = getToken() - const projectId = this.projectId - let ifrSrc = '' - console.log('模型中查看') - // ifrSrc = `${window.ProjectConfig.modelUrl}?token=${token}&projectId=${projectId}&isPreview=1&edit=false` - ifrSrc = window.ProjectConfig.modelUrl - iframe.src = ifrSrc - console.log('加载iframe地址', ifrSrc) - this.isLoading = false - }, - panoShow() { - const data = { - projectId: this.projectId - } - HomeAPI.GetProjectPanoramaList(data).then(res => { - console.log('全景图', res) - if (res.Ret === 1) { - const result = res.Data - if (result.length > 0) { - result.forEach(element => { - element.id = element.LabelId - element.label = element.LabelName - element.Children.forEach(item => { - item.id = item.PbGuid - item.label = item.PbName - }); + }, + created() { + window.addEventListener("resize", function () { + this.$refs.vi; }); - this.panoList = result - this.panoValue = [result[0].id, result[0].Children[0].id] - this.panoObj = result[0].Children[0] - this.getPanoPhase() - } - } - }) + }, + methods: { + getItemImg(item) { + return `${window.ProjectConfig.panoBaseUrl}/Panorama${this.panoObj.PbUrl}/vtour/panos/${item.PsScenename}.tiles/thumb.jpg`; + }, + handleZoomOut() { + console.log("放大"); + this.isFullScreen = !this.isFullScreen; + if (this.isFullScreen) { + const clientX = document.documentElement.clientWidth || document.body.clientWidth; + const clientY = document.documentElement.clientHeight || document.body.clientHeight; + this.fullScreenStyle = `width: ${clientX - 40}px; height: ${ + clientY - 120 + }px; margin:20px; position: fixed; top: 80px; left: 0;z-index: 100;background-color: #fff;overflow: hidden;`; + if (this.currentView === "720") { + this.fullScreenPanoStyle = `width: 100%; height: 100%; z-index: 100; `; + } else if (this.currentView === "model") { + this.fullScreenModelStyle = `width: ${clientX - 40}px; height: ${ + clientY - 120 + }px; margin:20px; position: fixed; top: 80px; left: 0;z-index: 100;background-color: #fff;overflow: hidden;`; + } + } + }, + handleChange(view) { + this.isLoading = true; + this.currentView = view; + if (view === "model") { + nextTick(() => { + this.modelShow(); + }); + } else if (view === "720") { + nextTick(() => { + this.panoShow(); + }); + } else if (view === "project") { + nextTick(() => { + this.getProjectLive(this.selectedId); + }); + } + }, + handlePanoChange(value) { + console.log("value", value); + this.isLoading = true; + this.panoList.forEach((item) => { + if (item.LabelId === value[0]) { + item.Children.forEach((item2) => { + if (item2.PbGuid === value[1]) { + this.panoObj = item2; + console.log("panoObj", this.panoObj); + this.getPanoPhase(item2); + } + }); + } + }); + }, + modelShow() { + const iframe = document.getElementById("model-iframe"); + const token = getToken(); + const projectId = this.projectId; + let ifrSrc = ""; + console.log("模型中查看"); + // ifrSrc = `${window.ProjectConfig.modelUrl}?token=${token}&projectId=${projectId}&isPreview=1&edit=false` + ifrSrc = window.ProjectConfig.modelUrl; + iframe.src = ifrSrc; + console.log("加载iframe地址", ifrSrc); + this.isLoading = false; + }, + panoShow() { + const data = { + projectId: this.projectId, + }; + HomeAPI.GetProjectPanoramaList(data).then((res) => { + console.log("全景图", res); + if (res.Ret === 1) { + const result = res.Data; + if (result.length > 0) { + result.forEach((element) => { + element.id = element.LabelId; + element.label = element.LabelName; + element.Children.forEach((item) => { + item.id = item.PbGuid; + item.label = item.PbName; + }); + }); + this.panoList = result; + this.panoValue = [result[0].id, result[0].Children[0].id]; + this.panoObj = result[0].Children[0]; + this.getPanoPhase(); + } + } + }); + }, + getPanoPhase() { + const data = { + pbguid: this.panoObj.PbGuid, + }; + HomeAPI.GetScenesByPbGuid(data).then((res) => { + console.log("全景图阶段", res); + if (res.Ret === 1) { + this.panoVersionList = res.Data; + this.panoPreview(this.panoObj, this.panoVersionList[0]); + } + }); + }, + panoPreview(item, scene) { + // /LinkShare/PanoShare/:PanoId/:organizeId/:StartScene + // PanoId:全景图的id,organizeId:项目id,StartScene:初始场景id + const panoFrame = document.getElementById("panoviewpreview"); + nextTick(() => { + if (panoFrame.src) { + panoFrame.removeAttribute("src"); //先移除上一次的src地址 + } + setTimeout(() => { + let ifrSrc = ""; + ifrSrc = `${window.ProjectConfig.panoUrl}/#/LinkShare/PanoShare/${scene.PbGuid}/${this.projectId}/${scene.PsScenename}`; + panoFrame.setAttribute("src", ifrSrc); + }, 300); + }); + // removepano('krpanoSWFObject') + // const basepath = `${window.ProjectConfig.panoUrl}/Panorama${item.PbUrl}/vtour/` + // const xmlurl = `${basepath}tour.xml?r=${(Math.random() * 100000 + 1)}` + // let setting = {} + // if (scene) { + // const scenename = 'scene_' + scene.PsScenename + // setting = { + // startscene: scenename + // } + // } + // this.$nextTick(() => { + // embedpano({ + // xml: xmlurl, + // target: 'panoviewpreview', + // basepath, + // vars: setting, + // html5: 'auto', + // passQueryParameters: true, + // }) + // }) + }, + sceneShow() { + const iframe = document.getElementById("scene-iframe"); + let ifrSrc = ""; + ifrSrc = window.ProjectConfig.sceneUrl; + iframe.src = ifrSrc; + this.isLoading = false; + }, + mounted() { + this.isLoading = true; + this.modelShow(); + }, + /** + * 获取项目实况数据 + * @param {string} bindId - 标段ID + */ + getProjectLive(bindId) { + const params = { + bindId, + }; + HomeAPI.GetJSCProjectMonitor(params).then((res) => { + if (res.Ret === 1) { + const result = res.Data; + if (result.length > 0) { + console.log("实况数据", result); + result.forEach((element) => { + element.id = element.BindId; + element.label = element.BindName; + element.JSCProjectMonitorList.forEach((item) => { + item.id = item.MonitorUrl; + item.label = item.MonitorName; + }); + }); + } + this.isLoading = false; + this.liveList = result; + this.liveValue = [result[0].id, result[0].JSCProjectMonitorList[0].id]; + this.videoSrc = this.liveList[0].JSCProjectMonitorList[0].MonitorUrl; + this.loadVideo(); + } + }); + }, + /** + * 处理实况的实时变化 + * @param value + */ + handleLiveChange(value) { + console.log("实况变化", value); + this.videoSrc = value[1]; + this.loadVideo(); + }, + // 检查FLV支持 + checkFlvSupport() { + if (!flvjs.isSupported()) { + this.errorMessage = "当前浏览器不支持FLV播放"; + this.playerStatus = "不支持"; + return false; + } + this.playerStatus = "已就绪"; + return true; + }, + /** + * 销毁播放器实例 + */ + destroyPlayer() { + if (this.flvPlayer) { + try { + this.flvPlayer.pause(); + this.flvPlayer.unload(); + this.flvPlayer.detachMediaElement(); + this.flvPlayer.destroy(); + this.flvPlayer = null; + } catch (error) { + console.error("销毁播放器时出错:", error); + } + } + this.isReady = false; + }, + /** + * 加载视频 + */ + loadVideo() { + if (!this.videoSrc.trim()) { + this.errorMessage = "请播放有效的视频URL"; + return; + } - }, - getPanoPhase() { - const data = { - pbguid: this.panoObj.PbGuid - } - HomeAPI.GetScenesByPbGuid(data).then(res => { - console.log('全景图阶段', res) - if (res.Ret === 1) { - this.panoVersionList = res.Data - this.panoPreview(this.panoObj, this.panoVersionList[0]) - } - }) - }, - panoPreview(item, scene) { - // /LinkShare/PanoShare/:PanoId/:organizeId/:StartScene - // PanoId:全景图的id,organizeId:项目id,StartScene:初始场景id - const panoFrame = document.getElementById('panoviewpreview') - nextTick(() => { - if(panoFrame.src){ - panoFrame.removeAttribute("src"); //先移除上一次的src地址 - } - setTimeout(()=>{ - let ifrSrc = '' - ifrSrc = `${window.ProjectConfig.panoUrl}/#/LinkShare/PanoShare/${scene.PbGuid}/${this.projectId}/${scene.PsScenename}` - panoFrame.setAttribute("src",ifrSrc); - }, 300) - - }) - // removepano('krpanoSWFObject') - // const basepath = `${window.ProjectConfig.panoUrl}/Panorama${item.PbUrl}/vtour/` - // const xmlurl = `${basepath}tour.xml?r=${(Math.random() * 100000 + 1)}` - // let setting = {} - // if (scene) { - // const scenename = 'scene_' + scene.PsScenename - // setting = { - // startscene: scenename - // } - // } - // this.$nextTick(() => { - // embedpano({ - // xml: xmlurl, - // target: 'panoviewpreview', - // basepath, - // vars: setting, - // html5: 'auto', - // passQueryParameters: true, - // }) - // }) - }, - sceneShow() { - const iframe = document.getElementById('scene-iframe') - let ifrSrc = '' - ifrSrc = window.ProjectConfig.sceneUrl - iframe.src = ifrSrc - this.isLoading = false - }, - mounted() { - this.isLoading = true - this.modelShow() - } - } -} + if (!this.checkFlvSupport()) { + return; + } + this.errorMessage = ""; + this.playerStatus = "加载中..."; + + try { + // 销毁旧的播放器实例 + this.destroyPlayer(); + + // 创建FLV播放器 + this.flvPlayer = flvjs.createPlayer( + { + type: "flv", + url: this.videoSrc, + isLive: false, // 如果是直播流,设置为true + cors: true, + withCredentials: false, + }, + { + enableWorker: false, + enableStashBuffer: true, + stashInitialSize: 128, + autoCleanupSourceBuffer: true, + }, + ); + + // 绑定事件监听器 + // this.bindPlayerEvents() + + // 绑定到video元素 + this.flvPlayer.attachMediaElement(this.$refs.videoElement); + + // 开始加载 + this.flvPlayer.load(); + } catch (error) { + console.error("加载视频失败:", error); + this.errorMessage = "视频加载失败: " + error.message; + this.playerStatus = "加载失败"; + } + }, + }, + }; </script> <style lang="scss" scoped> -.home-container { - display: flex; - flex-direction: column; - height: calc(100vh - 100px); - overflow: hidden; -} - -.top-nav { - height: 5vh; - display: flex; - justify-content: space-between; - align-items: center; - color: white; -} - -.bottom-nav { - flex: 1; -} - -.nav-items { - display: flex; - gap: 20px; -} - -.nav-item { - background: rgba(112, 119, 140, 0.3); - border-radius: 2px; - border: 1px solid rgba(112, 124, 140, 0.6); - padding: 5px 16px; - cursor: pointer; -} - -.nav-item.active { - background: rgba(255, 191, 0, 0.2); - border-radius: 2px; - border: 1px solid #FFBF00; -} - -.time-info { - display: flex; - flex-direction: column; - align-items: center; - width: 200px; -} - -.time-info-item { - display: flex; - align-items: center; - -} - -.time-line { - width: 200px; - height: 1px; - background: linear-gradient(270deg, rgba(255, 191, 0, 0) 0%, #FFBF00 100%); -} - -.content-wrapper { - display: flex; - overflow: hidden; - position: relative; - height: 98%; -} - -.chart-content { - width: 100%; - height: calc(100% - 52% - 20px); -} - -.side-menu { - width: 160px; - color: white; - position: absolute; - top: 10px; - left: 10px; - right: auto; - bottom: auto; - - ::v-deep .el-cascader { - width: 100%; - height: 100%; - - .el-cascader-node__label { - color: #fff; + .home-container { + display: flex; + flex-direction: column; + height: calc(100vh - 100px); + overflow: hidden; + } + .top-nav { + height: 5vh; + display: flex; + justify-content: space-between; + align-items: center; + color: white; } - .el-input .el-input__inner { - background: rgba(33, 72, 115, 0.9); + .bottom-nav { + flex: 1; } - } -} -.menu-dropdown { - padding: 15px; -} - -.menu-select { - width: 100%; - padding: 8px; - background-color: #0a1931; - color: white; - border: 1px solid #2a4d7d; -} - -.menu-list { - border-top: 1px solid #2a4d7d; -} - -.menu-item { - padding: 12px 20px; - display: flex; - justify-content: space-between; - align-items: center; - cursor: pointer; -} - -.menu-item:hover { - background-color: rgba(255, 255, 255, 0.1); -} - -.arrow-icon { - border: solid white; - border-width: 0 2px 2px 0; - display: inline-block; - padding: 3px; - transform: rotate(-45deg); -} - -.submenu { - background-color: #152b4a; -} - -.submenu-item { - padding: 10px 30px; - font-size: 14px; - cursor: pointer; -} - -.submenu-item:hover { - background-color: rgba(255, 255, 255, 0.1); -} - -.main-content { - flex: 1; - background-color: #fff; - width: 100%; - height: 100%; -} - -.content-header { - color: white; - margin-bottom: 20px; -} - -.chart-container { - padding: 20px; - width: 100%; - height: calc(100% - 5vh); -} - -.chart-legend { - display: flex; - gap: 20px; - margin-bottom: 20px; - color: white; -} - -.legend-item { - display: flex; - align-items: center; - gap: 8px; -} - -.dot { - width: 10px; - height: 10px; - border-radius: 50%; -} - -.dot.blue { - background-color: #00ffff; -} - -.dot.yellow { - background-color: #ffd700; -} - -.chart-area { - height: 400px; - margin-bottom: 20px; -} - -.chart-tabs { - display: flex; - gap: 10px; -} - -.tab { - padding: 8px 16px; - color: white; - cursor: pointer; - border-radius: 4px; -} - -.tab.active { - background-color: #2a4d7d; -} -</style><style lang="scss"> -.custom-dropdown { - background-color: rgba(33, 72, 115, 0.9); - border-radius: 2px; - border: 1px solid #3068A5; - - .el-cascader-menu { - color: #fff; - - .el-cascader-node__label { - color: #fff; + .nav-items { + display: flex; + gap: 20px; } - } - .el-cascader .el-input .el-input__inner:focus, - .el-cascader .el-input.is-focus .el-input__inner { - height: 28px; - line-height: 28px; - } + .nav-item { + background: rgba(112, 119, 140, 0.3); + border-radius: 2px; + border: 1px solid rgba(112, 124, 140, 0.6); + padding: 5px 16px; + cursor: pointer; + } - .el-cascader .el-input .el-input__inner { - height: 28px; - line-height: 28px; - background: rgba(33, 72, 115, 0.9); - } + .nav-item.active { + background: rgba(255, 191, 0, 0.2); + border-radius: 2px; + border: 1px solid #ffbf00; + } - .el-input__icon { - line-height: 38px; - } + .time-info { + display: flex; + flex-direction: column; + align-items: center; + width: 200px; + } - .el-cascader-node:not(.is-disabled):focus, - .el-cascader-node:not(.is-disabled):hover { - background: #3068A5; - } + .time-info-item { + display: flex; + align-items: center; + } - .popper__arrow { - display: none; - } + .time-line { + width: 200px; + height: 1px; + background: linear-gradient(270deg, rgba(255, 191, 0, 0) 0%, #ffbf00 100%); + } - .el-scrollbar__wrap { - overflow: hidden; - margin-bottom: 0px !important; - margin-right: 0px !important; - } -} + .content-wrapper { + display: flex; + overflow: hidden; + position: relative; + height: 98%; + } + + .chart-content { + width: 100%; + height: calc(100% - 52% - 20px); + } + + .side-menu { + width: 160px; + color: white; + position: absolute; + top: 10px; + left: 10px; + right: auto; + bottom: auto; + + ::v-deep .el-cascader { + width: 100%; + height: 100%; + + .el-cascader-node__label { + color: #fff; + } + + .el-input .el-input__inner { + background: rgba(33, 72, 115, 0.9); + } + } + } + + .menu-dropdown { + padding: 15px; + } + + .menu-select { + width: 100%; + padding: 8px; + background-color: #0a1931; + color: white; + border: 1px solid #2a4d7d; + } + + .menu-list { + border-top: 1px solid #2a4d7d; + } + + .menu-item { + padding: 12px 20px; + display: flex; + justify-content: space-between; + align-items: center; + cursor: pointer; + } + + .menu-item:hover { + background-color: rgba(255, 255, 255, 0.1); + } + + .arrow-icon { + border: solid white; + border-width: 0 2px 2px 0; + display: inline-block; + padding: 3px; + transform: rotate(-45deg); + } + + .submenu { + background-color: #152b4a; + } + + .submenu-item { + padding: 10px 30px; + font-size: 14px; + cursor: pointer; + } + + .submenu-item:hover { + background-color: rgba(255, 255, 255, 0.1); + } + + .main-content { + flex: 1; + background-color: #fff; + width: 100%; + height: 100%; + } + + .content-header { + color: white; + margin-bottom: 20px; + } + + .chart-container { + padding: 20px; + width: 100%; + height: calc(100% - 5vh); + } + + .chart-legend { + display: flex; + gap: 20px; + margin-bottom: 20px; + color: white; + } + + .legend-item { + display: flex; + align-items: center; + gap: 8px; + } + + .dot { + width: 10px; + height: 10px; + border-radius: 50%; + } + + .dot.blue { + background-color: #00ffff; + } + + .dot.yellow { + background-color: #ffd700; + } + + .chart-area { + height: 400px; + margin-bottom: 20px; + } + + .chart-tabs { + display: flex; + gap: 10px; + } + + .tab { + padding: 8px 16px; + color: white; + cursor: pointer; + border-radius: 4px; + } + + .tab.active { + background-color: #2a4d7d; + }</style +><style lang="scss"> + .custom-dropdown { + background-color: rgba(33, 72, 115, 0.9); + border-radius: 2px; + border: 1px solid #3068a5; + + .el-cascader-menu { + color: #fff; + + .el-cascader-node__label { + color: #fff; + } + } + + .el-cascader .el-input .el-input__inner:focus, + .el-cascader .el-input.is-focus .el-input__inner { + height: 28px; + line-height: 28px; + } + + .el-cascader .el-input .el-input__inner { + height: 28px; + line-height: 28px; + background: rgba(33, 72, 115, 0.9); + } + + .el-input__icon { + line-height: 38px; + } + + .el-cascader-node:not(.is-disabled):focus, + .el-cascader-node:not(.is-disabled):hover { + background: #3068a5; + } + + .popper__arrow { + display: none; + } + + .el-scrollbar__wrap { + overflow: hidden; + margin-bottom: 0px !important; + margin-right: 0px !important; + } + } </style> -- Gitblit v1.9.3