Prechádzať zdrojové kódy

增加油机设备、油站监测数据、密钥监测可视化大屏

DOVER-GLOBAL\11047086 1 rok pred
rodič
commit
39a1ef55b5
51 zmenil súbory, kde vykonal 4429 pridanie a 100 odobranie
  1. 655 90
      admin.ui.plus-master/package-lock.json
  2. 4 1
      admin.ui.plus-master/package.json
  3. 1 1
      admin.ui.plus-master/src/App.vue
  4. 3 1
      admin.ui.plus-master/src/api/admin/deviceAuthorization/softwarePackageManagementDto.ts
  5. 3 1
      admin.ui.plus-master/src/api/admin/productionManagement/ComponentDetailsDto.ts
  6. 2 1
      admin.ui.plus-master/src/api/admin/productionManagement/groupLogoKeyDto.ts
  7. BIN
      admin.ui.plus-master/src/assets/deviceVision/center_map.png
  8. BIN
      admin.ui.plus-master/src/assets/deviceVision/frame.png
  9. BIN
      admin.ui.plus-master/src/assets/deviceVision/guang.png
  10. BIN
      admin.ui.plus-master/src/assets/deviceVision/headers/juxing1.png
  11. BIN
      admin.ui.plus-master/src/assets/deviceVision/headers/juxing2.png
  12. BIN
      admin.ui.plus-master/src/assets/deviceVision/left_top_hong.png
  13. BIN
      admin.ui.plus-master/src/assets/deviceVision/left_top_huang.png
  14. BIN
      admin.ui.plus-master/src/assets/deviceVision/left_top_lan.png
  15. BIN
      admin.ui.plus-master/src/assets/deviceVision/left_top_lv.png
  16. BIN
      admin.ui.plus-master/src/assets/deviceVision/pageBg.png
  17. BIN
      admin.ui.plus-master/src/assets/deviceVision/titles/you.png
  18. BIN
      admin.ui.plus-master/src/assets/deviceVision/titles/zuo.png
  19. BIN
      admin.ui.plus-master/src/assets/deviceVision/top.png
  20. BIN
      admin.ui.plus-master/src/assets/deviceVision/xieyou.png
  21. BIN
      admin.ui.plus-master/src/assets/deviceVision/xiezuo.png
  22. BIN
      admin.ui.plus-master/src/assets/deviceVision/zuo_xuxian.png
  23. 65 0
      admin.ui.plus-master/src/components/echart/index.vue
  24. 97 0
      admin.ui.plus-master/src/components/item-wrap/item-wrap.vue
  25. 4 1
      admin.ui.plus-master/src/main.ts
  26. 59 0
      admin.ui.plus-master/src/utils/deviceVision.js
  27. 0 0
      admin.ui.plus-master/src/utils/map/china.json
  28. 217 0
      admin.ui.plus-master/src/utils/map/xzqCode.js
  29. 233 0
      admin.ui.plus-master/src/utils/mock.js
  30. 5 0
      admin.ui.plus-master/src/views/admin/authorize/softwarePackageManagement/components/form-edit.vue
  31. 1 0
      admin.ui.plus-master/src/views/admin/authorize/softwarePackageManagement/index.vue
  32. 14 1
      admin.ui.plus-master/src/views/admin/product/goodInfo/index.vue
  33. 8 1
      admin.ui.plus-master/src/views/admin/product/groupLogo/index.vue
  34. 9 2
      admin.ui.plus-master/src/views/admin/product/record/index.vue
  35. 83 0
      admin.ui.plus-master/src/views/admin/visualization/KeyWatchMonitoring/index.vue
  36. 261 0
      admin.ui.plus-master/src/views/admin/visualization/deviceVision/index.scss
  37. 105 0
      admin.ui.plus-master/src/views/admin/visualization/deviceVision/index.vue
  38. 189 0
      admin.ui.plus-master/src/views/admin/visualization/deviceVision/indexs/center-bottom.vue
  39. 385 0
      admin.ui.plus-master/src/views/admin/visualization/deviceVision/indexs/center-map.vue
  40. 140 0
      admin.ui.plus-master/src/views/admin/visualization/deviceVision/indexs/index.vue
  41. 255 0
      admin.ui.plus-master/src/views/admin/visualization/deviceVision/indexs/left-bottom.vue
  42. 247 0
      admin.ui.plus-master/src/views/admin/visualization/deviceVision/indexs/left-center.vue
  43. 195 0
      admin.ui.plus-master/src/views/admin/visualization/deviceVision/indexs/left-top.vue
  44. 194 0
      admin.ui.plus-master/src/views/admin/visualization/deviceVision/indexs/right-bottom.vue
  45. 163 0
      admin.ui.plus-master/src/views/admin/visualization/deviceVision/indexs/right-center.vue
  46. 299 0
      admin.ui.plus-master/src/views/admin/visualization/deviceVision/indexs/right-top.vue
  47. 258 0
      admin.ui.plus-master/src/views/admin/visualization/deviceVision/scale-screen.vue
  48. 105 0
      admin.ui.plus-master/src/views/admin/visualization/deviceVision/setting.vue
  49. 86 0
      admin.ui.plus-master/src/views/admin/visualization/deviceVision/test.vue
  50. 83 0
      admin.ui.plus-master/src/views/admin/visualization/fueldepotmonitoringdata/index.vue
  51. 1 0
      admin.ui.plus-master/src/views/admin/workbench/index.vue

Rozdielové dáta súboru neboli zobrazené, pretože súbor je príliš veľký
+ 655 - 90
admin.ui.plus-master/package-lock.json


+ 4 - 1
admin.ui.plus-master/package.json

@@ -15,6 +15,8 @@
   "dependencies": {
     "@element-plus/icons": "^0.0.11",
     "@element-plus/icons-vue": "^2.1.0",
+    "@jiaminghi/data-view": "^2.10.0",
+    "@kjgl77/datav-vue3": "^1.7.3",
     "@types/date-fns": "^2.6.0",
     "@wangeditor/editor": "^5.1.23",
     "@wangeditor/editor-for-vue": "^5.1.12",
@@ -23,7 +25,7 @@
     "countup.js": "^2.6.2",
     "cropperjs": "^1.5.13",
     "date-fns": "^3.6.0",
-    "echarts": "^5.4.2",
+    "echarts": "^5.5.0",
     "echarts-gl": "^2.0.9",
     "echarts-wordcloud": "^2.1.0",
     "element-plus": "^2.4.3",
@@ -47,6 +49,7 @@
     "vue": "^3.3.4",
     "vue-clipboard3": "^2.0.0",
     "vue-demi": "^0.14.5",
+    "vue-echarts": "^6.7.3",
     "vue-grid-layout": "^3.0.0-beta1",
     "vue-i18n": "^9.2.2",
     "vue-router": "^4.2.2"

+ 1 - 1
admin.ui.plus-master/src/App.vue

@@ -10,7 +10,7 @@
 
 <script setup lang="ts" name="app">
 import { defineAsyncComponent, computed, ref, onBeforeMount, onMounted, onUnmounted, nextTick, watch } from 'vue'
-import { useRoute } from 'vue-router'
+import { useRoute,createRouter, createWebHistory } from 'vue-router'
 import { useI18n } from 'vue-i18n'
 import { storeToRefs } from 'pinia'
 import { useTagsViewRoutes } from '/@/stores/tagsViewRoutes'

+ 3 - 1
admin.ui.plus-master/src/api/admin/deviceAuthorization/softwarePackageManagementDto.ts

@@ -55,7 +55,9 @@ export  interface softwarePackageManagement_TableData{
   /**下载地址*/
   downloadUrl?: string | null
   /**文件名*/
-  fileName?: string | null
+  fileName?: string | null,
+  /**数字签名*/
+  digitalSignature?: string | null,
 }
 
 /**

+ 3 - 1
admin.ui.plus-master/src/api/admin/productionManagement/ComponentDetailsDto.ts

@@ -70,7 +70,9 @@ export interface goodsInformationBasic {
   /**检测时间*/
   detectionEmployee: string,
   /**图片*/
-  img: string
+  img: string,
+  /**条码 */
+  barCode:string,
 }
 
 

+ 2 - 1
admin.ui.plus-master/src/api/admin/productionManagement/groupLogoKeyDto.ts

@@ -15,7 +15,8 @@ export interface groupLogoKeyFilterModel {
   applicationTime?: string | null,
   recordTime?: string | null ,
   remark?: string | null,
-  deviceType?: string | null
+  deviceType?: string | null,
+  manufacturer?: string | null
 }
 
 export interface groupLogoKeyRequestBody {

BIN
admin.ui.plus-master/src/assets/deviceVision/center_map.png


BIN
admin.ui.plus-master/src/assets/deviceVision/frame.png


BIN
admin.ui.plus-master/src/assets/deviceVision/guang.png


BIN
admin.ui.plus-master/src/assets/deviceVision/headers/juxing1.png


BIN
admin.ui.plus-master/src/assets/deviceVision/headers/juxing2.png


BIN
admin.ui.plus-master/src/assets/deviceVision/left_top_hong.png


BIN
admin.ui.plus-master/src/assets/deviceVision/left_top_huang.png


BIN
admin.ui.plus-master/src/assets/deviceVision/left_top_lan.png


BIN
admin.ui.plus-master/src/assets/deviceVision/left_top_lv.png


BIN
admin.ui.plus-master/src/assets/deviceVision/pageBg.png


BIN
admin.ui.plus-master/src/assets/deviceVision/titles/you.png


BIN
admin.ui.plus-master/src/assets/deviceVision/titles/zuo.png


BIN
admin.ui.plus-master/src/assets/deviceVision/top.png


BIN
admin.ui.plus-master/src/assets/deviceVision/xieyou.png


BIN
admin.ui.plus-master/src/assets/deviceVision/xiezuo.png


BIN
admin.ui.plus-master/src/assets/deviceVision/zuo_xuxian.png


+ 65 - 0
admin.ui.plus-master/src/components/echart/index.vue

@@ -0,0 +1,65 @@
+<template>  
+    <div ref="chartRef" :class="className" :style="{ height: height, width: width }"></div>  
+  </template>  
+    
+  <script>  
+  import { onMounted, onUnmounted, ref, watch, toRefs } from 'vue';  
+  import * as echarts from 'echarts';  
+    
+  export default {  
+    name: 'EChart',  
+    props: {  
+      className: {  
+        type: String,  
+        default: 'chart'  
+      },  
+      width: {  
+        type: String,  
+        default: '100%'  
+      },  
+      height: {  
+        type: String,  
+        default: '400px'  
+      },  
+      options: {  
+        type: Object,  
+        default: () => ({})  
+      }  
+    },  
+    setup(props) {  
+      const { className, width, height, options } = toRefs(props);  
+      const chartRef = ref(null);  
+      let chartInstance = null;  
+    
+      onMounted(() => {  
+        if (chartRef.value) {  
+          chartInstance = echarts.init(chartRef.value);  
+          chartInstance.setOption(options.value, true);  
+        }  
+      });  
+    
+      watch(options, (newOptions) => {  
+        if (chartInstance) {  
+          chartInstance.setOption(newOptions, true);  
+        }  
+      }, { deep: true });  
+    
+      onUnmounted(() => {  
+        if (chartInstance) {  
+          chartInstance.dispose();  
+        }  
+      });  
+    
+      return {  
+        chartRef  
+      };  
+    }  
+  };  
+  </script>  
+    
+  <style scoped>  
+  /* 添加一些样式 */  
+  .chart {  
+    /* ... */  
+  }  
+  </style>

+ 97 - 0
admin.ui.plus-master/src/components/item-wrap/item-wrap.vue

@@ -0,0 +1,97 @@
+<!--
+ * @Author: daidai
+ * @Date: 2022-03-01 09:16:22
+ * @LastEditors: Please set LastEditors
+ * @LastEditTime: 2022-09-29 15:12:34
+ * @FilePath: \web-pc\src\pages\big-screen\components\item-wrap\item-wrap.vue
+-->
+<template>
+    <dv-border-box-13 class="lr_titles">
+      <div class="item_title" v-if="title !== ''">
+        <div class="zuo"></div>
+        <span class="title-inner"> &nbsp;&nbsp;{{ title }}&nbsp;&nbsp; </span>
+        <div class="you"></div>
+      </div>
+      <div
+        :class="title !== '' ? 'item_title_content' : 'item_title_content_def'"
+      >
+        <slot></slot>
+      </div>
+    </dv-border-box-13>
+  </template>
+  
+  <script>
+  export default {
+    data() {
+      return {};
+    },
+    props: {
+      title: {
+        type: String,
+        default: () => "",
+      },
+    },
+    created() {},
+  
+    mounted() {},
+    methods: {},
+  };
+  </script>
+  <style lang='scss' scoped>
+  $item-title-height: 38px;
+  $item_title_content-height: calc(100% - 38px);
+  
+  .lr_titles {
+    box-sizing: border-box;
+  
+  :deep(.border-box-content)  {
+      box-sizing: border-box;
+      padding: 6px 16px 0px;
+    }
+  
+    .item_title {
+      height: $item-title-height;
+      line-height: $item-title-height;
+      width: 100%;
+      color: #31abe3;
+      text-align: center;
+      // background: linear-gradient(to right, transparent, #0f0756, transparent);
+      position: relative;
+      display: flex;
+      align-items: center;
+      justify-content: center;
+  
+      .zuo,
+      .you {
+        width: 58px;
+        height: 14px;
+        background-image: url("../../assets/deviceVision/titles/zuo.png");
+      }
+  
+      .you {
+        transform: rotate(180deg);
+      }
+      .title-inner {
+        font-weight: 900;
+        letter-spacing: 2px;
+        background: linear-gradient(
+          92deg,
+          #0072ff 0%,
+          #00eaff 48.8525390625%,
+          #01aaff 100%
+        );
+        -webkit-background-clip: text;
+        -webkit-text-fill-color: transparent;
+      }
+    }
+  
+    .item_title_content {
+      height: $item_title_content-height;
+    }
+  
+    .item_title_content_def {
+      width: 100%;
+      height: 100%;
+    }
+  }
+  </style>

+ 4 - 1
admin.ui.plus-master/src/main.ts

@@ -10,10 +10,13 @@ import ElementPlus from 'element-plus'
 import '/@/theme/index.scss'
 import VueGridLayout from 'vue-grid-layout'
 import globalProperties from '/@/globalProperties'
+import ECharts   from '/@/components/echart/index.vue'
+import DataVVue3 from '@kjgl77/datav-vue3'
 
 const app = createApp(App)
 
 directive(app)
 other.elSvg(app)
 
-app.use(pinia).use(router).use(ElementPlus).use(i18n).use(VueGridLayout).use(globalProperties).mount('#app')
+app.use(pinia).use(router).use(ElementPlus).use(i18n).use(VueGridLayout).use(DataVVue3)
+.use(globalProperties).mount('#app')

+ 59 - 0
admin.ui.plus-master/src/utils/deviceVision.js

@@ -0,0 +1,59 @@
+/*
+ * @Author: daidai
+ * @Date: 2022-02-23 08:59:26
+ * @LastEditors: daidai
+ * @LastEditTime: 2022-02-24 17:11:58
+ * @FilePath: \big-screen-vue-datav\src\utils\index.js
+ */
+
+/**
+ * @param {Function} fn 防抖函数
+ * @param {Number} delay 延迟时间
+ */
+export function debounce(fn, delay) {
+    var timer;
+    return function () {
+      var context = this;
+      var args = arguments;
+      clearTimeout(timer);
+      timer = setTimeout(function () {
+        fn.apply(context, args);
+      }, delay);
+    };
+  }
+  /**
+   * @param {date} time 需要转换的时间
+   * @param {String} fmt 需要转换的格式 如 yyyy-MM-dd、yyyy-MM-dd HH:mm:ss
+   */
+  export function formatTime(time, fmt) {
+    if (!time) return '';
+    else {
+      const date = new Date(time);
+      const o = {
+        'M+': date.getMonth() + 1,
+        'd+': date.getDate(),
+        'H+': date.getHours(),
+        'm+': date.getMinutes(),
+        's+': date.getSeconds(),
+        'q+': Math.floor((date.getMonth() + 3) / 3),
+        S: date.getMilliseconds(),
+      };
+      if (/(y+)/.test(fmt))
+        fmt = fmt.replace(
+          RegExp.$1,
+          (date.getFullYear() + '').substr(4 - RegExp.$1.length)
+        );
+      for (const k in o) {
+        if (new RegExp('(' + k + ')').test(fmt)) {
+          fmt = fmt.replace(
+            RegExp.$1,
+            RegExp.$1.length === 1
+              ? o[k]
+              : ('00' + o[k]).substr(('' + o[k]).length)
+          );
+        }
+      }
+      return fmt;
+    }
+  }
+  

Rozdielové dáta súboru neboli zobrazené, pretože súbor je príliš veľký
+ 0 - 0
admin.ui.plus-master/src/utils/map/china.json


+ 217 - 0
admin.ui.plus-master/src/utils/map/xzqCode.js

@@ -0,0 +1,217 @@
+/*
+ * @Author: daidai
+ * @Date: 2022-03-02 09:51:44
+ * @LastEditors: daidai
+ * @LastEditTime: 2022-03-02 09:51:45
+ * @FilePath: \web-pc\src\pages\big-screen\utils\map\xzqCode.js
+ */
+   //获取中国行政区 code
+//    AMap.plugin("AMap.DistrictSearch", function () {
+//     var districtSearch = new AMap.DistrictSearch({
+//       // 关键字对应的行政区级别,country表示国家
+//       level: "country",
+//       //  显示下级行政区级数,1表示返回下一级行政区
+//       subdistrict: 1,
+//     });
+//     let xzqCode = {};
+//     // 搜索所有省/直辖市信息
+//     districtSearch.search("中国", function (status, result) {
+//       // console.log(result);
+//       result.districtList[0].districtList.forEach((item) => {
+//         // console.log(item);
+//         xzqCode[item.name] = {
+//           adcode: item.adcode,
+//           level: item.level,
+//           name: item.name,
+//         };
+//       });
+//     });
+//     xzqCode["中国"] = {
+//       adcode: "100000",
+//       level: "country",
+//       name: "中华人民共和国",
+//     };
+//     setTimeout(() => {
+//     console.log(JSON.stringify(xzqCode),);
+
+//     }, 1000);
+//   });
+
+
+export default {
+    "中国": {
+        "adcode": "100000",
+        "level": "country",
+        "name": "中华人民共和国"
+    },
+    "新疆维吾尔自治区": {
+        "adcode": "650000",
+        "level": "province",
+        "name": "新疆维吾尔自治区"
+    },
+    "湖北省": {
+        "adcode": "420000",
+        "level": "province",
+        "name": "湖北省"
+    },
+    "辽宁省": {
+        "adcode": "210000",
+        "level": "province",
+        "name": "辽宁省"
+    },
+    "广东省": {
+        "adcode": "440000",
+        "level": "province",
+        "name": "广东省"
+    },
+    "内蒙古自治区": {
+        "adcode": "150000",
+        "level": "province",
+        "name": "内蒙古自治区"
+    },
+    "黑龙江省": {
+        "adcode": "230000",
+        "level": "province",
+        "name": "黑龙江省"
+    },
+    "河南省": {
+        "adcode": "410000",
+        "level": "province",
+        "name": "河南省"
+    },
+    "山东省": {
+        "adcode": "370000",
+        "level": "province",
+        "name": "山东省"
+    },
+    "陕西省": {
+        "adcode": "610000",
+        "level": "province",
+        "name": "陕西省"
+    },
+    "贵州省": {
+        "adcode": "520000",
+        "level": "province",
+        "name": "贵州省"
+    },
+    "上海市": {
+        "adcode": "310000",
+        "level": "province",
+        "name": "上海市"
+    },
+    "重庆市": {
+        "adcode": "500000",
+        "level": "province",
+        "name": "重庆市"
+    },
+    "西藏自治区": {
+        "adcode": "540000",
+        "level": "province",
+        "name": "西藏自治区"
+    },
+    "安徽省": {
+        "adcode": "340000",
+        "level": "province",
+        "name": "安徽省"
+    },
+    "福建省": {
+        "adcode": "350000",
+        "level": "province",
+        "name": "福建省"
+    },
+    "湖南省": {
+        "adcode": "430000",
+        "level": "province",
+        "name": "湖南省"
+    },
+    "海南省": {
+        "adcode": "460000",
+        "level": "province",
+        "name": "海南省"
+    },
+    "江苏省": {
+        "adcode": "320000",
+        "level": "province",
+        "name": "江苏省"
+    },
+    "青海省": {
+        "adcode": "630000",
+        "level": "province",
+        "name": "青海省"
+    },
+    "广西壮族自治区": {
+        "adcode": "450000",
+        "level": "province",
+        "name": "广西壮族自治区"
+    },
+    "宁夏回族自治区": {
+        "adcode": "640000",
+        "level": "province",
+        "name": "宁夏回族自治区"
+    },
+    "浙江省": {
+        "adcode": "330000",
+        "level": "province",
+        "name": "浙江省"
+    },
+    "河北省": {
+        "adcode": "130000",
+        "level": "province",
+        "name": "河北省"
+    },
+    "香港特别行政区": {
+        "adcode": "810000",
+        "level": "province",
+        "name": "香港特别行政区"
+    },
+    "台湾省": {
+        "adcode": "710000",
+        "level": "province",
+        "name": "台湾省"
+    },
+    "澳门特别行政区": {
+        "adcode": "820000",
+        "level": "province",
+        "name": "澳门特别行政区"
+    },
+    "甘肃省": {
+        "adcode": "620000",
+        "level": "province",
+        "name": "甘肃省"
+    },
+    "四川省": {
+        "adcode": "510000",
+        "level": "province",
+        "name": "四川省"
+    },
+    "天津市": {
+        "adcode": "120000",
+        "level": "province",
+        "name": "天津市"
+    },
+    "江西省": {
+        "adcode": "360000",
+        "level": "province",
+        "name": "江西省"
+    },
+    "云南省": {
+        "adcode": "530000",
+        "level": "province",
+        "name": "云南省"
+    },
+    "山西省": {
+        "adcode": "140000",
+        "level": "province",
+        "name": "山西省"
+    },
+    "北京市": {
+        "adcode": "110000",
+        "level": "province",
+        "name": "北京市"
+    },
+    "吉林省": {
+        "adcode": "220000",
+        "level": "province",
+        "name": "吉林省"
+    }
+}

+ 233 - 0
admin.ui.plus-master/src/utils/mock.js

@@ -0,0 +1,233 @@
+import Mock from 'mockjs'
+//延时200-600毫秒请求到数据
+Mock.setup({
+    timeout: '200-600'
+})
+
+const Random = Mock.Random;
+// 用户总览
+function countUserNum() {
+    const a = Mock.mock({
+        success: true,
+        data: {
+            offlineNum:'@integer(1, 100)',
+            lockNum: '@integer(1, 10)',
+            totalNum:218
+        }
+    })
+    a.data.onlineNum=a.data.totalNum-a.data.offlineNum-a.data.lockNum
+    return a
+}
+
+// 接口,第一个参数url,第二个参数请求类型,第三个参数响应回调
+Mock.mock(new RegExp('countUserNum'), 'get', countUserNum)
+
+// /设备总览 
+
+function countDeviceNum() {
+    const a = Mock.mock({
+        success: true,
+        data: {
+            alarmNum: '@integer(100, 1000)',
+            offlineNum: '@integer(0, 50)',
+            totalNum:698
+        }
+    })
+    a.data.onlineNum=a.data.totalNum-a.data.offlineNum
+
+
+    return a
+}
+
+Mock.mock(new RegExp('countDeviceNum'), 'get', countDeviceNum)
+
+// /设备总览 
+
+function sbtx() {
+    const a = Mock.mock({
+        success: true,
+        data: {
+            "list|20": [
+                {
+                    provinceName: "@province()",
+                    cityName: '@city()',
+                    countyName: "@county()",
+                    createTime: "@datetime('yyyy-MM-dd HH:mm:ss')",
+                    deviceId: "6c512d754bbcd6d7cd86abce0e0cac58",
+                    "gatewayno|+1": 10000,
+                    "onlineState|1": [0, 1],
+
+                }
+            ]
+        }
+    })
+    return a
+}
+
+Mock.mock(new RegExp('sbtx'), 'get', sbtx)
+
+
+
+//中间地图
+
+function centermap(options) {
+    let params = parameteUrl(options.url)
+    if (params.regionCode && params.regionCode != 'china') {
+        const a = Mock.mock({
+            success: true,
+            data: {
+                "dataList|30": [
+                    {
+                        name: "@city()",
+                        value: '@integer(1, 1000)'
+                    }
+                ],
+                regionCode: params.regionCode,//-代表中国
+            }
+        })
+        return a
+    } else {
+        const a = Mock.mock({
+            success: true,
+            data: {
+                "dataList|8": [
+                    {
+                        name: "@province()",
+                        value: '@integer(1, 1000)'
+                    }
+                ],
+                regionCode: 'china',
+            }
+        })
+        return a
+    }
+
+}
+
+Mock.mock(new RegExp('centermap'), 'get', centermap)
+
+// 报警次数
+
+function alarmNum() {
+    const a = Mock.mock({
+        success: true,
+        data: {
+            dateList:['2021-11', '2021-12', '2022-01', '2022-02', '2022-03',"2022-04"],
+            "numList|6":[
+                '@integer(0, 1000)'
+            ],
+            "numList2|6":[
+                '@integer(0, 1000)'
+            ]
+        }
+    })
+    return a
+}
+Mock.mock(new RegExp('alarmNum'), 'get', alarmNum)
+
+// 实时预警
+
+function ssyj() {
+    const a = Mock.mock({
+        success: true,
+        data: {
+            "list|40":[{
+                alertdetail: "@csentence(5,10)",
+                "alertname|1": ["水浸告警","各种报警"],
+                alertvalue: "@float(60, 200)",
+                createtime: "2022-04-19 08:38:33",
+                deviceid: null,
+                "gatewayno|+1": 10000,
+                phase: "A1",
+                sbInfo: "@csentence(10,18)",
+                "terminalno|+1": 100,
+                provinceName: "@province()",
+                cityName: '@city()',
+                countyName: "@county()",
+            }],
+            
+        }
+    })
+    return a
+}
+Mock.mock(new RegExp('ssyj'), 'get', ssyj)
+//安装计划 
+function installationPlan() {
+    let num=  RandomNumBoth(26,32);
+    const a = Mock.mock({
+        ["category|"+num]:["@city()"],
+        ["barData|"+num]:["@integer(10, 100)"],
+    })
+    let lineData=[],rateData=[];
+    for (let index = 0; index < num; index++) {
+        let lineNum = Mock.mock('@integer(0, 100)')+a.barData[index]
+        lineData.push(lineNum)
+        let rate = a.barData[index] / lineNum;
+        rateData.push((rate*100).toFixed(0))
+    }
+    a.lineData=lineData
+    a.rateData=rateData
+    return {
+        success: true,
+        data:a
+    }
+}
+Mock.mock(new RegExp('installationPlan'), 'get', installationPlan)
+
+
+
+
+//报警排名 
+function ranking() {
+   //多生成几个避免重复 重复会报错
+  let num =Mock.mock({"list|48":[{ value:"@integer(50,1000)",name:"@city()"}]}).list
+//   console.log(num);
+  let newNum =[],numObj={}
+  num.map(item=>{
+    if(!numObj[item.name] && newNum.length<8){
+        numObj[item.name] =true
+        newNum.push(item)
+    }
+  })
+  let arr = newNum.sort((a,b)=>{
+    return b.value-a.value
+  })
+  let a ={
+      success:true,
+      data:arr
+  }
+  return a
+}
+Mock.mock(new RegExp('ranking'), 'get', ranking)
+/**
+ * @description: min ≤ r ≤ max  随机数
+ * @param {*} Min
+ * @param {*} Max
+ * @return {*}
+ */
+function RandomNumBoth(Min,Max){
+    var Range = Max - Min;
+    var Rand = Math.random();
+    var num = Min + Math.round(Rand * Range); //四舍五入
+    return num;
+}
+/**
+ * @description: 获取路径参数
+ * @param {*} url
+ * @return {*}
+ */
+function parameteUrl(url) {
+    var json = {}
+    if (/\?/.test(url)) {
+        var urlString = url.substring(url.indexOf("?") + 1);
+        var urlArray = urlString.split("&");
+        for (var i = 0; i < urlArray.length; i++) {
+            var urlItem = urlArray[i];
+            var item = urlItem.split("=");
+            console.log(item);
+            json[item[0]] = item[1];
+        }
+        return json;
+    }
+    return {};
+}

+ 5 - 0
admin.ui.plus-master/src/views/admin/authorize/softwarePackageManagement/components/form-edit.vue

@@ -42,6 +42,11 @@
               <el-input v-model="formData.editData.remark" placeholder="请输入备注" rows="6" clearable type="textarea"></el-input>
             </el-form-item>
           </el-col>
+          <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
+            <el-form-item label="数字签名" prop="digitalSignature">
+              <el-input v-model="formData.editData.digitalSignature" placeholder="数字签名,TQC+、ECVR、OPW必填" clearable></el-input>
+            </el-form-item>
+          </el-col>
         </el-row>
         <MyUploadFile  v-model="formData.fileValue" ref="uploadFileRef" :file="{fileUrl:formData.editData.downloadUrl,fileName:formData.editData.fileName}"  @onUpload="onUpload"/>
       </el-form>

+ 1 - 0
admin.ui.plus-master/src/views/admin/authorize/softwarePackageManagement/index.vue

@@ -212,6 +212,7 @@ const softwareData = reactive({
     { prop: 'remark', label: '备注' },
     { prop: 'releaseTime', label: '发布日期' },
     { prop: 'uploadTime', label: '上传日期' },
+    { prop: 'digitalSignature', label: '数字签名' },
   ],
   /**分页标识 */
   pageInput:{

+ 14 - 1
admin.ui.plus-master/src/views/admin/product/goodInfo/index.vue

@@ -33,7 +33,7 @@
                   </template>
                 </el-popover>
               </div>
-              <div class="item">
+              <!-- <div class="item">
                 <el-popover
                   placement="top-start"
                   :width="200"
@@ -45,6 +45,19 @@
                     <span class="m-2"> CPUID: {{goods.basicInformation.cpuId}}</span>
                   </template>
                 </el-popover>
+              </div> -->
+              <div class="item">
+                <el-popover
+                  placement="top-start"
+                  :width="200"
+                  title="条码"
+                  trigger="hover"
+                  :content="goods.basicInformation.barCode"
+                >
+                  <template #reference>
+                    <span class="m-2"> 条码: {{goods.basicInformation.barCode}}</span>
+                  </template>
+                </el-popover>
               </div>
               <div class="item">
                 <el-popover

+ 8 - 1
admin.ui.plus-master/src/views/admin/product/groupLogo/index.vue

@@ -24,6 +24,11 @@
                   </el-select>
                 </el-form-item>
               </el-col>
+              <el-col :xs="24" :sm="12" :md="8" :lg="8" :xl="4" class="mb20">
+                <el-form-item label="厂商">
+                  <el-input v-model="groupLogoKeyOnQuery.filter.manufacturer" placeholder="请输入厂商" clearable></el-input>
+                </el-form-item>
+              </el-col>
               <el-col :xs="24" :sm="12" :md="8" :lg="8" :xl="4" class="mb20">
                 <el-form-item>
                   <el-button type="primary" icon="ele-Search" @click="onQuery"> 查询 </el-button>
@@ -48,10 +53,12 @@
                 {{ getDeviceType(row.deviceType).name}}
               </template>
             </el-table-column>
-            <el-table-column prop="remark" label="备注"  />
+          
             <el-table-column prop="lastUpdate" label="最近同步时间" />
             <el-table-column prop="applicationTime" label="申请时间" />
             <el-table-column prop="recordTime" label="备案时间" />
+            <el-table-column prop="manufacturer" label="厂商" />
+            <el-table-column prop="remark" label="备注"  />
           </el-table>
           <div class="my-flex my-flex-end" style="margin-top: 20px">
             <el-pagination

+ 9 - 2
admin.ui.plus-master/src/views/admin/product/record/index.vue

@@ -36,6 +36,12 @@
                 </el-form-item>
               </el-col>
 
+              <el-col :xs="24" :sm="12" :md="8" :lg="8" :xl="6" class="mb20">
+                <el-form-item label="条码">
+                  <el-input v-model="bomModel.filterModel.barcode" placeholder="条码" clearable></el-input>
+                </el-form-item>
+              </el-col>
+
               <el-col :xs="24" :sm="12" :md="8" :lg="8" :xl="6" class="mb20">
                 <el-form-item>
                   <el-button type="primary" icon="ele-Search" @click="onQuery"> 查询 </el-button>
@@ -58,7 +64,7 @@
             <el-table-column prop="bomName" label="部件名称"  />
             <el-table-column prop="bomNo" label="物料号"  />
             <el-table-column prop="bomProNo" label="生产编号"  />
-            <el-table-column prop="cpuId" label="CPUID"  />
+            <el-table-column prop="barCode" label="条码"  />
             <el-table-column prop="software_v" label="软件版本"  />
             <el-table-column prop="status"  label="状态" width="120" >
               <template #default="{ row }">
@@ -200,7 +206,8 @@ const bomModel = reactive({
     bomName: '',
     bomProNo: '',
     bomMateNo: '',
-    manufacturer:''
+    manufacturer:'',
+    barcode:''
   },
   total: 0,
   pageInput: {

+ 83 - 0
admin.ui.plus-master/src/views/admin/visualization/KeyWatchMonitoring/index.vue

@@ -0,0 +1,83 @@
+<!--
+ * @Author: daidai
+ * @Date: 2022-01-12 14:23:32
+ * @LastEditors: Please set LastEditors
+ * @LastEditTime: 2022-09-09 14:47:24
+ * @FilePath: \web-pc\src\pages\big-screen\view\home.vue
+-->
+<template>
+   
+    <div class="iframe-container">  
+     <iframe :src="iframeUrl" frameborder="0" class="fill-container"></iframe>  
+   </div> 
+   </template>
+ 
+ <script>
+ //import { formatTime } from "../../../../utils/deviceVision.js";
+ 
+ export default {
+
+   data() {
+     return {
+       timing: null,
+       loading: true,
+       dateDay: null,
+       dateYear: null,
+       dateWeek: null,
+       weekday: ["周日", "周一", "周二", "周三", "周四", "周五", "周六"],
+       iframeUrl:"http://47.101.220.106:8012/"
+     };
+   },
+   filters: {
+     numsFilter(msg) {
+       return msg || 0;
+     },
+   },
+   computed: {},
+   created() {},
+   mounted() {
+     this.timeFn();
+     this.cancelLoading();
+   },
+   beforeDestroy() {
+     clearInterval(this.timing);
+   },
+   methods: {
+     timeFn() {
+       this.timing = setInterval(() => {
+         //this.dateDay = formatTime(new Date(), "HH: mm: ss");
+         //this.dateYear = formatTime(new Date(), "yyyy-MM-dd");
+         this.dateWeek = this.weekday[new Date().getDay()];
+       }, 1000);
+     },
+     cancelLoading() {
+       let timer = setTimeout(() => {
+         this.loading = false;
+         clearTimeout(timer);
+       }, 500);
+     },
+   },
+ };
+ </script>
+ 
+ 
+ <style scoped>  
+ .iframe-container {  
+   /* 根据需要设置容器的样式 */  
+   width: 100%; /* 如果需要的话,设置容器的宽度 */  
+   height: 100vh; /* 设置容器的高度为视口高度的100% */  
+   /* 注意:如果有其他元素在页面上,你可能需要调整这个值 */  
+   display: flex; /* 使用Flexbox来确保iframe填充整个容器 */  
+   justify-content: center; /* 水平居中iframe(如果需要的话) */  
+   align-items: stretch; /* 垂直方向也尝试填充(但iframe内容可能不会响应) */  
+   overflow: hidden; /* 隐藏超出容器的iframe内容(如果需要的话) */  
+   position: relative; /* 如果需要绝对定位iframe或其他子元素 */  
+ }  
+   
+ .fill-container {  
+   width: 100%; /* 填充容器的宽度 */  
+   height: 100%; /* 填充容器的高度 */  
+   border: none; /* 移除边框(如果需要的话) */  
+   display: block; /* 确保iframe是块级元素 */  
+ }  
+ </style>

+ 261 - 0
admin.ui.plus-master/src/views/admin/visualization/deviceVision/index.scss

@@ -0,0 +1,261 @@
+.scale-wrap {
+    color: #d3d6dd;
+    width: 1920px;
+    height: 1080px;
+    overflow: hidden;
+    // &.pageisScale {
+    //     position: absolute;
+    //     top: 50%;
+    //     left: 50%;
+    //     transform: translate(-50%, -50%);
+    //     transform-origin: left top;
+    // }
+    .bg {
+        width: 100%;
+        height: 100%;
+        padding: 16px 16px 10px 16px;
+        box-sizing: border-box;
+        background-image: url("../../../../assets/deviceVision/pageBg.png");
+        background-size: cover;
+        background-position: center center;
+    }
+
+    .host-body {
+        height: 100%;
+
+        .title_wrap {
+            height: 60px;
+            background-image: url("../../../../assets/deviceVision/top.png");
+            background-size: cover;
+            background-position: center center;
+            position: relative;
+            margin-bottom: 4px;
+
+            .guang {
+                position: absolute;
+                bottom: -26px;
+                background-image: url("../../../../assets/deviceVision/guang.png");
+                background-position: 80px center;
+                width: 100%;
+                height: 56px;
+            }
+
+            .zuojuxing,
+            .youjuxing {
+                position: absolute;
+                top: -2px;
+                width: 140px;
+                height: 6px;
+                background-image: url("../../../../assets/deviceVision/headers/juxing1.png");
+            }
+
+            .zuojuxing {
+
+                left: 11%;
+            }
+
+            .youjuxing {
+                right: 11%;
+                transform: rotate(180deg);
+            }
+
+            .timers {
+                position: absolute;
+                right: 0;
+                top: 30px;
+                font-size: 18px;
+                display: flex;
+                align-items: center;
+
+                .blq-icon-shezhi02 {
+                    cursor: pointer;
+                }
+            }
+        }
+
+        .title {
+            position: relative;
+            // width: 500px;
+            text-align: center;
+            background-size: cover;
+            color: transparent;
+            height: 60px;
+            line-height: 46px;
+
+            .title-text {
+                font-size: 38px;
+                font-weight: 900;
+                letter-spacing: 6px;
+                width: 100%;
+                background: linear-gradient(92deg, #0072FF 0%, #00EAFF 48.8525390625%, #01AAFF 100%);
+                -webkit-background-clip: text;
+                -webkit-text-fill-color: transparent;
+            }
+        }
+    }
+
+
+}
+
+.scale-wrap {
+    .pagetab {
+        position: absolute;
+        top: -35px;
+        display: flex;
+
+        .item {
+            width: 130px;
+            height: 36px;
+            border-radius: 18px 0px 0px 18px;
+            color: #00FBF8;
+            text-indent: 26px;
+            line-height: 36px;
+            font-size: 16px;
+            margin-right: 20px;
+            background: linear-gradient(to right, rgba(76, 245, 255, .5), rgba(76, 245, 255, 0));
+        }
+    }
+}
+
+.setting {
+    position: fixed;
+    width: 100%;
+    height: 100%;
+    z-index: 999;
+    top: 0;
+    left: 0;
+
+    .left_shu {
+        color: #000;
+        font-weight: 900;
+        position: relative;
+        text-indent: 10px;
+        padding:16px 0 10px 0 ;
+        &::before {
+            display: block;
+            content: " ";
+            height: 16px;
+            width: 4px;
+            border-radius: 2px;
+            background: #0072FF;
+            position: absolute;
+            left: 0px;
+        }
+    }
+
+    .setting_dislog {
+        background-color: rgba($color: #000000, $alpha: .5);
+        position: absolute;
+        width: 100%;
+        height: 100%;
+        z-index: 0;
+        right: 0;
+        top: 0;
+    }
+
+    .setting_inner {
+        box-sizing: border-box;
+        background: #FFF;
+        width: 340px;
+        height: 100%;
+        position: absolute;
+        right: 0px;
+        top: 0;
+        z-index: 1;
+        color: #000000;
+        box-shadow: 0 8px 10px -5px rgba(0, 0, 0, .2), 0 16px 24px 2px rgba(0, 0, 0, .14), 0 6px 30px 5px rgba(0, 0, 0, .12);
+
+        .setting_header {
+            font-size: 20px;
+            color: rgb(0, 0, 0);
+            font-weight: 900;
+            text-align: center;
+            line-height: 40px;
+        }
+
+        .setting_body {
+            padding: 0px 16px;
+            box-sizing: border-box;
+            position: relative;
+        }
+
+        .setting_item {
+            font-size: 14px;
+            line-height: 1.5;
+
+            // display: flex;
+            .setting_label {
+                color: #555454;
+            }
+            .setting_label_tip{
+                font-size: 12px;
+                color: #838282;
+            }
+        }
+    }
+
+    .setting_inner {
+        animation: rtl-drawer-out .3s;
+    }
+}
+
+
+.settingShow {
+    .setting_inner {
+        animation: rtl-drawer-in .3s 1ms;
+    }
+
+}
+
+.yh-setting-fade-enter-active {
+    animation: yh-setting-fade-in .3s;
+}
+
+.yh-setting-fade-leave-active {
+
+    animation: yh-setting-fade-out .3s;
+
+}
+
+@keyframes yh-setting-fade-in {
+    0% {
+        opacity: 0;
+    }
+
+    100% {
+        opacity: 1;
+    }
+}
+
+@keyframes yh-setting-fade-out {
+    0% {
+        opacity: 1;
+
+    }
+
+    100% {
+        opacity: 0;
+    }
+}
+
+
+@keyframes rtl-drawer-in {
+    0% {
+        transform: translate(100%, 0)
+    }
+
+    100% {
+        -webkit-transform: translate(0, 0);
+        transform: translate(0, 0)
+    }
+}
+
+@keyframes rtl-drawer-out {
+    0% {
+        transform: translate(0, 0)
+    }
+
+    100% {
+        transform: translate(100%, 0)
+    }
+}

+ 105 - 0
admin.ui.plus-master/src/views/admin/visualization/deviceVision/index.vue

@@ -0,0 +1,105 @@
+<!--
+ * @Author: daidai
+ * @Date: 2022-01-12 14:23:32
+ * @LastEditors: Please set LastEditors
+ * @LastEditTime: 2022-09-09 14:47:24
+ * @FilePath: \web-pc\src\pages\big-screen\view\home.vue
+-->
+<template>
+   
+  <!-- <div id="index" ref="appRef" class="index_home" :class="{ pageisScale: isScale }"> -->
+  <ScaleScreen
+    :width="1920"
+    :height="1080"
+    class="scale-wrap"
+    :selfAdaption="true"
+  >
+    <div class="bg">
+      <dv-loading v-if="loading">Loading...</dv-loading>
+    <div v-else class="host-body">
+      <!-- 头部 s -->
+      <div class="d-flex jc-center title_wrap">
+        <div class="zuojuxing"></div>
+        <div class="youjuxing"></div>
+        <div class="guang"></div>
+        <div class="d-flex jc-center">
+          <div class="title">
+            <span class="title-text">设备可视化平台</span>
+          </div>
+        </div>
+        <div class="timers">
+          {{ dateYear }} {{ dateWeek }} {{ dateDay }}
+          <i
+            class="blq-icon-shezhi02"
+            style="margin-left: 10px"
+            @click="showSetting"
+          ></i>
+        </div>
+      </div>
+      <!-- 头部 e-->
+      <!-- 内容  s-->
+      <index />
+      <!-- 内容 e -->
+    </div>
+    </div>
+    <Setting ref="setting" />
+  </ScaleScreen>
+  <!-- </div> -->
+</template>
+
+<script>
+//import { formatTime } from "../../../../utils/deviceVision.js";
+import Setting from "./setting.vue";
+import ScaleScreen from "./scale-screen.vue";
+import index from "./indexs/index.vue";
+export default {
+components: { Setting, ScaleScreen ,index},
+data() {
+  return {
+    timing: null,
+    loading: true,
+    dateDay: null,
+    dateYear: null,
+    dateWeek: null,
+    weekday: ["周日", "周一", "周二", "周三", "周四", "周五", "周六"],
+  };
+},
+filters: {
+  numsFilter(msg) {
+    return msg || 0;
+  },
+},
+computed: {},
+created() {},
+mounted() {
+  this.timeFn();
+  this.cancelLoading();
+},
+beforeDestroy() {
+  clearInterval(this.timing);
+},
+methods: {
+  showSetting() {
+    this.$refs.setting.init();
+  },
+  timeFn() {
+    this.timing = setInterval(() => {
+      //this.dateDay = formatTime(new Date(), "HH: mm: ss");
+      //this.dateYear = formatTime(new Date(), "yyyy-MM-dd");
+      this.dateWeek = this.weekday[new Date().getDay()];
+    }, 1000);
+  },
+  cancelLoading() {
+    let timer = setTimeout(() => {
+      this.loading = false;
+      clearTimeout(timer);
+    }, 500);
+  },
+},
+};
+</script>
+
+
+<style lang="scss">
+@import "./index.scss";
+</style>

+ 189 - 0
admin.ui.plus-master/src/views/admin/visualization/deviceVision/indexs/center-bottom.vue

@@ -0,0 +1,189 @@
+<template>
+    <div class="center_bottom">
+      <Echart
+        :options="options"
+        id="bottomLeftChart"
+        class="echarts_bottom"
+      ></Echart>
+    </div>
+  </template>
+  
+  <script>
+  import { graphic } from "echarts";
+  import  Echart  from "../../../../../components/echart/index.vue";
+  //import * as graphic from "echarts";
+  export default {
+    components: { Echart},
+    data() {
+      return {
+        options: {},
+      };
+    },
+    props: {},
+    mounted() {
+      this.getData();
+    },
+    methods: {
+      getData() {
+        debugger
+        this.pageflag = true;
+      let json = {
+  success: true,
+  data: {
+    category: ["吉林市", "吉安市", "重庆市", "十堰市", "七台河市", "新界", "贺州市", "廊坊市", "天津市", "连江县", "本溪市", "上海市", "临沧市", "安顺市", "岳阳市", "哈尔滨市", "武威市", "四平市", "沈阳市", "铜仁市", "泉州市", "阿克苏地区", "内江市", "黔西南布依族苗族自治州", "石嘴山市", "宁波市", "晋城市", "咸宁市", "甘南藏族自治州", "福州市"],
+    barData: [25, 91, 17, 10, 58, 51, 12, 51, 94, 97, 68, 91, 65, 48, 90, 60, 19, 29, 75, 97, 55, 91, 44, 31, 42, 18, 91, 69, 91, 12],
+    lineData: [26, 161, 55, 63, 70, 145, 37, 61, 157, 106, 105, 159, 73, 52, 169, 133, 105, 103, 123, 174, 71, 103, 122, 97, 89, 26, 151, 154, 129, 45],
+    rateData: ["96", "57", "31", "16", "83", "35", "32", "84", "60", "92", "65", "57", "89", "92", "53", "45", "18", "28", "61", "56", "77", "88", "36", "32", "47", "69", "60", "45", "71", "27"]
+  }
+};
+this.init(json.data);
+this.pageflag = false;
+      },
+      init(newData) {
+        this.options = {
+          tooltip: {
+            trigger: "axis",
+            backgroundColor: "rgba(0,0,0,.6)",
+            borderColor: "rgba(147, 235, 248, .8)",
+            textStyle: {
+              color: "#FFF",
+            },
+            formatter: function (params) {
+              // 添加单位
+              var result = params[0].name + "<br>";
+              params.forEach(function (item) {
+                if (item.value) {
+                  if (item.seriesName == "安装率") {
+                    result +=
+                      item.marker +
+                      " " +
+                      item.seriesName +
+                      " : " +
+                      item.value +
+                      "%</br>";
+                  } else {
+                    result +=
+                      item.marker +
+                      " " +
+                      item.seriesName +
+                      " : " +
+                      item.value +
+                      "个</br>";
+                  }
+                } else {
+                  result += item.marker + " " + item.seriesName + " :  - </br>";
+                }
+              });
+              return result;
+            },
+          },
+          legend: {
+            data: ["已安装", "计划安装", "安装率"],
+            textStyle: {
+              color: "#B4B4B4",
+            },
+            top: "0",
+          },
+          grid: {
+            left: "50px",
+            right: "40px",
+            bottom: "30px",
+            top: "20px",
+          },
+          xAxis: {
+            data: newData.category,
+            axisLine: {
+              lineStyle: {
+                color: "#B4B4B4",
+              },
+            },
+            axisTick: {
+              show: false,
+            },
+          },
+          yAxis: [
+            {
+              splitLine: { show: false },
+              axisLine: {
+                lineStyle: {
+                  color: "#B4B4B4",
+                },
+              },
+  
+              axisLabel: {
+                formatter: "{value}",
+              },
+            },
+            {
+              splitLine: { show: false },
+              axisLine: {
+                lineStyle: {
+                  color: "#B4B4B4",
+                },
+              },
+              axisLabel: {
+                formatter: "{value}% ",
+              },
+            },
+          ],
+          series: [
+            {
+              name: "已安装",
+              type: "bar",
+              barWidth: 10,
+              itemStyle: {
+                borderRadius: 5,
+                color: new graphic.LinearGradient(0, 0, 0, 1, [
+                  { offset: 0, color: "#956FD4" },
+                  { offset: 1, color: "#3EACE5" },
+                ]),
+              },
+              data: newData.barData,
+            },
+            {
+              name: "计划安装",
+              type: "bar",
+              barGap: "-100%",
+              barWidth: 10,
+              itemStyle: {
+                borderRadius: 5,
+                color: new graphic.LinearGradient(0, 0, 0, 1, [
+                  { offset: 0, color: "rgba(156,107,211,0.8)" },
+                  { offset: 0.2, color: "rgba(156,107,211,0.5)" },
+                  { offset: 1, color: "rgba(156,107,211,0.2)" },
+                ]),
+              },
+              z: -12,
+              data: newData.lineData,
+            },
+            {
+              name: "安装率",
+              type: "line",
+              smooth: true,
+              showAllSymbol: true,
+              symbol: "emptyCircle",
+              symbolSize: 8,
+              yAxisIndex: 1,
+              itemStyle: {
+                color: "#F02FC2",
+              },
+              data: newData.rateData,
+            },
+          ],
+        };
+      },
+    },
+  };
+  </script>
+  <style lang="scss" scoped>
+  .center_bottom {
+    width: 100%;
+    height: 100%;
+  
+    .echarts_bottom {
+      width: 100%;
+      height: 100%;
+    }
+  }
+  </style>
+  

+ 385 - 0
admin.ui.plus-master/src/views/admin/visualization/deviceVision/indexs/center-map.vue

@@ -0,0 +1,385 @@
+<!--
+ * @Author: daidai
+ * @Date: 2022-03-01 11:17:39
+ * @LastEditors: Please set LastEditors
+ * @LastEditTime: 2022-09-29 15:50:18
+ * @FilePath: \web-pc\src\pages\big-screen\view\indexs\center-map.vue
+-->
+<template>
+    <div class="centermap">
+      <div class="maptitle">
+        <div class="zuo"></div>
+        <span class="titletext">{{ maptitle }}</span>
+        <div class="you"></div>
+      </div>
+      <div class="mapwrap">
+        <dv-border-box-13>
+          <div class="quanguo" @click="getData('china')" v-if="code !== 'china'">
+            中国
+          </div>
+  
+          <Echart id="CenterMap" :options="options" ref="CenterMap" />
+        </dv-border-box-13>
+      </div>
+    </div>
+  </template>
+  
+  <script>
+  import xzqCode from "../../../../../utils/map/xzqCode";
+  import * as echarts from "echarts";
+  import jsondata from '../../../../../utils/map/china.json'; // 如果你使用的是 ES6 语法  
+  export default {
+    data() {
+      return {
+        maptitle: "设备分布图",
+        options: {},
+        code: "china", //china 代表中国 其他地市是行政编码
+        echartBindClick: false,
+        isSouthChinaSea: false, //是否要展示南海群岛  修改此值请刷新页面
+      };
+    },
+    created() {},
+  
+    mounted() {
+      // console.log(xzqCode);
+      this.getData("china");
+    },
+    methods: {
+      getData(code) {
+        debugger
+      var fsdfsd  = jsondata;
+      const jsonString = '{"success":true,"data":{"dataList":[{"name":"澳门特别行政区","value":126},{"name":"吉林省","value":325},{"name":"江苏省","value":971},{"name":"福建省","value":279},{"name":"湖南省","value":15},{"name":"福建省","value":732},{"name":"宁夏回族自治区","value":63},{"name":"陕西省","value":983}],"regionCode":"china"}}';
+const jsonObject = JSON.parse(jsonString);
+this.getGeojson(jsonObject.data.regionCode, jsonObject.data.dataList);
+          this.mapclick();
+     /*  currentGET("big8", { regionCode: code }).then((res) => {
+        console.log("设备分布", JSON.stringify(res));
+        if (res.success) {
+          this.getGeojson(res.data.regionCode, res.data.dataList);
+          this.mapclick();
+        } else {
+          this.$Message.warning(res.msg);
+        }
+      }); */
+      },
+      /**
+       * @description: 获取geojson
+       * @param {*} name china 表示中国 其他省份行政区编码
+       * @param {*} mydata 接口返回列表数据
+       * @return {*}
+       */
+      async getGeojson(name, mydata) {
+        this.code = name;
+        //如果要展示南海群岛并且展示的是中国的话
+        let geoname=name
+        if (this.isSouthChinaSea && name == "china") {
+          geoname = "chinaNanhai";
+        }
+        //如果有注册地图的话就不用再注册 了
+        let mapjson = echarts.getMap(name);
+        if (mapjson) {
+          mapjson = mapjson.geoJSON;
+        } else {
+          /* mapjson = await GETNOBASE(`./map-geojson/${geoname}.json`).then((res) => {
+            return res;
+          }); */
+          mapjson = jsondata;
+          echarts.registerMap(name, mapjson);
+        }
+        let cityCenter = {};
+        let arr = mapjson.features;
+        //根据geojson获取省份中心点
+        arr.map((item) => {
+          cityCenter[item.properties.name] =
+            item.properties.centroid || item.properties.center;
+        });
+        let newData = [];
+        mydata.map((item) => {
+          if (cityCenter[item.name]) {
+            newData.push({
+              name: item.name,
+              value: cityCenter[item.name].concat(item.value),
+            });
+          }
+        });
+        this.init(name, mydata, newData);
+      },
+      init(name, data, data2) {
+        // console.log(data2);
+        let top = 45;
+        let zoom = 1.05;
+        let option = {
+          backgroundColor: "rgba(0,0,0,0)",
+          tooltip: {
+            show: false,
+          },
+          legend: {
+            show: false,
+          },
+          visualMap: {
+            left: 20,
+            bottom: 20,
+            pieces: [
+              { gte: 1000, label: "1000个以上" }, // 不指定 max,表示 max 为无限大(Infinity)。
+              { gte: 600, lte: 999, label: "600-999个" },
+              { gte: 200, lte: 599, label: "200-599个" },
+              { gte: 50, lte: 199, label: "49-199个" },
+              { gte: 10, lte: 49, label: "10-49个" },
+              { lte: 9, label: "1-9个" }, // 不指定 min,表示 min 为无限大(-Infinity)。
+            ],
+            inRange: {
+              // 渐变颜色,从小到大
+              color: [
+                "#c3d7df",
+                "#5cb3cc",
+                "#8abcd1",
+                "#66a9c9",
+                "#2f90b9",
+                "#1781b5",
+              ],
+            },
+            textStyle: {
+              color: "#fff",
+            },
+          },
+          geo: {
+            map: name,
+            roam: false,
+            selectedMode: false, //是否允许选中多个区域
+            zoom: zoom,
+            top: top,
+            // aspectScale: 0.78,
+            show: false,
+          },
+          series: [
+            {
+              name: "MAP",
+              type: "map",
+              map: name,
+              // aspectScale: 0.78,
+              data: data,
+              // data: [1,100],
+              selectedMode: false, //是否允许选中多个区域
+              zoom: zoom,
+              geoIndex: 1,
+              top: top,
+              tooltip: {
+                show: true,
+                formatter: function (params) {
+                  if (params.data) {
+                    return params.name + ":" + params.data["value"];
+                  } else {
+                    return params.name;
+                  }
+                },
+                backgroundColor: "rgba(0,0,0,.6)",
+                borderColor: "rgba(147, 235, 248, .8)",
+                textStyle: {
+                  color: "#FFF",
+                },
+              },
+              label: {
+                show: false,
+                color: "#000",
+                // position: [-10, 0],
+                formatter: function (val) {
+                  // console.log(val)
+                  if (val.data !== undefined) {
+                    return val.name.slice(0, 2);
+                  } else {
+                    return "";
+                  }
+                },
+                rich: {},
+              },
+              emphasis: {
+                label: {
+                  show: false,
+                },
+                itemStyle: {
+                  areaColor: "#389BB7",
+                  borderWidth: 1,
+                },
+              },
+              itemStyle: {
+                borderColor: "rgba(147, 235, 248, .8)",
+                borderWidth: 1,
+                areaColor: {
+                  type: "radial",
+                  x: 0.5,
+                  y: 0.5,
+                  r: 0.8,
+                  colorStops: [
+                    {
+                      offset: 0,
+                      color: "rgba(147, 235, 248, 0)", // 0% 处的颜色
+                    },
+                    {
+                      offset: 1,
+                      color: "rgba(147, 235, 248, .2)", // 100% 处的颜色
+                    },
+                  ],
+                  globalCoord: false, // 缺为 false
+                },
+                shadowColor: "rgba(128, 217, 248, .3)",
+                shadowOffsetX: -2,
+                shadowOffsetY: 2,
+                shadowBlur: 10,
+              },
+            },
+            {
+              data: data2,
+              type: "effectScatter",
+              coordinateSystem: "geo",
+              symbolSize: function (val) {
+                return 4;
+                // return val[2] / 50;
+              },
+              legendHoverLink: true,
+              showEffectOn: "render",
+              rippleEffect: {
+                // period: 4,
+                scale: 6,
+                color: "rgba(255,255,255, 1)",
+                brushType: "fill",
+              },
+              tooltip: {
+                show: true,
+                formatter: function (params) {
+                  if (params.data) {
+                    return params.name + ":" + params.data["value"][2];
+                  } else {
+                    return params.name;
+                  }
+                },
+                backgroundColor: "rgba(0,0,0,.6)",
+                borderColor: "rgba(147, 235, 248, .8)",
+                textStyle: {
+                  color: "#FFF",
+                },
+              },
+              label: {
+                formatter: (param) => {
+                  return param.name.slice(0, 2);
+                },
+  
+                fontSize: 11,
+                offset: [0, 2],
+                position: "bottom",
+                textBorderColor: "#fff",
+                textShadowColor: "#000",
+                textShadowBlur: 10,
+                textBorderWidth: 0,
+                color: "#FFF",
+                show: true,
+              },
+              // colorBy: "data",
+              itemStyle: {
+                color: "rgba(255,255,255,1)",
+                borderColor: "rgba(2255,255,255,2)",
+                borderWidth: 4,
+                shadowColor: "#000",
+                shadowBlur: 10,
+              },
+            },
+          ],
+           //动画效果
+              // animationDuration: 1000,
+              // animationEasing: 'linear',
+              // animationDurationUpdate: 1000
+        };
+        this.options = option;
+      },
+      message(text) {
+        this.$Message({
+          text: text,
+          type: "warning",
+        });
+      },
+      mapclick() {
+        if (this.echartBindClick) return;
+        //单击切换到级地图,当mapCode有值,说明可以切换到下级地图
+        this.$refs.CenterMap.chart.on("click", (params) => {
+          // console.log(params);
+          let xzqData = xzqCode[params.name];
+          if (xzqData) {
+            this.getData(xzqData.adcode);
+          } else {
+            this.message("暂无下级地市!");
+          }
+        });
+        this.echartBindClick = true;
+      },
+    },
+  };
+  </script>
+  <style lang="scss" scoped>
+  .centermap {
+    margin-bottom: 30px;
+  
+    .maptitle {
+      height: 60px;
+      display: flex;
+      justify-content: center;
+      padding-top: 10px;
+      box-sizing: border-box;
+  
+      .titletext {
+        font-size: 28px;
+        font-weight: 900;
+        letter-spacing: 6px;
+        background: linear-gradient(
+          92deg,
+          #0072ff 0%,
+          #00eaff 48.8525390625%,
+          #01aaff 100%
+        );
+        -webkit-background-clip: text;
+        -webkit-text-fill-color: transparent;
+        margin: 0 10px;
+      }
+  
+      .zuo,
+      .you {
+        background-size: 100% 100%;
+        width: 29px;
+        height: 20px;
+        margin-top: 8px;
+      }
+  
+      .zuo {
+        background: url("../../../../../assets/deviceVision/xiezuo.png") no-repeat;
+      }
+  
+      .you {
+        background: url("../../../../../assets/deviceVision/xieyou.png") no-repeat;
+      }
+    }
+  
+    .mapwrap {
+      height: 548px;
+      width: 100%;
+      // padding: 0 0 10px 0;
+      box-sizing: border-box;
+      position: relative;
+  
+      .quanguo {
+        position: absolute;
+        right: 20px;
+        top: -46px;
+        width: 80px;
+        height: 28px;
+        border: 1px solid #00eded;
+        border-radius: 10px;
+        color: #00f7f6;
+        text-align: center;
+        line-height: 26px;
+        letter-spacing: 6px;
+        cursor: pointer;
+        box-shadow: 0 2px 4px rgba(0, 237, 237, 0.5),
+          0 0 6px rgba(0, 237, 237, 0.4);
+      }
+    }
+  }
+  </style>
+  

+ 140 - 0
admin.ui.plus-master/src/views/admin/visualization/deviceVision/indexs/index.vue

@@ -0,0 +1,140 @@
+<!--
+ * @Author: daidai
+ * @Date: 2022-03-04 09:23:59
+ * @LastEditors: Please set LastEditors
+ * @LastEditTime: 2022-05-07 11:05:02
+ * @FilePath: \web-pc\src\pages\big-screen\view\indexs\index.vue
+-->
+<template>
+    <div class="contents">
+        <div class="contetn_left">
+      <div class="pagetab">
+        <!-- <div class="item">实时监测</div> -->
+        
+      </div>
+      <ItemWrap class="contetn_left-top contetn_lr-item" title="设备总览">
+        <LeftTop/>
+    
+      </ItemWrap>
+      <ItemWrap class="contetn_left-center contetn_lr-item" title="用户总览">
+        <LeftCenter />
+      </ItemWrap>
+
+    </div>
+
+        <div class="contetn_center">
+        <CenterMap class="contetn_center_top" />
+        <ItemWrap class="contetn_center-bottom" title="安装计划">
+          <CenterBottom />
+        </ItemWrap>
+      </div>
+    </div>
+  </template>
+  
+  <script>
+  import LeftTop from './left-top.vue';
+  import LeftCenter from "./left-center.vue";
+ /*  import LeftBottom from "./left-bottom.vue";*/
+  import CenterMap from "./center-map.vue"; 
+  import CenterBottom from "./center-bottom.vue";
+  /* import RightTop from "./right-top.vue";
+  import RightCenter from "./right-center.vue";
+  import RightBottom from "./right-bottom.vue"; */
+  import ItemWrap from "../../../../../components/item-wrap/item-wrap.vue";
+  
+  export default {
+    components: {
+     LeftTop,
+     LeftCenter,
+     //CenterMap,
+    /*    LeftCenter,
+      LeftBottom,
+      CenterMap,
+      RightTop,
+      RightCenter,
+      RightBottom, */
+      CenterBottom,
+      ItemWrap,
+    },
+    data() {
+      return {
+      
+      };
+    },
+    filters: {
+      numsFilter(msg) {
+        return msg || 0;
+      },
+    },
+    created() {
+    },
+  
+    mounted() {},
+    methods: {
+    
+    },
+  };
+  </script>
+  <style lang="scss" scoped>
+  // 内容
+  .contents {
+    .contetn_left,
+    .contetn_right {
+      width: 300px;
+      box-sizing: border-box;
+      // padding: 16px 0;
+    }
+  
+    .contetn_center {
+      width: 720px;
+    }
+  
+    //左右两侧 三个块
+    .contetn_lr-item {
+      height: 210px;
+    }
+  
+    .contetn_center_top {
+      width: 100%;
+    }
+  
+    // 中间
+    .contetn_center {
+      display: flex;
+      flex-direction: column;
+      justify-content: space-around;
+    }
+  
+    .contetn_center-bottom {
+      height: 315px;
+    }
+  
+    //左边 右边 结构一样
+    .contetn_left,
+    .contetn_right {
+      display: flex;
+      flex-direction: column;
+      justify-content: space-around;
+      position: relative;
+  
+    
+    }
+  }
+  
+  
+  @keyframes rotating {
+      0% {
+          -webkit-transform: rotate(0) scale(1);
+          transform: rotate(0) scale(1);
+      }
+      50% {
+          -webkit-transform: rotate(180deg) scale(1.1);
+          transform: rotate(180deg) scale(1.1);
+      }
+      100% {
+          -webkit-transform: rotate(360deg) scale(1);
+          transform: rotate(360deg) scale(1);
+      }
+  }
+  </style>
+  

+ 255 - 0
admin.ui.plus-master/src/views/admin/visualization/deviceVision/indexs/left-bottom.vue

@@ -0,0 +1,255 @@
+<!--
+ * @Author: daidai
+ * @Date: 2022-03-01 09:43:37
+ * @LastEditors: Please set LastEditors
+ * @LastEditTime: 2022-09-09 11:40:22
+ * @FilePath: \web-pc\src\pages\big-screen\view\indexs\left-bottom.vue
+-->
+<template>
+    <div
+      v-if="pageflag"
+      class="left_boottom_wrap beautify-scroll-def"
+      :class="{ 'overflow-y-auto': !sbtxSwiperFlag }"
+    >
+      <component :is="components" :data="list" :class-option="defaultOption">
+        <ul class="left_boottom">
+          <li class="left_boottom_item" v-for="(item, i) in list" :key="i">
+            <span class="orderNum doudong">{{ i + 1 }}</span>
+            <div class="inner_right">
+              <div class="dibu"></div>
+              <div class="flex">
+                <div class="info">
+                  <span class="labels">设备ID:</span>
+                  <span class="contents zhuyao doudong wangguan">
+                    {{ item.gatewayno }}</span
+                  >
+                </div>
+                <div class="info">
+                  <span class="labels">时间:</span>
+                  <span class="contents " style="font-size: 12px">
+                    {{ item.createTime }}</span
+                  >
+                </div>
+              </div>
+  
+                <span
+                  class="types doudong"
+                  :class="{
+                    typeRed: item.onlineState == 0,
+                    typeGreen: item.onlineState == 1,
+                  }"
+                  >{{ item.onlineState == 1 ? "上线" : "下线" }}</span
+                >
+  
+              <div class="info addresswrap">
+                <span class="labels">地址:</span>
+                <span class="contents ciyao" style="font-size: 12px">
+                  {{ addressHandle(item) }}</span
+                >
+              </div>
+            </div>
+          </li>
+        </ul>
+      </component>
+    </div>
+  
+    <Reacquire v-else @onclick="getData" style="line-height: 200px" />
+  </template>
+  
+  <script>
+  import { currentGET } from "api";
+  import vueSeamlessScroll from "vue-seamless-scroll"; // vue2引入方式
+  import Kong from "../../components/kong.vue";
+  export default {
+    components: { vueSeamlessScroll, Kong },
+    data() {
+      return {
+        list: [],
+        pageflag: true,
+        components: vueSeamlessScroll,
+        defaultOption: {
+          ...this.$store.state.setting.defaultOption,
+          singleHeight: 240,
+          limitMoveNum: 5, 
+          step: 0,
+        },
+      };
+    },
+    computed: {
+      sbtxSwiperFlag() {
+        let sbtxSwiper = this.$store.state.setting.sbtxSwiper;
+        if (sbtxSwiper) {
+          this.components = vueSeamlessScroll;
+        } else {
+          this.components = Kong;
+        }
+        return sbtxSwiper;
+      },
+    },
+    created() {
+      
+    },
+  
+    mounted() {
+      this.getData();
+    },
+    methods: {
+      addressHandle(item) {
+        let name = item.provinceName;
+        if (item.cityName) {
+          name += "/" + item.cityName;
+          if (item.countyName) {
+            name += "/" + item.countyName;
+          }
+        }
+        return name;
+      },
+      getData() {
+        this.pageflag = true;
+        // this.pageflag =false
+        currentGET("big3", { limitNum: 20 }).then((res) => {
+          console.log("设备提醒", res);
+          if (res.success) {
+            this.countUserNumData = res.data;
+            this.list = res.data.list;
+            let timer = setTimeout(() => {
+              clearTimeout(timer);
+              this.defaultOption.step =
+                this.$store.state.setting.defaultOption.step;
+            }, this.$store.state.setting.defaultOption.waitTime);
+          } else {
+            this.pageflag = false;
+            this.$Message({
+              text: res.msg,
+              type: "warning",
+            });
+          }
+        });
+      },
+    },
+  };
+  </script>
+  <style lang='scss' scoped>
+  .left_boottom_wrap {
+    overflow: hidden;
+    width: 100%;
+    height: 100%;
+  }
+  
+  .doudong {
+    //  vertical-align:middle;
+    overflow: hidden;
+    -webkit-backface-visibility: hidden;
+    -moz-backface-visibility: hidden;
+    -ms-backface-visibility: hidden;
+    backface-visibility: hidden;
+  }
+  
+  .overflow-y-auto {
+    overflow-y: auto;
+  }
+  
+  .left_boottom {
+    width: 100%;
+    height: 100%;
+  
+    .left_boottom_item {
+      display: flex;
+      align-items: center;
+      justify-content: center;
+      padding: 8px;
+      font-size: 14px;
+      margin: 10px 0;
+      .orderNum {
+        margin: 0 16px 0 -20px;
+      }
+  
+      .info {
+        margin-right: 10px;
+        display: flex;
+        align-items: center;
+        color: #fff;
+  
+        .labels {
+          flex-shrink: 0;
+          font-size: 12px;
+          color: rgba(255, 255, 255, 0.6);
+        }
+  
+        .zhuyao {
+          color: $primary-color;
+          font-size: 15px;
+        }
+  
+        .ciyao {
+          color: rgba(255, 255, 255, 0.8);
+        }
+  
+        .warning {
+          color: #e6a23c;
+          font-size: 15px;
+        }
+      }
+  
+      .inner_right {
+        position: relative;
+        height: 100%;
+        width: 380px;
+        flex-shrink: 0;
+        line-height: 1;
+        display: flex;
+        align-items: center;
+        justify-content: space-between;
+        flex-wrap: wrap;
+        .dibu {
+          position: absolute;
+          height: 2px;
+          width: 104%;
+          background-image: url("../../assets/img/zuo_xuxian.png");
+          bottom: -10px;
+          left: -2%;
+          background-size: cover;
+        }
+        .addresswrap {
+          width: 100%;
+          display: flex;
+          margin-top: 8px;
+        }
+      }
+  
+      .wangguan {
+        color: #1890ff;
+        font-weight: 900;
+        font-size: 15px;
+        width: 80px;
+        flex-shrink: 0;
+      }
+  
+  
+      .time {
+        font-size: 12px;
+        // color: rgba(211, 210, 210,.8);
+        color: #fff;
+      }
+  
+      .address {
+        font-size: 12px;
+        cursor: pointer;
+        // @include text-overflow(1);
+      }
+  
+      .types {
+        width: 30px;
+        flex-shrink: 0;
+      }
+  
+      .typeRed {
+        color: #fc1a1a;
+      }
+  
+      .typeGreen {
+        color: #29fc29;
+      }
+    }
+  }
+  </style>

+ 247 - 0
admin.ui.plus-master/src/views/admin/visualization/deviceVision/indexs/left-center.vue

@@ -0,0 +1,247 @@
+<!--
+ * @Author: daidai
+ * @Date: 2022-02-28 16:16:42
+ * @LastEditors: Please set LastEditors
+ * @LastEditTime: 2022-10-25 09:18:22
+ * @FilePath: \web-pc\src\pages\big-screen\view\indexs\left-center.vue
+-->
+<template>
+    <Echart id="leftCenter" :options="options" class="left_center_inner" v-if="pageflag" ref="charts" />
+<!--     <Reacquire v-else @onclick="getData" style="line-height:200px">
+      重新获取
+    </Reacquire> -->
+  </template>
+  
+  <script>
+  //import { currentGET } from 'api/modules'
+  import  Echart  from "../../../../../components/echart/index.vue";
+  export default {
+    components: { Echart},
+    data() {
+      return {
+        options: {},
+        countUserNumData: {
+          lockNum: 0,
+          onlineNum: 0,
+          offlineNum: 0,
+          totalNum: 0
+        },
+        pageflag: true,
+        timer: null
+      };
+    },
+    created() {
+      this.getData()
+    },
+    mounted() {
+    },
+    beforeDestroy() {
+      this.clearData()
+  
+    },
+    methods: {
+      clearData() {
+        if (this.timer) {
+          clearInterval(this.timer)
+          this.timer = null
+        }
+      },
+      getData() {
+        this.pageflag = true
+        // this.pageflag =false
+  
+        this.countUserNumData = {
+      offlineNum: 26,
+      lockNum: 4,
+      totalNum: 218,
+      onlineNum: 188
+    }
+            this.$nextTick(() => {
+              this.init()
+            })
+  
+  /*       currentGET('big1').then(res => {
+          //只打印一次
+          if (!this.timer) {
+            console.log("设备总览", JSON.stringify(res));
+          }
+          if (res.success) {
+            this.countUserNumData = res.data
+            this.$nextTick(() => {
+              this.init()
+            })
+  
+          } else {
+            this.pageflag = false
+            this.$Message({
+              text: res.msg,
+              type: 'warning'
+            })
+          }
+        }) */
+      },
+      //轮询
+      switper() {
+        if (this.timer) {
+          return
+        }
+        let looper = (a) => {
+          this.getData()
+        };
+        this.timer = setInterval(looper, this.$store.state.setting.echartsAutoTime);
+        let myChart = this.$refs.charts.chart
+        myChart.on('mouseover', params => {
+          this.clearData()
+        });
+        myChart.on('mouseout', params => {
+          this.timer = setInterval(looper, this.$store.state.setting.echartsAutoTime);
+        });
+      },
+      init() {
+        let total = this.countUserNumData.totalNum;
+        let colors = ["#ECA444", "#33A1DB", "#56B557"];
+        let piedata = {
+          name: "用户总览",
+          type: "pie",
+          radius: ["30%", "40%"],
+          avoidLabelOverlap: false,
+          itemStyle: {
+            borderRadius: 4,
+            borderColor: "rgba(0,0,0,0)",
+            borderWidth: 2,
+          },
+  
+          color: colors,
+          data: [
+            // {
+            //   value: 0,
+            //   name: "告警",
+            //   label: {
+            //     shadowColor: colors[0],
+            //   },
+            // },
+            {
+              value: this.countUserNumData.lockNum,
+              name: "锁定",
+              label: {
+                shadowColor: colors[0],
+              },
+            },
+            {
+              value: this.countUserNumData.onlineNum,
+              name: "在线",
+              label: {
+                shadowColor: colors[2],
+              },
+            },
+            {
+              value: this.countUserNumData.offlineNum,
+              name: "离线",
+              label: {
+                shadowColor: colors[1],
+              },
+            },
+  
+  
+          ],
+        };
+        this.options = {
+            
+          title: {
+            // zlevel: 0,
+            text: ["{value|" + total + "}", "{name|总数}"].join("\n"),
+            top: "center",
+            left: "center",
+            textStyle: {
+              rich: {
+                value: {
+                  color: "#ffffff",
+                  fontSize: 24,
+                  fontWeight: "bold",
+                  lineHeight: 20,
+                },
+                name: {
+                  color: "#ffffff",
+                  lineHeight: 20,
+                },
+              },
+            },
+          },
+          tooltip: {
+            trigger: "item",
+            backgroundColor: "rgba(0,0,0,.6)",
+            borderColor: "rgba(147, 235, 248, .8)",
+            textStyle: {
+              color: "#FFF",
+            },
+          },
+          legend: {
+            show: false,
+            top: "5%",
+            left: "center",
+          },
+          series: [
+            //展示圆点
+            {
+              ...piedata,
+              tooltip: { show: true },
+              label: {
+                formatter: "   {b|{b}}   \n   {c|{c}个}   {per|{d}%}  ",
+                //   position: "outside",
+                rich: {
+                  b: {
+                    color: "#fff",
+                    fontSize: 12,
+                    lineHeight: 26,
+                  },
+                  c: {
+                    color: "#31ABE3",
+                    fontSize: 14,
+                  },
+                  per: {
+                    color: "#31ABE3",
+                    fontSize: 14,
+                  },
+                },
+              },
+              labelLine: {
+                length: 20, // 第一段线 长度
+                length2: 36, // 第二段线 长度
+                show: true,
+              
+              },
+                emphasis: {
+                  show: true,
+                },
+            },
+            {
+              ...piedata,
+              tooltip: { show: true },
+              itemStyle: {},
+              label: {
+                backgroundColor: "inherit", //圆点颜色,auto:映射的系列色
+                height: 0,
+                width: 0,
+                lineHeight: 0,
+                borderRadius: 2.5,
+                shadowBlur: 8,
+                shadowColor: "auto",
+                padding: [2.5, -2.5, 2.5, -2.5],
+              },
+              labelLine: {
+                length: 20, // 第一段线 长度
+                length2: 36, // 第二段线 长度
+                show: false,
+              },
+            },
+          ],
+        };
+      },
+    },
+  };
+  </script>
+  <style lang='scss' scoped>
+  .left_center_inner{
+    height: 170px  !important;;
+  }
+  </style>

+ 195 - 0
admin.ui.plus-master/src/views/admin/visualization/deviceVision/indexs/left-top.vue

@@ -0,0 +1,195 @@
+<template>
+    <ul class="user_Overview flex" v-if="pageflag">
+        <li class="user_Overview-item" style="color: #00fdfa">
+            <div class="user_Overview_nums allnum ">
+                <dv-digital-flop :config="config" style="width:100%;height:100%;" />
+            </div>
+            <p>总设备数</p>
+        </li>
+        <li class="user_Overview-item" style="color: #07f7a8">
+            <div class="user_Overview_nums online">
+                <dv-digital-flop :config="onlineconfig" style="width:100%;height:100%;" />
+            </div>
+            <p>在线数</p>
+        </li>
+        <li class="user_Overview-item" style="color: #e3b337">
+            <div class="user_Overview_nums offline">
+                <dv-digital-flop :config="offlineconfig" style="width:100%;height:100%;" />
+
+            </div>
+            <p>掉线数</p>
+        </li>
+        <li class="user_Overview-item" style="color: #f5023d">
+            <div class="user_Overview_nums laramnum">
+                <dv-digital-flop :config="laramnumconfig" style="width:100%;height:100%;" />
+            </div>
+            <p>告警次数</p>
+        </li>
+    </ul>
+    <Reacquire v-else @onclick="getData" line-height="200px">
+        重新获取
+    </Reacquire>
+</template>
+
+<script>
+let style = {
+    fontSize: 24
+}
+
+export default {
+    data() {
+        return {
+            options: {},
+            userOverview: {
+                alarmNum: 0,
+                offlineNum: 0,
+                onlineNum: 0,
+                totalNum: 0,
+            },
+            pageflag: true,
+            timer: null,
+            config: {
+                number: [100],
+                content: '{nt}',
+                style: {
+                    ...style,
+                    // stroke: "#00fdfa",
+                    fill: "#00fdfa",
+                },
+            },
+            onlineconfig: {
+                number: [0],
+                content: '{nt}',
+                style: {
+                    ...style,
+                    // stroke: "#07f7a8",
+                    fill: "#07f7a8",
+                },
+            },
+            offlineconfig: {
+                number: [0],
+                content: '{nt}',
+                style: {
+                    ...style,
+                    // stroke: "#e3b337",
+                    fill: "#e3b337",
+                },
+            },
+            laramnumconfig: {
+                number: [0],
+                content: '{nt}',
+                style: {
+                    ...style,
+                    // stroke: "#f5023d",
+                    fill: "#f5023d",
+                },
+            }
+
+        };
+    },
+    filters: {
+        numsFilter(msg) {
+            return msg || 0;
+        },
+    },
+    created() {
+        this.getData()
+    },
+    mounted() {
+    },
+    beforeDestroy() {
+        this.clearData()
+
+    },
+    methods: {
+        clearData() {
+            if (this.timer) {
+                clearInterval(this.timer)
+                this.timer = null
+            }
+        },
+        getData() {
+
+        },
+        //轮询
+        switper() {
+            if (this.timer) {
+                return
+            }
+            let looper = (a) => {
+                this.getData()
+            };
+            this.timer = setInterval(looper, 5000);
+        },
+    },
+};
+</script>
+<style lang='scss' scoped>
+.user_Overview {
+
+    li {
+        flex: 1;
+        list-style: none;
+        p {
+            text-align: center;
+            height: 16px;
+            font-size: 16px;
+        }
+
+        .user_Overview_nums {
+            width: 100px;
+            height: 100px;
+            text-align: center;
+            line-height: 100px;
+            font-size: 22px;
+           // margin: 50px auto 30px;
+            background-size: cover;
+            background-position: center center;
+            position: relative;
+
+            &::before {
+                content: '';
+                position: absolute;
+                width: 100%;
+                height: 100%;
+                top: 0;
+                left: 0;
+            }
+
+            &.bgdonghua::before {
+                animation: rotating 14s linear infinite;
+            }
+        }
+
+        .allnum {
+
+            // background-image: url("../../assets/img/left_top_lan.png"); ../../../../assets/deviceVision
+            &::before {
+                background-image: url("../../../../../assets/deviceVision/left_top_lan.png");
+
+            }
+        }
+
+        .online {
+            &::before {
+                background-image: url("../../../../../assets/deviceVision/left_top_lv.png");
+
+            }
+        }
+
+        .offline {
+            &::before {
+                background-image: url("../../../../../assets/deviceVision/left_top_huang.png");
+
+            }
+        }
+
+        .laramnum {
+            &::before {
+                background-image: url("../../../../../assets/deviceVision/left_top_hong.png");
+
+            }
+        }
+    }
+}
+</style>

+ 194 - 0
admin.ui.plus-master/src/views/admin/visualization/deviceVision/indexs/right-bottom.vue

@@ -0,0 +1,194 @@
+<!--
+ * @Author: daidai
+ * @Date: 2022-03-01 15:27:58
+ * @LastEditors: Please set LastEditors
+ * @LastEditTime: 2022-05-07 11:24:14
+ * @FilePath: \web-pc\src\pages\big-screen\view\indexs\right-center.vue
+-->
+<template>
+    <div v-if="pageflag" class="right_center_wrap beautify-scroll-def" :class="{ 'overflow-y-auto': !sbtxSwiperFlag }">
+      <component :is="components" :data="list" :class-option="defaultOption">
+        <ul class="right_center ">
+          <li class="right_center_item" v-for="(item, i) in list" :key="i">
+            <span class="orderNum">{{ i + 1 }}</span>
+            <div class="inner_right">
+              <div class="dibu"></div>
+              <div class="flex">
+                <div class="info">
+                  <span class="labels ">设备ID:</span>
+                  <span class="contents zhuyao"> {{ item.gatewayno }}</span>
+                </div>
+                <div class="info">
+                  <span class="labels">型号:</span>
+                  <span class="contents "> {{ item.terminalno }}</span>
+                </div>
+                <div class="info">
+                  <span class="labels">告警值:</span>
+                  <span class="contents warning"> {{ item.alertvalue | montionFilter }}</span>
+                </div>
+              </div>
+  
+  
+              <div class="flex">
+  
+                <div class="info">
+                  <span class="labels"> 地址:</span>
+                  <span class="contents ciyao" style="font-size:12px"> {{ item.provinceName }}/{{ item.cityName }}/{{ item.countyName }}</span>
+                </div>
+                <div class="info time">
+                  <span class="labels">时间:</span>
+                  <span class="contents" style="font-size:12px"> {{ item.createtime }}</span>
+                </div>
+  
+              </div>
+              <div class="flex">
+  
+                <div class="info">
+                  <span class="labels">报警内容:</span>
+                  <span class="contents ciyao" :class="{ warning: item.alertdetail }"> {{ item.alertdetail || '无'
+                  }}</span>
+                </div>
+              </div>
+            </div>
+          </li>
+        </ul>
+      </component>
+    </div>
+    <Reacquire v-else @onclick="getData" style="line-height:200px" />
+  
+  </template>
+  
+  <script>
+  import { currentGET } from 'api/modules'
+  import vueSeamlessScroll from 'vue-seamless-scroll'  // vue2引入方式
+  import Kong from '../../components/kong.vue'
+  export default {
+    components: { vueSeamlessScroll, Kong },
+  
+    data() {
+      return {
+        list: [],
+        pageflag: true,
+        defaultOption: {
+          ...this.$store.state.setting.defaultOption,
+          limitMoveNum: 3, 
+          singleHeight: 250, 
+          step:0,
+        }
+  
+      };
+    },
+    computed: {
+      sbtxSwiperFlag() {
+        let ssyjSwiper = this.$store.state.setting.ssyjSwiper
+        if (ssyjSwiper) {
+          this.components = vueSeamlessScroll
+        } else {
+          this.components = Kong
+        }
+        return ssyjSwiper
+      }
+    },
+    created() {
+      this.getData()
+    },
+  
+    mounted() { },
+    methods: {
+      getData() {
+        this.pageflag = true
+        // this.pageflag =false
+        currentGET('big5', { limitNum: 50 }).then(res => {
+          console.log('实时预警', res);
+          if (res.success) {
+            this.list = res.data.list
+            let timer = setTimeout(() => {
+                clearTimeout(timer)
+                this.defaultOption.step=this.$store.state.setting.defaultOption.step
+            }, this.$store.state.setting.defaultOption.waitTime);
+          } else {
+            this.pageflag = false
+            this.$Message.warning(res.msg)
+          }
+        })
+      },
+  
+    },
+  };
+  </script>
+  <style lang='scss' scoped>
+  .right_center {
+    width: 100%;
+    height: 100%;
+  
+    .right_center_item {
+      display: flex;
+      align-items: center;
+      justify-content: center;
+      height: auto;
+      padding: 10px;
+      font-size: 14px;
+      color: #fff;
+  
+      .orderNum {
+        margin: 0 20px 0 -20px;
+      }
+  
+  
+      .inner_right {
+        position: relative;
+        height: 100%;
+        width: 400px;
+        flex-shrink: 0;
+        line-height: 1.5;
+  
+        .dibu {
+          position: absolute;
+          height: 2px;
+          width: 104%;
+          background-image: url("../../assets/img/zuo_xuxian.png");
+          bottom: -12px;
+          left: -2%;
+          background-size: cover;
+        }
+      }
+  
+      .info {
+        margin-right: 10px;
+        display: flex;
+        align-items: center;
+  
+        .labels {
+          flex-shrink: 0;
+          font-size: 12px;
+          color: rgba(255, 255, 255, 0.6);
+        }
+  
+        .zhuyao {
+          color: $primary-color;
+          font-size: 15px;
+        }
+  
+        .ciyao {
+          color: rgba(255, 255, 255, 0.8);
+        }
+  
+        .warning {
+          color: #E6A23C;
+          font-size: 15px;
+        }
+      }
+  
+    }
+  }
+  
+  .right_center_wrap {
+    overflow: hidden;
+    width: 100%;
+    height: 250px;
+  }
+  
+  .overflow-y-auto {
+    overflow-y: auto;
+  }
+  </style>

+ 163 - 0
admin.ui.plus-master/src/views/admin/visualization/deviceVision/indexs/right-center.vue

@@ -0,0 +1,163 @@
+<!--
+ * @Author: daidai
+ * @Date: 2022-03-01 15:51:43
+ * @LastEditors: Please set LastEditors
+ * @LastEditTime: 2022-09-29 15:12:46
+ * @FilePath: \web-pc\src\pages\big-screen\view\indexs\right-bottom.vue
+-->
+<template>
+    <div class="right_bottom">
+      <dv-capsule-chart :config="config" style="width:100%;height:260px" />
+    </div>
+  </template>
+  
+  <script>
+  import { currentGET } from 'api/modules'
+  export default {
+    data() {
+      return {
+        gatewayno: '',
+        config: {
+          showValue: true,
+          unit: "次",
+          data: []
+        },
+  
+      };
+    },
+    created() {
+      this.getData()
+  
+    },
+    computed: {
+    },
+    mounted() { },
+    beforeDestroy() {
+      this.clearData()
+    },
+    methods: {
+      clearData() {
+        if (this.timer) {
+          clearInterval(this.timer)
+          this.timer = null
+        }
+      },
+      //轮询
+      switper() {
+        if (this.timer) {
+          return
+        }
+        let looper = (a) => {
+          this.getData()
+        };
+        this.timer = setInterval(looper, this.$store.state.setting.echartsAutoTime);
+      },
+      getData() {
+        this.pageflag = true
+        // this.pageflag =false
+        currentGET('big7', { gatewayno: this.gatewayno }).then(res => {
+  
+          if (!this.timer) {
+            console.log('报警排名', res);
+          }
+          if (res.success) {
+            this.config = {
+              ...this.config,
+              data: res.data
+            }
+            this.switper()
+          } else {
+            this.pageflag = false
+            this.srcList = []
+            this.$Message({
+              text: res.msg,
+              type: 'warning'
+            })
+          }
+        })
+      },
+    },
+  };
+  </script>
+  <style lang='scss' scoped>
+  .list_Wrap {
+    height: 100%;
+    overflow: hidden;
+    :deep(.kong)   {
+      width: auto;
+    }
+  }
+  
+  .sbtxSwiperclass {
+    .img_wrap {
+      overflow-x: auto;
+    }
+  
+  }
+  
+  .right_bottom {
+    box-sizing: border-box;
+    padding: 0 16px;
+  
+    .searchform {
+      height: 80px;
+      display: flex;
+      align-items: center;
+      justify-content: center;
+  
+      .searchform_item {
+        display: flex;
+        justify-content: center;
+        align-items: center;
+  
+        label {
+          margin-right: 10px;
+          color: rgba(255, 255, 255, 0.8);
+        }
+  
+        button {
+          margin-left: 30px;
+        }
+  
+        input {}
+      }
+    }
+  
+    .img_wrap {
+      display: flex;
+      // justify-content: space-around;
+      box-sizing: border-box;
+      padding: 0 0 20px;
+      // overflow-x: auto;
+  
+      li {
+        width: 105px;
+        height: 137px;
+        border-radius: 6px;
+        overflow: hidden;
+        cursor: pointer;
+        // background: #84ccc9;
+        // border: 1px solid #ffffff;
+        overflow: hidden;
+        flex-shrink: 0;
+        margin: 0 10px;
+  
+        img {
+          flex-shrink: 0;
+        }
+      }
+  
+  
+  
+  
+    }
+  
+    .noData {
+      width: 100%;
+      line-height: 100px;
+      text-align: center;
+      color: rgb(129, 128, 128);
+  
+    }
+  }
+  </style>

+ 299 - 0
admin.ui.plus-master/src/views/admin/visualization/deviceVision/indexs/right-top.vue

@@ -0,0 +1,299 @@
+<!--
+ * @Author: daidai
+ * @Date: 2022-03-01 14:13:04
+ * @LastEditors: Please set LastEditors
+ * @LastEditTime: 2022-09-27 15:04:49
+ * @FilePath: \web-pc\src\pages\big-screen\view\indexs\right-top.vue
+-->
+<template>
+    <Echart
+      id="rightTop"
+      :options="option"
+      class="right_top_inner"
+      v-if="pageflag"
+      ref="charts"
+    />
+    <Reacquire v-else @onclick="getData" style="line-height: 200px">
+      重新获取
+    </Reacquire>
+  </template>
+  
+  <script>
+  import { currentGET } from "api/modules";
+  import {graphic} from "echarts"
+  export default {
+    data() {
+      return {
+        option: {},
+        pageflag: false,
+        timer: null,
+      };
+    },
+    created() {
+     
+    },
+  
+    mounted() {
+       this.getData();
+    },
+    beforeDestroy() {
+      this.clearData();
+    },
+    methods: {
+      clearData() {
+        if (this.timer) {
+          clearInterval(this.timer);
+          this.timer = null;
+        }
+      },
+      getData() {
+        this.pageflag = true;
+        // this.pageflag =false
+        currentGET("big4").then((res) => {
+          if (!this.timer) {
+            console.log("报警次数", res);
+          }
+          if (res.success) {
+            this.countUserNumData = res.data;
+            this.$nextTick(() => {
+              this.init(res.data.dateList, res.data.numList, res.data.numList2),
+                this.switper();
+            });
+          } else {
+            this.pageflag = false;
+            this.$Message({
+              text: res.msg,
+              type: "warning",
+            });
+          }
+        });
+      },
+      //轮询
+      switper() {
+        if (this.timer) {
+          return;
+        }
+        let looper = (a) => {
+          this.getData();
+        };
+        this.timer = setInterval(
+          looper,
+          this.$store.state.setting.echartsAutoTime
+        );
+        let myChart = this.$refs.charts.chart;
+        myChart.on("mouseover", (params) => {
+          this.clearData();
+        });
+        myChart.on("mouseout", (params) => {
+          this.timer = setInterval(
+            looper,
+            this.$store.state.setting.echartsAutoTime
+          );
+        });
+      },
+      init(xData, yData, yData2) {
+        this.option = {
+          xAxis: {
+            type: "category",
+            data: xData,
+            boundaryGap: false, // 不留白,从原点开始
+            splitLine: {
+              show: true,
+              lineStyle: {
+                color: "rgba(31,99,163,.2)",
+              },
+            },
+            axisLine: {
+              // show:false,
+              lineStyle: {
+                color: "rgba(31,99,163,.1)",
+              },
+            },
+            axisLabel: {
+              color: "#7EB7FD",
+              fontWeight: "500",
+            },
+          },
+          yAxis: {
+            type: "value",
+            splitLine: {
+              show: true,
+              lineStyle: {
+                color: "rgba(31,99,163,.2)",
+              },
+            },
+            axisLine: {
+              lineStyle: {
+                color: "rgba(31,99,163,.1)",
+              },
+            },
+            axisLabel: {
+              color: "#7EB7FD",
+              fontWeight: "500",
+            },
+          },
+          tooltip: {
+            trigger: "axis",
+            backgroundColor: "rgba(0,0,0,.6)",
+            borderColor: "rgba(147, 235, 248, .8)",
+            textStyle: {
+              color: "#FFF",
+            },
+          },
+          grid: {
+            //布局
+            show: true,
+            left: "10px",
+            right: "30px",
+            bottom: "10px",
+            top: "28px",
+            containLabel: true,
+            borderColor: "#1F63A3",
+          },
+          series: [
+            {
+              data: yData,
+              type: "line",
+              smooth: true,
+              symbol: "none", //去除点
+              name: "报警1次数",
+              color: "rgba(252,144,16,.7)",
+              areaStyle: {
+                  //右,下,左,上
+                  color: new graphic.LinearGradient(
+                    0,
+                    0,
+                    0,
+                    1,
+                    [
+                      {
+                        offset: 0,
+                        color: "rgba(252,144,16,.7)",
+                      },
+                      {
+                        offset: 1,
+                        color: "rgba(252,144,16,.0)",
+                      },
+                    ],
+                    false
+                  ),
+              },
+              markPoint: {
+                data: [
+                  {
+                    name: "最大值",
+                    type: "max",
+                    valueDim: "y",
+                    symbol: "rect",
+                    symbolSize: [60, 26],
+                    symbolOffset: [0, -20],
+                    itemStyle: {
+                      color: "rgba(0,0,0,0)",
+                    },
+                    label: {
+                      color: "#FC9010",
+                      backgroundColor: "rgba(252,144,16,0.1)",
+                      borderRadius: 6,
+                      padding: [7, 14],
+                      borderWidth: 0.5,
+                      borderColor: "rgba(252,144,16,.5)",
+                      formatter: "报警1:{c}",
+                    },
+                  },
+                  {
+                    name: "最大值",
+                    type: "max",
+                    valueDim: "y",
+                    symbol: "circle",
+                    symbolSize: 6,
+                    itemStyle: {
+                      color: "#FC9010",
+                      shadowColor: "#FC9010",
+                      shadowBlur: 8,
+                    },
+                    label: {
+                      formatter: "",
+                    },
+                  },
+                ],
+              },
+            },
+            {
+              data: yData2,
+              type: "line",
+              smooth: true,
+              symbol: "none", //去除点
+              name: "报警2次数",
+              color: "rgba(9,202,243,.7)",
+              areaStyle: {
+                  //右,下,左,上
+                  color: new graphic.LinearGradient(
+                    0,
+                    0,
+                    0,
+                    1,
+                    [
+                      {
+                        offset: 0,
+                        color: "rgba(9,202,243,.7)",
+                      },
+                      {
+                        offset: 1,
+                        color: "rgba(9,202,243,.0)",
+                      },
+                    ],
+                    false
+                  ),
+              },
+              markPoint: {
+                data: [
+                  {
+                    name: "最大值",
+                    type: "max",
+                    valueDim: "y",
+                    symbol: "rect",
+                    symbolSize: [60, 26],
+                    symbolOffset: [0, -20],
+                    itemStyle: {
+                      color: "rgba(0,0,0,0)",
+                    },
+                    label: {
+                      color: "#09CAF3",
+                      backgroundColor: "rgba(9,202,243,0.1)",
+  
+                      borderRadius: 6,
+                      borderColor: "rgba(9,202,243,.5)",
+                      padding: [7, 14],
+                      formatter: "报警2:{c}",
+                      borderWidth: 0.5,
+                    },
+                  },
+                  {
+                    name: "最大值",
+                    type: "max",
+                    valueDim: "y",
+                    symbol: "circle",
+                    symbolSize: 6,
+                    itemStyle: {
+                      color: "#09CAF3",
+                      shadowColor: "#09CAF3",
+                      shadowBlur: 8,
+                    },
+                    label: {
+                      formatter: "",
+                    },
+                  },
+                ],
+              },
+            },
+          ],
+        };
+      },
+    },
+  };
+  </script>
+  <style lang='scss' scoped>
+  .right_top_inner {
+    margin-top: -8px;
+  }
+  </style>

+ 258 - 0
admin.ui.plus-master/src/views/admin/visualization/deviceVision/scale-screen.vue

@@ -0,0 +1,258 @@
+<!--
+ * @Author: wei
+ * @description: 大屏自适应容器组件
+ * @LastEditTime: 2022-09-09 16:42:40
+-->
+<template>
+    <!-- <section class="screen-box" :style="boxStyle"> -->
+    <div class="screen-wrapper" ref="screenWrapper" :style="wrapperStyle">
+      <slot></slot>
+    </div>
+    <!-- </section> -->
+  </template>
+  <script>
+  /**
+   * 防抖函数
+   * @param {T} fn
+   * @param {number} delay
+   * @return
+   */
+  function debounce(fn, delay) {
+    let timer = null;
+    return function (...args) {
+      timer = setTimeout(
+        () => {
+          typeof fn === "function" && fn.apply(null, args);
+          clearTimeout(timer);
+        },
+        delay > 0 ? delay : 100
+      );
+    };
+  }
+  
+  export default {
+    name: "VScaleScreen",
+    props: {
+      width: {
+        type: [String, Number],
+        default: 1920,
+      },
+      height: {
+        type: [String, Number],
+        default: 1080,
+      },
+      fullScreen: {
+        type: Boolean,
+        default: false,
+      },
+      autoScale: {
+        type: [Object, Boolean],
+        default: false,
+      },
+      selfAdaption: {
+        type: Boolean,
+        default: true,
+      },
+      delay: {
+        type: Number,
+        default: 500,
+      },
+      boxStyle: {
+        type: Object,
+        default: () => ({}),
+      },
+      wrapperStyle: {
+        type: Object,
+        default: () => ({}),
+      },
+    },
+    data() {
+      return {
+        currentWidth: 0,
+        currentHeight: 0,
+        originalWidth: 0,
+        originalHeight: 0,
+        onResize: null,
+        observer: null,
+      };
+    },
+    watch: {
+      selfAdaption(val) {
+        if (val) {
+          this.resize();
+          this.addListener();
+        } else {
+          this.clearListener();
+          this.clearStyle();
+        }
+      },
+    },
+    computed: {
+      screenWrapper() {
+        return this.$refs["screenWrapper"];
+      },
+    },
+    methods: {
+      initSize() {
+        return new Promise((resolve, reject) => {
+          // console.log("初始化样式");
+          //给父元素设置 overflow:hidden
+          this.screenWrapper.parentNode.style.overflow = "hidden";
+          this.screenWrapper.parentNode.scrollLeft = 0;
+          this.screenWrapper.parentNode.scrollTop = 0;
+  
+          this.$nextTick(() => {
+            // region 获取大屏真实尺寸
+            if (this.width && this.height) {
+              this.currentWidth = this.width* 0.8;
+              this.currentHeight = this.height* 0.8;
+            } else {
+              this.currentWidth = this.screenWrapper.clientWidth * 0.8;
+              this.currentHeight = this.screenWrapper.clientHeight* 0.8;
+            }
+            // endregion
+            // region 获取画布尺寸
+            if (!this.originalHeight || !this.originalWidth) {
+              this.originalWidth = window.screen.width* 0.8;
+              this.originalHeight = window.screen.height* 0.8;
+            }
+            // endregion
+            resolve();
+          });
+        });
+      },
+      updateSize() {
+        if (this.currentWidth && this.currentHeight) {
+          this.screenWrapper.style.width = `${this.currentWidth* 0.8}px`;
+          this.screenWrapper.style.height = `${this.currentHeight* 0.8}px`;
+        } else {
+          this.screenWrapper.style.width = `${this.originalWidth* 0.8}px`;
+          this.screenWrapper.style.height = `${this.originalHeight* 0.8}px`;
+        }
+      },
+      handleAutoScale(scale) {
+        if (!this.autoScale) return;
+        const screenWrapper = this.screenWrapper;
+        const domWidth = screenWrapper.clientWidth* 0.8;
+        const domHeight = screenWrapper.clientHeight* 0.8;
+        const currentWidth = document.body.clientWidth* 0.8;
+        const currentHeight = document.body.clientHeight* 0.8;
+        //screenWrapper.style.transform = `scale(${scale},${scale}) `;
+        let mx = Math.max((currentWidth - domWidth * scale) / 2, 0);
+        let my = Math.max((currentHeight - domHeight * scale) / 2, 0);
+        if (typeof this.autoScale === "object") {
+          // @ts-ignore
+          !this.autoScale.x && (mx = 0);
+          // @ts-ignore
+          !this.autoScale.y && (my = 0);
+        }
+        // console.log({
+        //   mx,
+        //   my,
+        //   currentWidth,
+        //   currentHeight,
+        //   domWidth,
+        //   domHeight,
+        //   scale,
+        // });
+        //this.screenWrapper.style.margin = `${my}px ${mx}px`;
+      },
+      updateScale() {
+        const screenWrapper = this.screenWrapper;
+        // 获取真实视口尺寸
+        const currentWidth = document.body.clientWidth* 0.8;
+        const currentHeight = document.body.clientHeight* 0.8;
+        // 获取大屏最终的宽高onResize
+        const realWidth = this.currentWidth || this.originalWidth;
+        const realHeight = this.currentHeight || this.originalHeight;
+        // 计算缩放比例
+        const widthScale = currentWidth / realWidth;
+        const heightScale = currentHeight / realHeight;
+         console.log("计算缩放比例 :"
+         + "currentWidth" + currentWidth 
+         + "currentHeight" + currentHeight 
+         + "realWidth" + realWidth 
+         + "realHeight" + realHeight);
+  
+        // 若要铺满全屏,则按照各自比例缩放
+        if (this.fullScreen) {
+          screenWrapper.style.transform = `scale(${widthScale},${heightScale})`;
+          return false;
+        }
+        // 按照宽高最小比例进行缩放
+        const scale = Math.min(widthScale, heightScale);
+        this.handleAutoScale(scale);
+      },
+      initMutationObserver() {
+        const screenWrapper = this.screenWrapper;
+        const observer = (this.observer = new MutationObserver(() => {
+          this.onResize();
+        }));
+  
+        observer.observe(screenWrapper, {
+          attributes: true,
+          attributeFilter: ["style"],
+          attributeOldValue: true,
+        });
+      },
+      clearListener() {
+        window.removeEventListener("resize", this.onResize);
+      },
+      addListener() {
+        window.addEventListener("resize", this.onResize);
+      },
+      clearStyle() {
+        // console.log("清除");
+        const screenWrapper = this.screenWrapper;
+        screenWrapper.parentNode.style.overflow = "auto";
+  
+        screenWrapper.style = "";
+      },
+      async resize() {
+        if (!this.selfAdaption) {
+          return;
+        }
+        await this.initSize();
+        this.updateSize();
+        this.updateScale();
+      },
+    },
+    mounted() {
+      this.onResize = debounce(() => {
+        this.resize();
+      }, this.delay);
+      this.$nextTick(() => {
+        if (this.selfAdaption) {
+          this.resize();
+          this.addListener();
+        }
+      });
+    },
+    beforeDestroy() {
+      this.clearListener();
+      // this.observer.disconnect()
+    },
+  };
+  //
+  </script>
+  
+  <style scoped>
+  .screen-box {
+    overflow: hidden;
+    background-size: 100% 100%;
+    background: #000;
+    width: 100vw;
+    height: 100vh;
+  }
+  
+  .screen-wrapper {
+    transition-property: all;
+    transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
+    transition-duration: 500ms;
+    position: relative;
+    overflow: hidden;
+    z-index: 100;
+    transform-origin: left top;
+  }
+  </style>
+  

+ 105 - 0
admin.ui.plus-master/src/views/admin/visualization/deviceVision/setting.vue

@@ -0,0 +1,105 @@
+<template>
+    <transition name="yh-setting-fade">
+        <div class="setting" :class="{ settingShow: settingShow }" v-show="settingShow">
+            <div class="setting_dislog" @click="settingShow = false">
+
+            </div>
+            <div class="setting_inner">
+                <div class="setting_header">
+                    设置
+                </div>
+                <div class="setting_body">
+                    <!-- <div class="left_shu"> 实时监测</div> -->
+                    <div class="left_shu"> 全局设置</div> 
+                      <div class="setting_item">
+                        <span class="setting_label">
+                            是否进行自动适配<span class="setting_label_tip">(默认分辨率1920*1080)</span>: 
+                        </span>
+                        <div class="setting_content">
+                            <el-radio-group v-model="isScaleradio" @change="(val) => radiochange(val, 'isScale')">
+                                <el-radio :label="true">是</el-radio>
+                                <el-radio :label="false">否</el-radio>
+                            </el-radio-group>
+
+                        </div>
+                    </div>
+                    <div class="left_shu"> 实时监测</div>
+                    <div class="setting_item">
+                        <span class="setting_label">
+                            设备提醒自动轮询: <span class="setting_label_tip"></span>
+                        </span>
+                        <div class="setting_content">
+                            <el-radio-group v-model="sbtxradio" @change="(val) => radiochange(val, 'sbtxSwiper')">
+                                <el-radio :label="true">是</el-radio>
+                                <el-radio :label="false">否</el-radio>
+                            </el-radio-group>
+
+                        </div>
+                    </div>
+                    <div class="setting_item">
+                        <span class="setting_label">
+                            实时预警轮播:
+                        </span>
+                        <div class="setting_content">
+                            <el-radio-group v-model="ssyjradio" @change="(val) => radiochange(val, 'ssyjSwiper')">
+                                <el-radio :label="true">是</el-radio>
+                                <el-radio :label="false">否</el-radio>
+                            </el-radio-group>
+                        </div>
+                    </div>
+                    <div class="flex justify-center">
+                        <!-- <el-button type="primary" round size="mini">确定</el-button> -->
+                    </div>
+                </div>
+            </div>
+        </div>
+    </transition>
+</template>
+
+<script>
+
+export default {
+    components: {},
+    data() {
+        return {
+            settingShow: false,
+            sbtxradio:true,
+            ssyjradio: true,
+            isScaleradio:true,
+        };
+    },
+    computed: {},
+    methods: {
+        init() {
+            this.settingShow = true
+        },
+        radiochange(val, type) {
+            //this.$store.commit('setting/updateSwiper', { val, type })
+            if(type==='isScale'){
+                // this.$router.go(0)
+                // location.reload()
+                // window.location.href=window.location.href+"?t="+Date.now()
+            }
+        },
+    },
+    created() {
+        //this.$store.commit('setting/initSwipers')
+        //this.sbtxradio = this.$store.state.setting.sbtxSwiper,
+       // this.ssyjradio = this.$store.state.setting.ssyjSwiper,
+       // this.isScaleradio = this.$store.state.setting.isScale;
+    },
+    mounted() {
+        document.body.appendChild(this.$el);
+    },
+    beforeDestroy() {
+    },
+    destroyed() {
+        if (this.$el && this.$el.parentNode) {
+            this.$el.parentNode.removeChild(this.$el);
+        }
+    }
+}
+</script>
+
+<style lang='scss' scoped>
+</style>

+ 86 - 0
admin.ui.plus-master/src/views/admin/visualization/deviceVision/test.vue

@@ -0,0 +1,86 @@
+<!--
+ * @Author: daidai
+ * @Date: 2022-01-12 14:23:32
+ * @LastEditors: Please set LastEditors
+ * @LastEditTime: 2022-09-09 14:47:24
+ * @FilePath: \web-pc\src\pages\big-screen\view\home.vue
+-->
+<template>
+   
+   <div class="iframe-container">  
+    <iframe :src="iframeUrl" frameborder="0" class="fill-container"></iframe>  
+  </div> 
+  </template>
+
+<script>
+//import { formatTime } from "../../../../utils/deviceVision.js";
+import Setting from "./setting.vue";
+export default {
+  components: { Setting},
+  data() {
+    return {
+      timing: null,
+      loading: true,
+      dateDay: null,
+      dateYear: null,
+      dateWeek: null,
+      weekday: ["周日", "周一", "周二", "周三", "周四", "周五", "周六"],
+      iframeUrl:"http://localhost:8080/#/index"
+    };
+  },
+  filters: {
+    numsFilter(msg) {
+      return msg || 0;
+    },
+  },
+  computed: {},
+  created() {},
+  mounted() {
+    this.timeFn();
+    this.cancelLoading();
+  },
+  beforeDestroy() {
+    clearInterval(this.timing);
+  },
+  methods: {
+    showSetting() {
+      this.$refs.setting.init();
+    },
+    timeFn() {
+      this.timing = setInterval(() => {
+        //this.dateDay = formatTime(new Date(), "HH: mm: ss");
+        //this.dateYear = formatTime(new Date(), "yyyy-MM-dd");
+        this.dateWeek = this.weekday[new Date().getDay()];
+      }, 1000);
+    },
+    cancelLoading() {
+      let timer = setTimeout(() => {
+        this.loading = false;
+        clearTimeout(timer);
+      }, 500);
+    },
+  },
+};
+</script>
+
+
+<style scoped>  
+.iframe-container {  
+  /* 根据需要设置容器的样式 */  
+  width: 100%; /* 如果需要的话,设置容器的宽度 */  
+  height: 100vh; /* 设置容器的高度为视口高度的100% */  
+  /* 注意:如果有其他元素在页面上,你可能需要调整这个值 */  
+  display: flex; /* 使用Flexbox来确保iframe填充整个容器 */  
+  justify-content: center; /* 水平居中iframe(如果需要的话) */  
+  align-items: stretch; /* 垂直方向也尝试填充(但iframe内容可能不会响应) */  
+  overflow: hidden; /* 隐藏超出容器的iframe内容(如果需要的话) */  
+  position: relative; /* 如果需要绝对定位iframe或其他子元素 */  
+}  
+  
+.fill-container {  
+  width: 100%; /* 填充容器的宽度 */  
+  height: 100%; /* 填充容器的高度 */  
+  border: none; /* 移除边框(如果需要的话) */  
+  display: block; /* 确保iframe是块级元素 */  
+}  
+</style>

+ 83 - 0
admin.ui.plus-master/src/views/admin/visualization/fueldepotmonitoringdata/index.vue

@@ -0,0 +1,83 @@
+<!--
+ * @Author: daidai
+ * @Date: 2022-01-12 14:23:32
+ * @LastEditors: Please set LastEditors
+ * @LastEditTime: 2022-09-09 14:47:24
+ * @FilePath: \web-pc\src\pages\big-screen\view\home.vue
+-->
+<template>
+   
+    <div class="iframe-container">  
+     <iframe :src="iframeUrl" frameborder="0" class="fill-container"></iframe>  
+   </div> 
+   </template>
+ 
+ <script>
+ //import { formatTime } from "../../../../utils/deviceVision.js";
+ 
+ export default {
+
+   data() {
+     return {
+       timing: null,
+       loading: true,
+       dateDay: null,
+       dateYear: null,
+       dateWeek: null,
+       weekday: ["周日", "周一", "周二", "周三", "周四", "周五", "周六"],
+       iframeUrl:"http://47.101.220.106:8011?ss=1"
+     };
+   },
+   filters: {
+     numsFilter(msg) {
+       return msg || 0;
+     },
+   },
+   computed: {},
+   created() {},
+   mounted() {
+     this.timeFn();
+     this.cancelLoading();
+   },
+   beforeDestroy() {
+     clearInterval(this.timing);
+   },
+   methods: {
+     timeFn() {
+       this.timing = setInterval(() => {
+         //this.dateDay = formatTime(new Date(), "HH: mm: ss");
+         //this.dateYear = formatTime(new Date(), "yyyy-MM-dd");
+         this.dateWeek = this.weekday[new Date().getDay()];
+       }, 1000);
+     },
+     cancelLoading() {
+       let timer = setTimeout(() => {
+         this.loading = false;
+         clearTimeout(timer);
+       }, 500);
+     },
+   },
+ };
+ </script>
+ 
+ 
+ <style scoped>  
+ .iframe-container {  
+   /* 根据需要设置容器的样式 */  
+   width: 100%; /* 如果需要的话,设置容器的宽度 */  
+   height: 100vh; /* 设置容器的高度为视口高度的100% */  
+   /* 注意:如果有其他元素在页面上,你可能需要调整这个值 */  
+   display: flex; /* 使用Flexbox来确保iframe填充整个容器 */  
+   justify-content: center; /* 水平居中iframe(如果需要的话) */  
+   align-items: stretch; /* 垂直方向也尝试填充(但iframe内容可能不会响应) */  
+   overflow: hidden; /* 隐藏超出容器的iframe内容(如果需要的话) */  
+   position: relative; /* 如果需要绝对定位iframe或其他子元素 */  
+ }  
+   
+ .fill-container {  
+   width: 100%; /* 填充容器的宽度 */  
+   height: 100%; /* 填充容器的高度 */  
+   border: none; /* 移除边框(如果需要的话) */  
+   display: block; /* 确保iframe是块级元素 */  
+ }  
+ </style>

+ 1 - 0
admin.ui.plus-master/src/views/admin/workbench/index.vue

@@ -559,6 +559,7 @@ const initData = async () => {
   lineChart.value.option.series[3].data = getSeriesData(data.chart?.recordVaporRecovery)
   pieChart.getName = pieChartGetName(mainboardChart)
   pieChart.getValue = pieChartGetValue(mainboardChart)
+  debugger
   state.loading = false
 }
 

Niektoré súbory nie sú zobrazené, pretože je v týchto rozdielových dátach zmenené mnoho súborov