- -
等待配置三维模型地址
+ + +
等待配置三维模型地址
@@ -261,6 +265,15 @@ export default { headerDateCn: '', headerTime: '', iframeAddress: '', + mode: 'DT', + currentMode: 'DT', + srcDt: 'http://localhost:10056/', + srcSm: 'http://localhost:10059/', + autoPlayCraftCode: '', + modeSwitchTimer: null, + cameraSyncTimer: null, + iframeReadyTimer: null, + dmtIframeReady: false, clockTimer: null, resizeHandler: null, alarmPieChart: null, @@ -268,7 +281,8 @@ export default { viewButtons: [ { label: '长地轨视角', value: 'longRail' }, { label: '短地轨视角', value: 'shortRail' }, - { label: '关节视角', value: 'joint' } + { label: '关节视角', value: 'joint' }, + { label: '磨床视角', value: 'grinder' } ], cameraViews: { longRail: { @@ -285,6 +299,11 @@ export default { target: { x: 2.7622940494890424, y: 15.83905572715569, z: 0.08552052688719107 }, position: { x: -3.2731867066688367, y: 15.875402633541817, z: 9.618973337149745 }, zoom0: 1 + }, + grinder: { + target: { x: -10.128808700176803, y: -15.480679803858136, z: 1.9651555238025413 }, + position: { x: -18.876923526978523, y: -15.520222640141816, z: 9.998726005761771 }, + zoom0: 1 } }, lineMonitorRows: [ @@ -487,8 +506,12 @@ export default { } }, mounted() { - this.iframeAddress = window.dt_Config && window.dt_Config.iframeAddress ? window.dt_Config.iframeAddress : '' - this.titleText = window.dt_Config.titleText + const config = window.dt_Config || {} + this.iframeAddress = config.iframeAddress ? config.iframeAddress : '' + this.autoPlayCraftCode = config.autoPlayCraftCode || 'E8077755-9B85-46A1-9B8A-85083C00DF26' + this.srcDt = this.buildIframeUrl(config.dtIframe || this.srcDt, this.autoPlayCraftCode) + this.srcSm = this.buildIframeUrl(config.smIframe || this.srcSm, this.autoPlayCraftCode) + this.titleText = config.titleText this.updateTime() this.setScale() this.$nextTick(this.initAlarmPieChart) @@ -500,6 +523,7 @@ export default { } } window.addEventListener('resize', this.resizeHandler) + window.addEventListener('message', this.handleDmtMessage) }, beforeDestroy() { if (this.clockTimer) { @@ -510,6 +534,19 @@ export default { window.removeEventListener('resize', this.resizeHandler) this.resizeHandler = null } + window.removeEventListener('message', this.handleDmtMessage) + if (this.modeSwitchTimer) { + clearTimeout(this.modeSwitchTimer) + this.modeSwitchTimer = null + } + if (this.cameraSyncTimer) { + clearTimeout(this.cameraSyncTimer) + this.cameraSyncTimer = null + } + if (this.iframeReadyTimer) { + clearTimeout(this.iframeReadyTimer) + this.iframeReadyTimer = null + } if (this.alarmPieChart) { this.alarmPieChart.dispose() this.alarmPieChart = null @@ -535,18 +572,99 @@ export default { }, changeView(value) { this.activeView = value - const camera = this.cameraViews[value] - if (!camera) return + if (this.dmtIframeReady) { + this.syncActiveCamera() + } + }, + buildIframeUrl(baseUrl, craftCode) { + if (!baseUrl) { + return '' + } + let nextUrl = baseUrl + if (craftCode && nextUrl.includes('autoPlayCraftCode=') && !nextUrl.includes(craftCode)) { + const separator = nextUrl.endsWith('=') || nextUrl.endsWith('/') ? '' : '/' + nextUrl = `${nextUrl}${separator}${craftCode}` + } + return this.withTransparentParam(nextUrl) + }, + withTransparentParam(url) { + if (!url || url.includes('transparent=true')) { + return url + } + const hashIndex = url.indexOf('#') + if (hashIndex > -1) { + const separator = url.slice(hashIndex).includes('?') ? '&' : '?' + return `${url}${separator}transparent=true` + } + return `${url}${url.endsWith('/') ? '' : '/'}#?transparent=true` + }, + handleIframeLoad() { + this.dmtIframeReady = false + if (this.iframeReadyTimer) { + clearTimeout(this.iframeReadyTimer) + this.iframeReadyTimer = null + } + }, + handleDmtMessage(event) { + if (!event || !event.data || event.data.type !== 'dmt_load_finish') { + return + } const iframe = document.getElementById('dmtIframe') - if (!iframe || !iframe.contentWindow) return - iframe.contentWindow.postMessage({ - type: 'set_camera', - data: { - target: camera.target, - position: camera.position, - zoom0: camera.zoom0 - } - }, '*') + if (!iframe || event.source !== iframe.contentWindow) { + return + } + this.markDmtIframeReady() + }, + markDmtIframeReady() { + this.dmtIframeReady = true + if (this.iframeReadyTimer) { + clearTimeout(this.iframeReadyTimer) + this.iframeReadyTimer = null + } + this.syncActiveCamera() + }, + syncActiveCamera() { + const camera = this.cameraViews[this.activeView] + if (!camera) return + if (!this.dmtIframeReady) return + if (this.cameraSyncTimer) { + clearTimeout(this.cameraSyncTimer) + } + this.cameraSyncTimer = setTimeout(() => { + const iframe = document.getElementById('dmtIframe') + if (!iframe || !iframe.contentWindow) return + iframe.contentWindow.postMessage({ + type: 'set_camera', + data: { + target: camera.target, + position: camera.position, + zoom0: camera.zoom0 + } + }, '*') + this.cameraSyncTimer = null + }, 300) + }, + switchMode(mode) { + this.currentMode = mode + this.mode = '' + this.dmtIframeReady = false + if (this.iframeReadyTimer) { + clearTimeout(this.iframeReadyTimer) + this.iframeReadyTimer = null + } + if (this.modeSwitchTimer) { + clearTimeout(this.modeSwitchTimer) + } + this.modeSwitchTimer = setTimeout(() => { + this.mode = mode + this.modeSwitchTimer = null + }, 600) + }, + changeDtMode() { + this.switchMode('DT') + }, + changeSmMode() { + this.switchMode('SM') }, initAlarmPieChart() { if (!this.$refs.alarmPieChart) { @@ -744,7 +862,7 @@ body, .view-switch { display: grid; - grid-template-columns: repeat(3, minmax(0, 1fr)); + grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 6px; pointer-events: auto; } @@ -840,10 +958,39 @@ body, 0 0 18px rgba(75, 245, 209, 0.22); } +.mode-button--active { + color: #ffffff; + border-color: rgba(128, 255, 230, 0.95); + background: + linear-gradient(90deg, rgba(12, 62, 78, 0.96), rgba(26, 122, 132, 0.88), rgba(12, 62, 78, 0.96)), + rgba(4, 20, 35, 0.86); + box-shadow: + inset 0 1px 0 rgba(255, 255, 255, 0.26), + inset 0 0 20px rgba(75, 245, 209, 0.24), + 0 0 20px rgba(75, 245, 209, 0.28); +} + .mode-button:focus { outline: none; } +.brand-logo { + display: block; + width: 300px; + height: 50px; + object-fit: contain; + object-position: left center; + pointer-events: none; + filter: drop-shadow(0 0 10px rgba(114, 232, 255, 0.28)); +} + +.mode-button-group { + display: flex; + width: 300px; + height: 30px; + gap: 10px; +} + .title-text { margin-right: 37px; color: #fff; @@ -915,17 +1062,18 @@ body, .right-control-bar { position: absolute; width: 300px; - height: 30px; z-index: 20; pointer-events: auto; } .left-control-bar { - top: 50px; + top: 18px; left: 80px; display: flex; + flex-direction: column; align-items: flex-start; - gap: 10px; + height: 66px; + gap: 7px; } .right-control-bar { @@ -939,12 +1087,16 @@ body, box-sizing: border-box; } -.right-control-bar .df-header__timebar, -.right-control-bar .view-switch { +.right-control-bar .df-header__timebar { width: 236px; justify-self: end; } +.right-control-bar .view-switch { + width: 300px; + justify-self: end; +} + .model-bg-frame { position: absolute; inset: 0; diff --git a/vue.config.js b/vue.config.js index c10288d..00c0219 100644 --- a/vue.config.js +++ b/vue.config.js @@ -26,6 +26,11 @@ module.exports = { } } } + }, + configureWebpack: { + output: { + hashFunction: 'sha256' + } } // publicPath: '/GQMobile/' }