| | |
| | | <template> |
| | | <div class="data-dashboard"> |
| | | <div class="scale-container" :style="{ transform: `scale(${scaleRatio})` }"> |
| | | <div class="data-dashboard"> |
| | | <!-- 全屏按钮 - 移动到左上角 --> |
| | | <button class="fullscreen-btn" @click="toggleFullscreen" :title="isFullscreen ? '退出全屏' : '全屏显示'"> |
| | | <svg v-if="!isFullscreen" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> |
| | |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import * as echarts from 'echarts' |
| | | import { ref, onMounted, onBeforeUnmount, nextTick } from 'vue' |
| | | import { ref, reactive, onMounted, onBeforeUnmount, nextTick } from 'vue' |
| | | import autofit from 'autofit.js' |
| | | import Echarts from "@/components/Echarts/echarts.vue"; |
| | | import useUserStore from '@/store/modules/user' |
| | |
| | | |
| | | // 全屏相关状态 |
| | | const isFullscreen = ref(false); |
| | | |
| | | // 缩放比例 |
| | | const scaleRatio = ref(1) |
| | | // 设计尺寸(基准尺寸)- 根据实际设计稿调整 |
| | | const designWidth = 1920 |
| | | const designHeight = 1080 |
| | | |
| | | // 用户store |
| | | const userStore = useUserStore() |
| | |
| | | // 待办事项 |
| | | const todoList = ref([]) |
| | | |
| | | // 窗口大小变化处理 |
| | | const handleResize = () => { |
| | | // 计算缩放比例 |
| | | const calculateScale = () => { |
| | | const container = document.querySelector('.scale-container') |
| | | if (!container) return |
| | | |
| | | // 获取容器的实际尺寸 |
| | | const containerWidth = container.clientWidth || window.innerWidth |
| | | const containerHeight = container.clientHeight || window.innerHeight |
| | | |
| | | // 计算宽高缩放比例,取较小值以保证内容完整显示(等比缩放) |
| | | const scaleX = containerWidth / designWidth |
| | | const scaleY = containerHeight / designHeight |
| | | scaleRatio.value = Math.min(scaleX, scaleY) |
| | | |
| | | // 触发图表resize |
| | | charts.value.forEach(chart => { |
| | | if (chart && chart.resize) { |
| | | chart.resize() |
| | | } |
| | | }) |
| | | } |
| | | |
| | | // 窗口大小变化处理 |
| | | const handleResize = () => { |
| | | // 延迟执行,确保DOM更新完成 |
| | | setTimeout(() => { |
| | | calculateScale() |
| | | }, 100) |
| | | } |
| | | |
| | | // 销毁图表实例 |
| | |
| | | updateTime() |
| | | timer.value = setInterval(updateTime, 1000) |
| | | } |
| | | // 全屏功能实现 - 针对data-dashboard元素 |
| | | // 全屏功能实现 - 针对scale-container元素 |
| | | const toggleFullscreen = () => { |
| | | const element = document.querySelector('.data-dashboard') |
| | | const element = document.querySelector('.scale-container') |
| | | |
| | | if (!element) return |
| | | |
| | |
| | | const fullscreenElement = document.fullscreenElement || |
| | | document.webkitFullscreenElement || |
| | | document.msFullscreenElement |
| | | isFullscreen.value = fullscreenElement && fullscreenElement.classList.contains('data-dashboard') |
| | | isFullscreen.value = fullscreenElement && fullscreenElement.classList.contains('scale-container') |
| | | |
| | | // 全屏状态变化时,延迟重新计算缩放比例(确保DOM更新完成) |
| | | setTimeout(() => { |
| | | calculateScale() |
| | | }, 200) |
| | | } |
| | | |
| | | // 生命周期钩子 |
| | |
| | | initTime() |
| | | // 使用nextTick确保DOM完全渲染后再初始化图表 |
| | | nextTick(() => { |
| | | // 初始化autofit自适应 |
| | | autofit.init({ dh: 800, dw: 1280, el: '.data-dashboard', resize: true }, false) |
| | | // 计算初始缩放比例 |
| | | calculateScale() |
| | | |
| | | // 初始化autofit自适应(如果需要保留autofit,可以保留,但主要缩放由scale-container控制) |
| | | // autofit.init({ dh: 800, dw: 1280, el: '.data-dashboard', resize: true }, false) |
| | | |
| | | // 添加自动滚动动画效果 - 客户信息列表 |
| | | const contractList = refContractList.value |
| | |
| | | }) |
| | | |
| | | window.addEventListener('resize', handleResize) |
| | | window.addEventListener('fullscreenchange', handleFullscreenChange) |
| | | window.addEventListener('webkitfullscreenchange', handleFullscreenChange) |
| | | window.addEventListener('MSFullscreenChange', handleFullscreenChange) |
| | | analysisCustomer() |
| | | qualityStatisticsInfo() |
| | | accountStatisticsInfo() |
| | |
| | | </script> |
| | | |
| | | <style scoped> |
| | | /* 外部缩放容器 - 占据整个视口 */ |
| | | .scale-container { |
| | | position: relative; |
| | | width: 100vw; |
| | | height: 100vh; |
| | | overflow: hidden; |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | transform-origin: center center; |
| | | background-color: #000; |
| | | } |
| | | |
| | | /* 内部内容区域 - 固定设计尺寸 */ |
| | | .data-dashboard { |
| | | position: relative; |
| | | width: 100%; |
| | | height: 100%; |
| | | width: 1920px; |
| | | height: 1080px; |
| | | background-image: url("@/assets/BI/backImage@2x.png"); |
| | | background-size: cover; |
| | | background-position: center; |
| | | background-repeat: no-repeat; |
| | | } |
| | | |
| | | /* 全屏状态的样式 */ |
| | | .data-dashboard:fullscreen { |
| | | width: 100%; |
| | | height: 100%; |
| | | /* 全屏状态的样式 - 作用于scale-container */ |
| | | .scale-container:fullscreen { |
| | | width: 100vw; |
| | | height: 100vh; |
| | | margin: 0; |
| | | padding: 0; |
| | | background-color: inherit; |
| | | background-color: #000; |
| | | z-index: 9999; |
| | | } |
| | | |
| | | /* Webkit浏览器前缀 */ |
| | | .data-dashboard:-webkit-full-screen { |
| | | width: 100%; |
| | | height: 100%; |
| | | .scale-container:-webkit-full-screen { |
| | | width: 100vw; |
| | | height: 100vh; |
| | | margin: 0; |
| | | padding: 0; |
| | | background-color: inherit; |
| | | background-color: #000; |
| | | z-index: 9999; |
| | | } |
| | | |
| | | /* MS浏览器前缀 */ |
| | | .data-dashboard:-ms-fullscreen { |
| | | width: 100%; |
| | | height: 100%; |
| | | .scale-container:-ms-fullscreen { |
| | | width: 100vw; |
| | | height: 100vh; |
| | | margin: 0; |
| | | padding: 0; |
| | | background-color: inherit; |
| | | background-color: #000; |
| | | z-index: 9999; |
| | | } |
| | | |