diff --git a/src/views/qingAn.vue b/src/views/qingAn.vue index c9dcf2b..a3adfb5 100644 --- a/src/views/qingAn.vue +++ b/src/views/qingAn.vue @@ -37,6 +37,30 @@ +
+
+
+ 选择仿真播放倍率 + 默认 5 倍 +
+
+ +
+
+ + +
+
+
@@ -275,7 +299,12 @@ export default { currentMode: 'DT', srcDt: 'http://localhost:10056/', srcSm: 'http://localhost:10059/', + smIframeBase: 'http://localhost:10059/', autoPlayCraftCode: '', + autoPlayRates: [0.5, 1, 2, 4, 5, 10], + selectedAutoPlayRate: 5, + pendingAutoPlayRate: 5, + simulationRateDialogVisible: false, modeSwitchTimer: null, cameraSyncTimer: null, iframeReadyTimer: null, @@ -283,38 +312,38 @@ export default { clockTimer: null, resizeHandler: null, alarmPieChart: null, - activeView: 'longRail', + activeView: 'overview', viewButtons: [ + { label: '全揽视角', value: 'overview' }, { label: '加工中心单元视角', value: 'longRail' }, { label: '车床加工单元视角', value: 'shortRail' }, { label: '插齿机单元视角', value: 'joint' }, - { label: '磨床加工单元视角', value: 'grinder' }, - { label: '全揽视角', value: 'overview' } + { label: '磨床加工单元视角', value: 'grinder' } ], cameraViews: { longRail: { - target: { x: -5.725619423653396, y: 1.559219531820475, z: -5.23360272959924 }, - position: { x: -18.7530206850084, y: 1.6376732214652037, z: 15.344064598520557 }, + target: { x: -7.242748313927699, y: 1.365235845234568, z: -6.193333867630938 }, + position: { x: -20.270149575282687, y: 1.4436895348793037, z: 14.38433346048873 }, zoom0: 1 }, shortRail: { - target: { x: -5.814177085428968, y: 16.255194514605996, z: -5.3456965650308055 }, - position: { x: -17.571406723801864, y: 16.32599896951042, z: 13.22564819859711 }, + target: { x: -7.001588883043185, y: 16.262345352657395, z: -6.097455776264499 }, + position: { x: -18.758818521416032, y: 16.33314980756182, z: 12.473888987363225 }, zoom0: 1 }, joint: { - target: { x: 2.7622940494890424, y: 15.83905572715569, z: 0.08552052688719117 }, - position: { x: -4.6476929900921515, y: 15.883680193065107, z: 11.790099601955712 }, + target: { x: 1.9482734060133915, y: 15.747678960743341, z: -0.429474906955281 }, + position: { x: -5.461713633567803, y: 15.792303426652754, z: 11.275104168113232 }, zoom0: 1 }, grinder: { - target: { x: -10.128808700176803, y: -15.480679803858136, z: 1.9651555238025413 }, - position: { x: -21.43448244172167, y: -15.531783203240701, z: 12.347383997813267 }, + target: { x: -10.691421929972085, y: -15.525894683054275, z: 1.3522782143982923 }, + position: { x: -21.99709567151696, y: -15.576998082436841, z: 11.73450668840891 }, zoom0: 1 }, overview: { - target: { x: -2.4540886878602937, y: -1.7690793306726371, z: -0.104103172990748 }, - position: { x: -44.67609815729721, y: -1.5148097061598855, z: 38.669527626788486 }, + target: { x: -4.793874852627955, y: 6.052339186049304, z: -6.403726952169199 }, + position: { x: -26.23140973687205, y: 33.78061698752333, z: 24.44556028867285 }, zoom0: 1 } }, @@ -570,8 +599,11 @@ export default { const config = window.dt_Config || {} this.iframeAddress = config.iframeAddress ? config.iframeAddress : '' this.autoPlayCraftCode = config.autoPlayCraftCode || 'E8077755-9B85-46A1-9B8A-85083C00DF26' + this.smIframeBase = config.smIframe || this.srcSm + this.selectedAutoPlayRate = this.normalizeAutoPlayRate(config.autoPlayRate || this.getAutoPlayRateFromUrl(this.smIframeBase) || 5) + this.pendingAutoPlayRate = this.selectedAutoPlayRate this.srcDt = this.buildIframeUrl(config.dtIframe || this.srcDt, this.autoPlayCraftCode) - this.srcSm = this.buildIframeUrl(config.smIframe || this.srcSm, this.autoPlayCraftCode) + this.srcSm = this.buildIframeUrl(this.smIframeBase, this.autoPlayCraftCode, this.selectedAutoPlayRate) this.titleText = config.titleText this.updateTime() this.setScale() @@ -637,17 +669,44 @@ export default { this.syncActiveCamera() } }, - buildIframeUrl(baseUrl, craftCode) { + buildIframeUrl(baseUrl, craftCode, autoPlayRate) { if (!baseUrl) { return '' } let nextUrl = baseUrl + if (nextUrl.includes('dmtmode=SM')) { + nextUrl = this.withAutoPlayRateParam(nextUrl, this.normalizeAutoPlayRate(autoPlayRate)) + } if (craftCode && nextUrl.includes('autoPlayCraftCode=') && !nextUrl.includes(craftCode)) { const separator = nextUrl.endsWith('=') || nextUrl.endsWith('/') ? '' : '/' nextUrl = `${nextUrl}${separator}${craftCode}` } return this.withTransparentParam(nextUrl) }, + getAutoPlayRateFromUrl(url) { + const match = String(url || '').match(/[?&]autoPlayRate=([^&#]*)/) + return match ? decodeURIComponent(match[1]) : '' + }, + normalizeAutoPlayRate(rate) { + const numericRate = Number(rate) + return this.autoPlayRates.includes(numericRate) ? numericRate : 5 + }, + withAutoPlayRateParam(url, rate) { + const value = encodeURIComponent(String(rate)) + if (url.includes('autoPlayRate=')) { + return url.replace(/([?&]autoPlayRate=)[^&#]*/, `$1${value}`) + } + if (url.includes('autoPlayCraftCode=')) { + return url.replace(/([?&])autoPlayCraftCode=/, `$1autoPlayRate=${value}&autoPlayCraftCode=`) + } + const hashIndex = url.indexOf('#') + if (hashIndex > -1) { + const separator = url.slice(hashIndex).includes('?') ? '&' : '?' + return `${url}${separator}autoPlayRate=${value}` + } + const separator = url.includes('?') ? '&' : '?' + return `${url}${separator}autoPlayRate=${value}` + }, withTransparentParam(url) { if (!url || url.includes('transparent=true')) { return url @@ -725,6 +784,22 @@ export default { this.switchMode('DT') }, changeSmMode() { + this.openSimulationRateDialog() + }, + openSimulationRateDialog() { + this.pendingAutoPlayRate = this.selectedAutoPlayRate + this.simulationRateDialogVisible = true + }, + selectSimulationRate(rate) { + this.pendingAutoPlayRate = this.normalizeAutoPlayRate(rate) + }, + cancelSimulationRateDialog() { + this.simulationRateDialogVisible = false + }, + confirmSimulationRate() { + this.selectedAutoPlayRate = this.normalizeAutoPlayRate(this.pendingAutoPlayRate) + this.srcSm = this.buildIframeUrl(this.smIframeBase, this.autoPlayCraftCode, this.selectedAutoPlayRate) + this.simulationRateDialogVisible = false this.switchMode('SM') }, initAlarmPieChart() { @@ -1034,6 +1109,114 @@ body, outline: none; } +.simulation-rate-mask { + position: absolute; + inset: 0; + z-index: 80; + display: flex; + align-items: center; + justify-content: center; + background: rgba(1, 9, 20, 0.58); + pointer-events: auto; +} + +.simulation-rate-dialog { + width: 430px; + padding: 20px 22px 18px; + border: 1px solid rgba(114, 232, 255, 0.48); + background: + linear-gradient(180deg, rgba(19, 55, 82, 0.96), rgba(4, 16, 31, 0.96)), + rgba(5, 20, 44, 0.96); + box-shadow: + inset 0 1px 0 rgba(255, 255, 255, 0.12), + inset 0 0 24px rgba(44, 143, 255, 0.18), + 0 18px 42px rgba(0, 0, 0, 0.48), + 0 0 28px rgba(114, 232, 255, 0.18); +} + +.simulation-rate-dialog__head { + display: flex; + align-items: baseline; + justify-content: space-between; + gap: 12px; + margin-bottom: 18px; +} + +.simulation-rate-dialog__head strong { + color: #ffffff; + font-size: 20px; + letter-spacing: 0; + text-shadow: 0 0 12px rgba(114, 232, 255, 0.3); +} + +.simulation-rate-dialog__head span { + color: #91dfff; + font-size: 13px; +} + +.simulation-rate-options { + display: grid; + grid-template-columns: repeat(3, minmax(0, 1fr)); + gap: 10px; +} + +.simulation-rate-option, +.simulation-rate-action { + height: 36px; + border: 1px solid rgba(111, 224, 255, 0.34); + color: #d8f6ff; + background: + linear-gradient(180deg, rgba(24, 52, 82, 0.82), rgba(5, 17, 30, 0.9)), + rgba(6, 25, 53, 0.72); + font-family: inherit; + font-size: 14px; + font-weight: 700; + cursor: pointer; +} + +.simulation-rate-option--active { + color: #ffffff; + border-color: rgba(128, 255, 230, 0.95); + background: + linear-gradient(180deg, rgba(36, 216, 139, 0.42), rgba(14, 92, 61, 0.7)), + rgba(14, 92, 61, 0.52); + box-shadow: + inset 0 1px 0 rgba(255, 255, 255, 0.18), + 0 0 18px rgba(36, 216, 139, 0.24); +} + +.simulation-rate-dialog__actions { + display: flex; + justify-content: flex-end; + gap: 10px; + margin-top: 18px; +} + +.simulation-rate-action { + min-width: 96px; + padding: 0 18px; +} + +.simulation-rate-action--ghost { + color: #b9d8ec; + border-color: rgba(160, 180, 194, 0.24); + background: rgba(36, 48, 60, 0.48); +} + +.simulation-rate-action--primary { + color: #ffffff; + border-color: rgba(114, 232, 255, 0.72); + 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: 0 0 18px rgba(75, 245, 209, 0.24); +} + +.simulation-rate-option:focus, +.simulation-rate-action:focus { + outline: none; +} + .brand-logo { display: block; width: 300px;