Bladeren bron

feat: 添加全屏功能支持

yusheng 3 maanden geleden
bovenliggende
commit
16895c87ee
4 gewijzigde bestanden met toevoegingen van 128 en 16 verwijderingen
  1. 2 1
      package.json
  2. 2 0
      src/main.js
  3. 123 15
      src/views/home/index.vue
  4. 1 0
      src/views/home/map.vue

+ 2 - 1
package.json

@@ -47,6 +47,7 @@
     "vue-clipboard2": "^0.3.3",
     "vue-countup-v2": "^4.0.0",
     "vue-echarts": "^6.2.3",
+    "vue-fullscreen": "^2.6.1",
     "vue-i18n": "^8.27.2",
     "vue-router": "^3.6.4",
     "vue-virtual-scroller": "^1.1.2",
@@ -81,4 +82,4 @@
     "vue-template-compiler": "^2.7.10",
     "webpack": "^5.74.0"
   }
-}
+}

+ 2 - 0
src/main.js

@@ -8,6 +8,7 @@ import permission from './utils/permission';
 import { MAP_KEY, LICENSE_CODE } from '@/config/setting';
 import EleAdmin from 'ele-admin';
 import VueClipboard from 'vue-clipboard2';
+import VueFullscreen from 'vue-fullscreen';
 import i18n from './i18n';
 import './styles/index.scss';
 import DictSelection from '@/components/Dict/DictSelection';
@@ -47,6 +48,7 @@ Vue.use(EleAdmin, {
 });
 Vue.use(permission);
 Vue.use(VueClipboard);
+Vue.use(VueFullscreen);
 let instance = null;
 // bpmnProcessDesigner 需要引入
 import MyPD from '@/components/bpmnProcessDesigner/package/index.js';

+ 123 - 15
src/views/home/index.vue

@@ -1,6 +1,11 @@
 <template>
-  <div class="h-[100%] page">
-    <div class="top_box">
+  <vue-fullscreen
+    v-model="isFullscreen"
+    :exit-on-click-wrapper="false"
+    class="h-[100%]"
+  >
+    <div class="page" :class="{ 'fullscreen-active': isFullscreen }">
+      <div class="top_box">
       <div class="title">
         <span class="title_text">生产管控</span>
       </div>
@@ -58,7 +63,9 @@
                 </div>
               </div>
 
-              <div class="userName"> </div>
+              <div class="fullscreen-btn" @click="toggleFullscreen">
+                <i :class="isFullscreen ? 'el-icon-close' : 'el-icon-full-screen'"></i>
+              </div>
             </div>
           </el-col>
         </el-row>
@@ -378,7 +385,8 @@
       </div>
     </div>
     <Drawer ref="DrawerRef"></Drawer>
-  </div>
+    </div>
+  </vue-fullscreen>
 </template>
 <script>
   import {
@@ -397,6 +405,7 @@
   import { CanvasRenderer } from 'echarts/renderers';
   import { BarChart } from 'echarts/charts';
   import { getFactoryarea } from '@/api/factoryModel/index';
+  import { component } from 'vue-fullscreen';
 
   import {
     GridComponent,
@@ -411,12 +420,16 @@
     LegendComponent
   ]);
   export default {
-    name: 'Home',
-    components: { MapDemo, VChart, Drawer },
+    // name: 'Home',
+    components: { MapDemo, VChart, Drawer, VueFullscreen: component },
     mixins: [echartsMixin(['barRef'])],
     data() {
       return {
         timer: null,
+        deviceObserver: null,
+        stationObserver: null,
+        alarmObserver: null,
+        isFullscreen: false,
         dateType: 2,
         stationId: 1,
         businessStatus,
@@ -449,6 +462,14 @@
         productLineList: []
       };
     },
+    watch: {
+      isFullscreen() {
+        setTimeout(() => {
+          this.getMaxHeigth();
+          this.resizeAllCharts();
+        }, 300);
+      }
+    },
     mounted() {
       getFactoryarea({
         pageNum: 1,
@@ -468,6 +489,7 @@
     beforeDestroy() {
       window.removeEventListener('resize', this.getMaxHeigth);
       clearInterval(this.timer);
+      this.disconnectObservers();
     },
     methods: {
       barOptionFn(data, dataY) {
@@ -526,16 +548,61 @@
       dateTypeChange() {
         this.init();
       },
+      disconnectObservers() {
+        if (this.deviceObserver) {
+          this.deviceObserver.disconnect();
+          this.deviceObserver = null;
+        }
+        if (this.stationObserver) {
+          this.stationObserver.disconnect();
+          this.stationObserver = null;
+        }
+        if (this.alarmObserver) {
+          this.alarmObserver.disconnect();
+          this.alarmObserver = null;
+        }
+      },
+      initResizeObservers() {
+        this.disconnectObservers();
+        
+        const createObserver = (refName, callback) => {
+          const el = this.$refs[refName];
+          if (!el) return null;
+          
+          const observer = new ResizeObserver((entries) => {
+            for (const entry of entries) {
+              callback(entry.contentRect.height);
+            }
+          });
+          observer.observe(el);
+          return observer;
+        };
+
+        this.deviceObserver = createObserver('deviceTableRef', (height) => {
+          this.deviceMaxHeight = height - 10;
+        });
+        
+        this.stationObserver = createObserver('stationTableRef', (height) => {
+          this.stationMaxHeight = height - 10;
+        });
+        
+        this.alarmObserver = createObserver('alarmListRef', (height) => {
+          this.alarmMaxHeight = height - 10;
+        });
+      },
       getMaxHeigth() {
         this.$nextTick(() => {
-          setTimeout(() => {
-            this.deviceMaxHeight = this.$refs.deviceTableRef.clientHeight;
-            this.stationMaxHeight = this.$refs.stationTableRef.clientHeight;
-            this.alarmMaxHeight = this.$refs.alarmListRef.clientHeight;
-            this.mapHeight = this.$refs.mapBoxRef.clientHeight - 30;
-          }, 100);
+          this.initResizeObservers();
+          
+          const mapEl = this.$refs.mapBoxRef;
+          if (mapEl) {
+            this.mapHeight = mapEl.clientHeight - 30;
+          }
         });
       },
+      toggleFullscreen() {
+        this.isFullscreen = !this.isFullscreen;
+      },
       init() {
         queryComprehensiveStatisticsAndWarningStatistics({
           dateType: this.dateType,
@@ -686,6 +753,30 @@
           background: rgb(34, 156, 152);
         }
       }
+      .fullscreen-btn {
+        position: absolute;
+        right: 15px;
+        width: 36px;
+        height: 36px;
+        display: flex;
+        align-items: center;
+        justify-content: center;
+        background: rgba(56, 255, 249, 0.15);
+        border: 1px solid #38fff9;
+        border-radius: 4px;
+        cursor: pointer;
+        transition: all 0.3s ease;
+
+        i {
+          font-size: 18px;
+          color: #38fff9;
+        }
+
+        &:hover {
+          background: rgba(56, 255, 249, 0.3);
+          box-shadow: 0 0 10px rgba(56, 255, 249, 0.5);
+        }
+      }
     }
     .right_box {
       position: relative;
@@ -735,7 +826,7 @@
       height: 100%;
       .comprehensive {
         .header {
-          height: 35px;
+          height:14%;
         }
         width: 100%;
         height: 27%;
@@ -770,7 +861,7 @@
         flex-direction: column;
       }
       .header {
-        height: 45px;
+        height: 13%;
         display: flex;
         align-items: center;
         img {
@@ -863,6 +954,7 @@
             padding: 10px 0;
             width: 45%;
             height: calc(5.9vh);
+            min-height: 63px;
             margin-bottom: 18px;
             display: flex;
             flex-direction: column;
@@ -945,7 +1037,7 @@
         background-size: 100% 100%;
         min-height: 300px;
         .header {
-          height: 40px;
+          height:15%;
           display: flex;
           align-items: center;
           img {
@@ -1016,4 +1108,20 @@
   :deep(.el-table__body tr:hover > td) {
     background-color: rgba(255, 123, 48, 0.6) !important;
   }
+  :deep(.el-table) {
+    height: 100% !important;
+  }
+  :deep(.el-table__body-wrapper) {
+    overflow-y: auto !important;
+    height: 100% !important;
+  }
+
+  /* 全屏时 header 内容自适应居中 */
+  .fullscreen-active {
+    height: 100vh !important;
+    .header {
+      display: flex !important;
+      align-items: center !important;
+    }
+  }
 </style>

+ 1 - 0
src/views/home/map.vue

@@ -40,6 +40,7 @@
         plugins: ['AMap.Scale'] //需要使用的的插件列表,如比例尺'AMap.Scale',支持添加多个如:['AMap.Scale','...','...']
       })
         .then((AMap) => {
+          
           var map = new AMap.Map('container', {
             pitch: 0, //地图俯仰角度,有效范围 0 度- 83 度
             viewMode: '3D', //地图模式