Parcourir la source

feat:整合设备可视化数据大屏

xianna.liang il y a 1 an
Parent
commit
6302fa35f6
48 fichiers modifiés avec 6440 ajouts et 1134 suppressions
  1. 43 9
      admin.ui.plus-master/package-lock.json
  2. 4 2
      admin.ui.plus-master/package.json
  3. 179 0
      admin.ui.plus-master/src/api/newDeviceVision/api.js
  4. 46 0
      admin.ui.plus-master/src/api/newDeviceVision/index.js
  5. 99 0
      admin.ui.plus-master/src/api/newDeviceVision/modules/index.js
  6. 36 0
      admin.ui.plus-master/src/config/UtilVar.js
  7. 429 0
      admin.ui.plus-master/src/lib/currency.js
  8. 93 0
      admin.ui.plus-master/src/lib/dd-moment.js
  9. 9 0
      admin.ui.plus-master/src/lib/index.js
  10. 46 0
      admin.ui.plus-master/src/lib/types.js
  11. 14 1
      admin.ui.plus-master/src/main.ts
  12. 1108 1108
      admin.ui.plus-master/src/router/route.ts
  13. 37 0
      admin.ui.plus-master/src/stores/newDeviceVision/index.js
  14. 56 0
      admin.ui.plus-master/src/stores/newDeviceVision/modules/setting.js
  15. 265 0
      admin.ui.plus-master/src/theme/newDeviceVision/home.scss
  16. 23 0
      admin.ui.plus-master/src/theme/newDeviceVision/iconfont/iconfont.css
  17. BIN
      admin.ui.plus-master/src/theme/newDeviceVision/iconfont/iconfont.ttf
  18. BIN
      admin.ui.plus-master/src/theme/newDeviceVision/iconfont/iconfont.woff
  19. BIN
      admin.ui.plus-master/src/theme/newDeviceVision/iconfont/iconfont.woff2
  20. 361 0
      admin.ui.plus-master/src/theme/newDeviceVision/index.scss
  21. 200 0
      admin.ui.plus-master/src/theme/newDeviceVision/modules/reset.scss
  22. 98 0
      admin.ui.plus-master/src/theme/newDeviceVision/modules/variables.scss
  23. 156 0
      admin.ui.plus-master/src/theme/newDeviceVision/public.scss
  24. BIN
      admin.ui.plus-master/src/theme/newDeviceVision/theme/fonts/element-icons.ttf
  25. BIN
      admin.ui.plus-master/src/theme/newDeviceVision/theme/fonts/element-icons.woff
  26. 0 0
      admin.ui.plus-master/src/theme/newDeviceVision/theme/index.css
  27. 50 0
      admin.ui.plus-master/src/theme/newDeviceVision/variable.scss
  28. 18 0
      admin.ui.plus-master/src/theme/newDeviceVision/webfont/index.css
  29. 75 0
      admin.ui.plus-master/src/utils/newDeviceVision/drawMixin.js
  30. 58 0
      admin.ui.plus-master/src/utils/newDeviceVision/index.js
  31. 0 0
      admin.ui.plus-master/src/utils/newDeviceVision/map/china.json
  32. 217 0
      admin.ui.plus-master/src/utils/newDeviceVision/map/xzqCode.js
  33. 72 0
      admin.ui.plus-master/src/views/admin/visualization/newDeviceVision/components/echart/index.vue
  34. 90 0
      admin.ui.plus-master/src/views/admin/visualization/newDeviceVision/components/item-wrap/item-wrap.vue
  35. 21 0
      admin.ui.plus-master/src/views/admin/visualization/newDeviceVision/components/kong.vue
  36. 45 0
      admin.ui.plus-master/src/views/admin/visualization/newDeviceVision/components/reacquire/reacquire.vue
  37. 279 0
      admin.ui.plus-master/src/views/admin/visualization/newDeviceVision/components/scale-screen/scale-screen.vue
  38. 126 0
      admin.ui.plus-master/src/views/admin/visualization/newDeviceVision/home.vue
  39. 393 0
      admin.ui.plus-master/src/views/admin/visualization/newDeviceVision/indexs/center-map.vue
  40. 145 0
      admin.ui.plus-master/src/views/admin/visualization/newDeviceVision/indexs/index.vue
  41. 242 0
      admin.ui.plus-master/src/views/admin/visualization/newDeviceVision/indexs/left-bottom.vue
  42. 242 0
      admin.ui.plus-master/src/views/admin/visualization/newDeviceVision/indexs/left-center.vue
  43. 257 0
      admin.ui.plus-master/src/views/admin/visualization/newDeviceVision/indexs/left-top.vue
  44. 192 0
      admin.ui.plus-master/src/views/admin/visualization/newDeviceVision/indexs/right-bottom.vue
  45. 195 0
      admin.ui.plus-master/src/views/admin/visualization/newDeviceVision/indexs/right-center.vue
  46. 292 0
      admin.ui.plus-master/src/views/admin/visualization/newDeviceVision/indexs/right-top.vue
  47. 102 0
      admin.ui.plus-master/src/views/admin/visualization/newDeviceVision/setting.vue
  48. 27 14
      admin.ui.plus-master/tsconfig.json

+ 43 - 9
admin.ui.plus-master/package-lock.json

@@ -21,7 +21,7 @@
         "countup.js": "^2.6.2",
         "cropperjs": "^1.5.13",
         "date-fns": "^3.6.0",
-        "echarts": "^5.5.0",
+        "echarts": "^5.5.1",
         "echarts-gl": "^2.0.9",
         "echarts-wordcloud": "^2.1.0",
         "element-plus": "^2.4.3",
@@ -48,7 +48,9 @@
         "vue-echarts": "^6.7.3",
         "vue-grid-layout": "^3.0.0-beta1",
         "vue-i18n": "^9.2.2",
-        "vue-router": "^4.2.2"
+        "vue-router": "^4.2.2",
+        "vue3-seamless-scroll": "^2.0.1",
+        "vuex": "^4.0.2"
       },
       "devDependencies": {
         "@types/node": "^20.3.1",
@@ -2411,12 +2413,13 @@
       }
     },
     "node_modules/echarts": {
-      "version": "5.5.0",
-      "resolved": "https://registry.npmjs.org/echarts/-/echarts-5.5.0.tgz",
-      "integrity": "sha512-rNYnNCzqDAPCr4m/fqyUFv7fD9qIsd50S6GDFgO1DxZhncCsNsG7IfUlAlvZe5oSEQxtsjnHiUuppzccry93Xw==",
+      "version": "5.5.1",
+      "resolved": "https://registry.npmmirror.com/echarts/-/echarts-5.5.1.tgz",
+      "integrity": "sha512-Fce8upazaAXUVUVsjgV6mBnGuqgO+JNDlcgF79Dksy4+wgGpQB2lmYoO4TSweFg/mZITdpGHomw/cNBJZj1icA==",
+      "license": "Apache-2.0",
       "dependencies": {
         "tslib": "2.3.0",
-        "zrender": "5.5.0"
+        "zrender": "5.6.0"
       }
     },
     "node_modules/echarts-gl": {
@@ -4912,6 +4915,15 @@
       "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==",
       "dev": true
     },
+    "node_modules/throttle-debounce": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmmirror.com/throttle-debounce/-/throttle-debounce-5.0.0.tgz",
+      "integrity": "sha512-2iQTSgkkc1Zyk0MeVrt/3BvuOXYPl/R8Z0U2xxo9rjwNciaHDG3R+Lm6dh4EeUci49DanvBnuqI6jshoQQRGEg==",
+      "license": "MIT",
+      "engines": {
+        "node": ">=12.22"
+      }
+    },
     "node_modules/tiny-emitter": {
       "version": "2.1.0",
       "resolved": "https://registry.npmmirror.com/tiny-emitter/-/tiny-emitter-2.1.0.tgz",
@@ -5381,6 +5393,27 @@
         "vue": "^3.2.0"
       }
     },
+    "node_modules/vue3-seamless-scroll": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmmirror.com/vue3-seamless-scroll/-/vue3-seamless-scroll-2.0.1.tgz",
+      "integrity": "sha512-mI3BaDU3pjcPUhVSw3/xNKdfPBDABTi/OdZaZqKysx4cSdNfGRbVvGNDzzptBbJ5S7imv5T55l6x/SqgnxKreg==",
+      "license": "MIT",
+      "dependencies": {
+        "throttle-debounce": "5.0.0"
+      }
+    },
+    "node_modules/vuex": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmmirror.com/vuex/-/vuex-4.0.2.tgz",
+      "integrity": "sha512-M6r8uxELjZIK8kTKDGgZTYX/ahzblnzC4isU1tpmEuOIIKmV+TRdc+H4s8ds2NuZ7wpUTdGRzJRtoj+lI+pc0Q==",
+      "license": "MIT",
+      "dependencies": {
+        "@vue/devtools-api": "^6.0.0-beta.11"
+      },
+      "peerDependencies": {
+        "vue": "^3.0.2"
+      }
+    },
     "node_modules/web-streams-polyfill": {
       "version": "3.2.1",
       "resolved": "https://registry.npmmirror.com/web-streams-polyfill/-/web-streams-polyfill-3.2.1.tgz",
@@ -5556,9 +5589,10 @@
       }
     },
     "node_modules/zrender": {
-      "version": "5.5.0",
-      "resolved": "https://registry.npmjs.org/zrender/-/zrender-5.5.0.tgz",
-      "integrity": "sha512-O3MilSi/9mwoovx77m6ROZM7sXShR/O/JIanvzTwjN3FORfLSr81PsUGd7jlaYOeds9d8tw82oP44+3YucVo+w==",
+      "version": "5.6.0",
+      "resolved": "https://registry.npmmirror.com/zrender/-/zrender-5.6.0.tgz",
+      "integrity": "sha512-uzgraf4njmmHAbEUxMJ8Oxg+P3fT04O+9p7gY+wJRVxo8Ge+KmYv0WJev945EH4wFuc4OY2NLXz46FZrWS9xJg==",
+      "license": "BSD-3-Clause",
       "dependencies": {
         "tslib": "2.3.0"
       }

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

@@ -25,7 +25,7 @@
     "countup.js": "^2.6.2",
     "cropperjs": "^1.5.13",
     "date-fns": "^3.6.0",
-    "echarts": "^5.5.0",
+    "echarts": "^5.5.1",
     "echarts-gl": "^2.0.9",
     "echarts-wordcloud": "^2.1.0",
     "element-plus": "^2.4.3",
@@ -52,7 +52,9 @@
     "vue-echarts": "^6.7.3",
     "vue-grid-layout": "^3.0.0-beta1",
     "vue-i18n": "^9.2.2",
-    "vue-router": "^4.2.2"
+    "vue-router": "^4.2.2",
+    "vue3-seamless-scroll": "^2.0.1",
+    "vuex": "^4.0.2"
   },
   "devDependencies": {
     "@types/node": "^20.3.1",

+ 179 - 0
admin.ui.plus-master/src/api/newDeviceVision/api.js

@@ -0,0 +1,179 @@
+
+/*
+ * @LastEditors: Please set LastEditors
+ * @LastEditTime: 2023-08-02 14:58:23
+ */
+
+/* 截拦器 -- 固定格式? 
+ * 1、添加 请求 截拦器
+ * 2、添加 响应 截拦器
+ * 
+ */
+
+import axios from 'axios';
+import UtilVar from "/@/config/UtilVar.js";
+// import router from '/@/router'
+
+let baseUrl = UtilVar.baseUrl
+const CancelToken = axios.CancelToken;
+export { baseUrl };
+// axios.defaults.withCredentials = true;
+// 添加请求拦截器
+axios.interceptors.request.use(function (config) {
+    // 在发送请求之前做些什么 传token  -- 本地存储的token
+    let token = localStorage.getItem("token");
+    // -- 修改请求头的 类型和token值。config为请求需要发送的数据
+    config.headers['Content-Type'] = "application/json;charset=utf-8";
+    config.headers['token'] = token;  //Authorization
+    return config;
+}, function (error) {
+    // 对请求错误做些什么
+    console.log(error)
+    return Promise.reject(error);
+});
+/**
+ * @响应拦截
+ */
+axios.interceptors.response.use(response => {
+  
+    // -- status返回200,则响应成功
+    if (response.status !== 200) {
+        return Promise.reject(response)
+    }
+      /**
+     * @code 登录过期 token验证失败 根据后端调 
+     */
+    if (response.data.code == UtilVar.code) {
+        // router.push("/login")
+    }
+    return response.data
+}, error => {
+    console.error(error);
+    let err = {
+        success: false,
+        msg: "未知异常,请联系管理员!"
+    }
+    return Promise.reject(err)
+})
+
+let configs_ENC = {
+    headers: { 'enc': UtilVar.ENC }
+}
+//处理是否加密数据
+let isEncryptionParam = (params) => {
+    return params
+
+}
+export const GET = async (url, params) => {
+    try {
+        params = isEncryptionParam(params)
+        const data = await axios.get(`${baseUrl}${url}`, {
+            params: params,
+            headers: configs_ENC.headers
+        }, configs_ENC);
+        return data;
+    } catch (error) {
+        return error;
+    }
+}
+//没有基地址 访问根目录下文件
+
+export const GETNOBASE = async (url, params) => {
+    try {
+        const data = await axios.get(url, {
+            params: params,
+        });
+        return data;
+    } catch (error) {
+        return error;
+    }
+}
+export const POST = async (url, params) => {
+    try {
+        console.log("baseUrl "+baseUrl);
+        params = isEncryptionParam(params)
+        const data = await axios.post(`${baseUrl}${url}`, params, configs_ENC);
+        return data;
+    } catch (error) {
+        return error;
+    }
+}
+export const PUT = async (url, params) => {
+    try {
+        params = isEncryptionParam(params)
+        const data = await axios.put(`${baseUrl}${url}`, params, configs_ENC);
+        return data;
+    } catch (error) {
+        return error;
+    }
+}
+export const DELETE = async (url, params) => {
+    // console.log(params)
+    try {
+        params = isEncryptionParam(params)
+        const data = await axios.delete(`${baseUrl}${url}`, { data: params, headers: configs_ENC.headers }, configs_ENC);
+        return data;
+    } catch (error) {
+        return error;
+    }
+}
+
+
+/**
+ * @文件类型提交方法
+ */
+let configs = {
+    headers: { 'Content-Type': 'multipart/form-data' },
+
+}
+export const FILESubmit = async (url, params, config) => {
+    try {
+        const data = await axios.post(`${baseUrl}${url}`, params, {
+            ...configs,
+            cancelToken: new CancelToken(function executor(c) {
+                config.setCancel && config.setCancel(c)
+            }),
+            onUploadProgress: (e) => {
+                if (e.total > 0) {
+                    e.percent = e.loaded / e.total * 100;
+                }
+                // console.log(config)
+                config.onProgress && config.onProgress(e)
+            },
+
+        });
+        return data;
+    } catch (err) {
+        return err;
+    }
+}
+
+/**
+ * 下载文档流
+ * @param {config.responseType} 下载文件流根据后端 配置   arraybuffer || blod
+ */
+// -- 参数config,类型为responseTyle - 下载文档流
+export const FILE = async (config = {}, body, params) => {
+    try {
+        const data = await axios({
+            method: config.method || 'get',
+            url: `${baseUrl}${config.url}`,
+            data: body,
+            params: params,
+            responseType: config.responseType || 'blob',
+            onDownloadProgress: (e) => {
+                // console.log(e,e.currentTarget)
+                // if (e.currentTarget.response.size > 0) {
+                //     e.percent = e.loaded / e.currentTarget.response.size * 100;
+                // }
+                // event.srcElement.getResponseHeader('content-length')
+                config.onProgress && config.onProgress(e)
+            },
+        });
+        return data;
+    } catch (err) {
+        return err;
+    }
+}
+
+

+ 46 - 0
admin.ui.plus-master/src/api/newDeviceVision/index.js

@@ -0,0 +1,46 @@
+/*
+ * @Author: daidai
+ * @Date: 2021-12-09 10:47:56
+ * @LastEditors: Please set LastEditors
+ * @LastEditTime: 2022-04-27 16:32:31
+ * @FilePath: \web-pc\src\api\index.js
+ */
+
+
+import {    currentList,
+    currentPage,
+    currentSave,
+    currentUpdate,
+    currentDelete,
+    currentSelect,
+    currentSelectList,
+
+    currentPOST,
+    currentGET,
+    currentApi
+
+} from './modules'
+import { 
+    GETNOBASE,
+    GET
+} from './api'
+
+
+export {
+    GETNOBASE,
+    GET
+}
+
+
+export {
+    currentApi,
+    currentList,
+    currentPage,
+    currentSave,
+    currentUpdate,
+    currentDelete,
+    currentSelect,
+    currentSelectList,
+    currentPOST,
+    currentGET
+}

+ 99 - 0
admin.ui.plus-master/src/api/newDeviceVision/modules/index.js

@@ -0,0 +1,99 @@
+/*
+ * @Author: daidai
+ * @Date: 2021-12-23 11:18:37
+ * @LastEditors: Please set LastEditors
+ * @LastEditTime: 2022-04-28 15:10:45
+ * @FilePath: \web-pc\src\api\modules\index.js
+ */
+import * as API from "../api";
+
+export const paramType ={
+    'big1':"/api/app/device-vision/get-device-status", //设备状态
+    'big2':"/api/app/device-vision/get-device-overview", //设备总览 
+    'big3':"/api/app/device-vision/get-device", //设备提醒
+    'big4':"/api/app/device-vision/get-alarm-count", //报警次数
+    'big5':'/api/app/device-vision/get-generate-data-chart',//实时预警 
+    'big6':'/bigscreen/installationPlan',// 安装计划
+    'big7':'/bigscreen/ranking',// 报警排名
+    'big8':'/bigscreen/centermap',// //中间地图
+
+}
+/******************      通用增删改查       ********************* */
+/**
+ * 通用列表
+ * @param {*} param 
+ */
+ export const currentList =  (key,param)=> {
+    return API.GET(paramType[key]+"/list", param)
+}
+export const currentPage =  (key,param)=> {
+    return API.GET(paramType[key]+"/page", param)
+}
+/**
+ * 查询可选择的列表
+ * @param {*} param 
+ */
+ export const currentSelectList=  (key,param)=> {
+    return API.GET(paramType[key]+"/selectList", param)
+}
+
+
+/**
+ * 通用新增
+ * @param {*} param 
+ */
+ export const currentSave= (key,param)=> {
+    return API.POST(paramType[key]+"/save", param)
+}
+/**
+ * 通用修改
+ * @param {*} param 
+ */
+ export const currentUpdate=  (key,param) => {
+    return API.POST(paramType[key]+"/update", param)
+}
+
+/**
+ * 通用删除
+ * @param {*} param 
+ */
+ export const currentDelete= (key,param) => {
+    return API.POST(paramType[key]+"/delete", param)
+}
+
+/**
+ * 通用获取所有不分页
+ * @param {*} param 
+ */
+ export const currentSelect=  (key,param)=> {
+    return API.GET(paramType[key]+"/select", param)
+}
+
+/**
+ * 通用GET
+ * @param {*} param 
+ */
+ export const currentGET=  (key,param)=> {
+    console.log("currentGET666"+paramType[key])
+    return API.GET(paramType[key], param)
+}
+/**
+ * 通用POST
+ * @param {*} param 
+ */
+ export const currentPOST=  (key,param)=> {
+    console.log("currentPOST"+paramType[key])
+    return API.POST(paramType[key], param)
+}
+// 通用接口集合
+export const currentApi={
+    currentList,
+    currentPage,
+    currentSave,
+    currentUpdate,
+    currentDelete,
+    currentSelect,
+    currentSelectList,
+    currentPOST,
+    currentGET
+}

+ 36 - 0
admin.ui.plus-master/src/config/UtilVar.js

@@ -0,0 +1,36 @@
+/*
+ * @Author: daidai
+ * @Date: 2021-12-06 10:58:24
+ * @LastEditors: Please set LastEditors
+ * @LastEditTime: 2023-08-02 14:56:12
+ * @FilePath: \web-pc\src\config\UtilVar.js
+ */
+let UtilVar = {
+    ENC: false, //返回结果是否加密
+    baseUrl: `http://47.101.220.106:8070`,
+    code: 401,
+}
+const runtimeType = {
+    production: () => {
+        /**
+         * 通过打包配置打某个环境的api地址
+         */
+        UtilVar.baseUrl = `http://47.101.220.106:8070`
+    },
+    //测试环境
+    test:()=>{
+
+    },
+    //开发环境
+    development: () => {
+      
+    },
+    
+}
+// console.log("查看一下")
+// console.log(process.env);
+
+//通过打包配置打某个环境的api地址
+// runtimeType[process.env.VUE_APP_URL_ENV]()
+export default UtilVar
+

+ 429 - 0
admin.ui.plus-master/src/lib/currency.js

@@ -0,0 +1,429 @@
+/*
+ * @Author: daidai
+ * @Date: 2021-12-06 15:53:24
+ * @LastEditors: Please set LastEditors
+ * @LastEditTime: 2022-04-22 09:31:24
+ * @FilePath: \web-pc\src\lib\currency.js
+ */
+import router from '@/router'
+import { isString, isHtmlElement } from './types'
+import UtilVar from "@/config/UtilVar";
+export const returnWeek = () => {
+  var week = new Date().getDay();
+  switch (week) {
+    case 1:
+      return '周一'
+    case 2:
+      return '周二'
+    case 3:
+      return '周三'
+    case 4:
+      return '周四'
+    case 5:
+      return '周五'
+    case 6:
+      return '周六'
+    case 0:
+      return '周日'
+  }
+}
+
+/**
+ * 获取uuid
+ */
+export function getUUID() {
+  return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => {
+    return (c === 'x' ? (Math.random() * 16 | 0) : ('r&0x3' | '0x8')).toString(16)
+  })
+}
+
+/**
+ * 是否有权限
+ * @param {*} key
+ */
+export function isAuth(key) {
+  // console.log("key",key,sessionStorage.getItem('permissions'))
+  return JSON.parse(sessionStorage.getItem('permissions') || '[]').indexOf(key) !== -1 || false
+}
+export const rowClassName = ({ row, rowIndex }) => {
+  if (rowIndex % 2 == 0) {
+    return 'lightColour';
+  } else {
+    return 'DarkColor';
+  }
+}
+
+export const getToken = () => {
+  return localStorage.getItem("token");
+}
+//跳转当前页面并传参
+export const currentQuery = (param) => {
+  let newParam = { ...param }
+  for (let i in newParam) {
+    if (newParam[i] === "") {
+      delete newParam[i]
+    }
+  }
+  // console.log(newParam)
+  router.push({
+    path: router.currentRoute.path,
+    query: newParam
+  })
+}
+/**
+ * 树形数据转换
+ * @param {*} data
+ * @param {*} id
+ * @param {*} pid
+ * @param {*} order
+ */
+export function treeDataTranslate(data, id, pid, order) {
+  // console.log(Array.isArray(data))
+  if (data == null || !Array.isArray(data)) {
+    return [];
+  }
+  if (order) {
+    data.sort(function (a, b) {
+      return a[order] - b[order];
+    })
+  }
+  // console.log(data)
+  var res = []
+  var temp = {}
+  for (var i = 0; i < data.length; i++) {
+    temp[data[i][id]] = data[i]
+  }
+  for (var k = 0; k < data.length; k++) {
+
+    if (temp[data[k][pid]] && data[k][id] !== data[k][pid]) {
+      if (!temp[data[k][pid]]['subs']) {
+        temp[data[k][pid]]['subs'] = []
+      }
+      if (!temp[data[k][pid]]['_level']) {
+        temp[data[k][pid]]['_level'] = 1
+      }
+      data[k]['_level'] = temp[data[k][pid]]._level + 1
+      temp[data[k][pid]]['subs'].push(data[k])
+
+
+    } else {
+      res.push(data[k])
+    }
+  }
+  // console.log(outurls)
+  // console.log(res)
+  return res
+}
+
+//带了一个 margin-left  
+export const dragss = (e, marginleft) => {
+
+  let odiv = e.currentTarget.parentElement;
+  let disX = e.clientX - odiv.offsetLeft;
+  let disY = e.clientY - odiv.offsetTop;
+  document.onmousemove = (e) => {
+    odiv.style.left = e.clientX - disX + marginleft + 'px';
+    odiv.style.top = e.clientY - disY + 'px';
+    return false;
+  };
+  document.onmouseup = (e) => {
+    document.onmousemove = null;
+    document.onmouseup = null;
+  };
+  return false;
+}
+
+//转base64
+
+export const turnStr = (data) => {
+  return window.btoa(window.encodeURI(JSON.stringify(data)));
+}
+// 验证只能输入数字和小数,小数且只能输入2位,第一位不能输入小数点
+//   .replace(/[^\d.]/g, '')
+//   .replace(/\.{2,}/g, '.')
+//   .replace('.', '$#$')
+//   .replace(/\./g, '')
+//   .replace('$#$', '.')
+//   .replace(/^(\-)*(\d+)\.(\d\d).*$/, '$1$2.$3')
+//   .replace(/^\./g, '')
+/**
+ * 清除登录信息
+ */
+export function clearLoginInfo() {
+  router.options.isAddDynamicMenuRoutes = false;
+  localStorage.removeItem('token')
+  sessionStorage.removeItem("menuList")
+  sessionStorage.removeItem("permissions")
+}
+
+
+//对象拼成路径传参
+export const convertObj = (data) => {
+  var _result = [];
+  for (var key in data) {
+    var value = data[key];
+    if (value.constructor == Array) {
+      value.forEach(function (_value) {
+        _result.push(key + "=" + _value);
+      });
+    } else {
+      _result.push(key + '=' + value);
+    }
+  }
+  return _result.join('&');
+}
+//判断浏览器
+function getExplorer() {
+  var explorer = window.navigator.userAgent;
+  if (explorer.indexOf('MSIE') >= 0) {
+    return 'ie';        // ie
+  } else if (explorer.indexOf('Firefox') >= 0) {
+    return 'Firefox';   // firefox
+  } else if (explorer.indexOf('Chrome') >= 0) {
+    return 'Chrome';    // Chrome
+  } else if (explorer.indexOf('Opera') >= 0) {
+    return 'Opera';     // Opera
+  } else if (explorer.indexOf('Safari') >= 0) {
+    return 'Safari';    // Safari
+  } else if (!!explorer.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/)) {
+    return 'IOS';
+  } else if (u.indexOf('Android') > -1 || u.indexOf('Adr') > -1) {
+    return 'Android';
+  } else {
+    return explorer
+  }
+};
+
+//导出文档流
+export const exportFile = (data, name) => {
+  return new Promise((resolve, reject) => {
+    let types = getExplorer()
+    if (types == 'IOS') {
+      resolve({
+        success: false,
+        msg: "请使用设备自带浏览器导出!"
+      })
+      return
+    }
+    if (data.type && data.type.indexOf('application/vnd.ms-excel') >= 0) {
+      // console.log(data)
+      try {
+        let blob = new Blob([data], {
+          type:data.type|| 'application/vnd.ms-excel;charset=UTF-8'
+        })
+        if (window.navigator && window.navigator.msSaveOrOpenBlob) {
+          window.navigator.msSaveOrOpenBlob(blob, name);
+        } else {
+          const link = document.createElement('a')
+          link.style.display = 'none';
+          link.href = URL.createObjectURL(blob);
+          if (types == 'Safari') {
+            link.download = `${name || "未命名"}`;
+          } else {
+            link.download = `${name || "未命名"}.xlsx`;
+          }
+          // Safari thinks _blank anchor are pop ups. We only want to set _blank
+          // target if the browser does not support the HTML5 download attribute.
+          // This allows you to download files in desktop safari if pop up blocking
+          // is enabled.
+          if (typeof link.download === 'unde fined') {
+            tempLink.setAttribute('target', '_blank');
+          }
+          document.body.appendChild(link)
+          link.click()
+          // Fixes "webkit blob resource error 1"
+          let timer = setTimeout(function () {
+            document.body.removeChild(link)
+            window.URL.revokeObjectURL(link.href);
+            clearTimeout(timer)
+          }, 200)
+        }
+        resolve({
+          success: true,
+          msg: "导出成功"
+        })
+      } catch (error) {
+        resolve({
+          success: false,
+          msg: "未知异常,请联系管理员!"
+        })
+      }
+    } else {
+      // console.log(data)
+       readFile(data).then(res => {
+        resolve(res)
+      }).catch(err => {
+        resolve({
+          success: false,
+          msg: "未知异常,请联系管理员!"
+        })
+      })
+    }
+  })
+
+}
+//阅读 blod
+export const readFile = (data) => {
+  return new Promise((resole, reject) => {
+    if (Object.prototype.toString.call(data)==='[object Blob]') {
+      let reader = new FileReader()
+      reader.readAsText(data, 'utf-8')
+      reader.onload = (e) => {
+        console.log('--导出--', JSON.parse(reader.result))
+        let result = JSON.parse(reader.result)
+        if (result.code == UtilVar.code) {
+          router.push("/login")
+        }
+        resole(result)
+      }
+    } else {
+      resole(data)
+    }
+
+    // reader.readAsText(data)
+  })
+
+}
+
+//element 时间选择
+
+
+
+export const shortcuts = [{
+  text: '最近一周',
+  onClick(picker) {
+    const end = new Date();
+    const start = new Date();
+    start.setTime(start.getTime() - 3600 * 1000 * 24 * 7);
+    picker.$emit('pick', [start, end]);
+  }
+}, {
+  text: '最近一个月',
+  onClick(picker) {
+    const end = new Date();
+    const start = new Date();
+    start.setTime(start.getTime() - 3600 * 1000 * 24 * 30);
+    picker.$emit('pick', [start, end]);
+  }
+}, {
+  text: '最近三个月',
+  onClick(picker) {
+    const end = new Date();
+    const start = new Date();
+    start.setTime(start.getTime() - 3600 * 1000 * 24 * 89);
+    picker.$emit('pick', [start, end]);
+  }
+}]
+export const pickerOptions = {
+  shortcuts: shortcuts
+}
+/**
+ * 清除相同
+ * @param {*} origin
+ * @param {*} target
+ */
+export const ArrayCleanRepeat = (origin, target) => {
+  if (target) origin = origin.concat(target);
+  const result = []
+  const tagObj = {}
+  for (const i of origin) {
+    if (!tagObj[i]) {
+      result.push(i)
+      tagObj[i] = 1
+    }
+  }
+  return result
+}
+/**
+ * @description: 
+ * @param {file:Object} 文件
+ * @return {*}
+ */
+export const beforeUpoads = (file) => {
+  // console.log(file)
+  var testmsg = file.name.substring(file.name.lastIndexOf('.') + 1)
+  if (
+    testmsg != 'png' &&
+    testmsg != 'jpg' &&
+    testmsg != 'jpeg' &&
+    testmsg != 'webp'
+  ) {
+    // testmsg != 'gif' &&
+    return {
+      success: false,
+      msg: "上传图片格式不正确!"
+    }
+  }
+  const if10M = file.size / 1024 / 1024 < 20
+  if (!if10M) {
+    return {
+      success: false,
+      msg: "上传图片大小不能超过20M!"
+    }
+  }
+  // console.log("上传前",file, this.filelist)
+  return {
+    success: true
+  }
+}
+//复制文字
+export const copy = (value) => {
+  let transfer = document.createElement('input')
+
+  document.body.appendChild(transfer)
+  transfer.value = value // 这里表示想要复制的内容
+  transfer.focus()
+  transfer.select()
+  if (document.execCommand('copy')) {
+    document.execCommand('copy')
+  }
+  transfer.blur()
+  document.body.removeChild(transfer)
+  //选中文字
+  //   let range = document.createRange()
+  //   let referenceNode = this.$refs.xy
+  //   range.selectNodeContents(referenceNode)
+  //   var selection = window.getSelection()
+  //   selection.removeAllRanges()
+  //   selection.addRange(range)
+}
+// 取出两个数组的不同元素
+export const getArrDifference = (arr1, arr2) => {
+  return arr1.concat(arr2).filter(function (v, i, arr) {
+    return arr.indexOf(v) === arr.lastIndexOf(v);
+  });
+}
+
+/**
+ * 表格最大高度
+ * @param {ElementDom} dom 
+ * @param {Boolean} isPaging 是否拥有分页 false 没有 ||  true 有 默认有
+ * @returns 
+ */
+export const tableHeight = (dom,isPaging=true) => {
+  //定位父级到文档高度
+  if (isString(dom)) {
+    dom = document.querySelector(dom)
+    // if (dom) {
+    //   return window.innerHeight - top
+    // }
+  }
+  if (isHtmlElement(dom)) {
+    var parent = dom.offsetParent;
+    var top = dom.offsetTop
+    if(isPaging){
+      top= top+ 63 + 4
+    }else{
+      top= top+ 16
+    }
+    while (parent != null) {
+      top += parent.offsetTop;
+      parent = parent.offsetParent;
+    };
+    return window.innerHeight - top
+  }
+
+  return null
+}
+
+//

+ 93 - 0
admin.ui.plus-master/src/lib/dd-moment.js

@@ -0,0 +1,93 @@
+
+/*
+ * @Author: daidai
+ * @Date: 2021-12-16 14:40:18
+ * @LastEditors: Please set LastEditors
+ * @LastEditTime: 2022-04-19 14:44:14
+ * @FilePath: \web-pc\src\lib\dd-moment.js
+ */
+
+
+const DDmoment = function (date) {
+    let time;
+    if (!date) {
+        time = new Date()
+    }else if(date){
+        time=new Date(date);
+    }
+    return {
+        time,
+        format,
+        subtract,
+        getTime,
+    }
+}
+/**
+ * @content 前多少天
+ * @param  days  天 ||  years 年  || months 月 ||  weeks 周 
+ * @returns 
+ */
+function subtract(num, type) {
+    let time = this.time
+    time.setTime(time.getTime()-getNeedTime(num, type))
+    time=new Date(time)
+    return {
+        time,
+        format,
+        getTime
+    }
+}
+/**
+ * @param  Yy年  ||  M 月  || Dd 日 ||  Hh 时 || m 分 || Ss 秒
+ * @returns 
+ */
+function format(fmt) {
+    let date = this.time
+    let ret;
+    const opt = {
+        "Y+": date.getFullYear().toString(),        // 年
+        "y+": date.getFullYear().toString(),        // 年
+        "M+": (date.getMonth() + 1).toString(),     // 月
+        "d+": date.getDate().toString(),            // 日
+        "D+": date.getDate().toString(),            // 日
+        "h+": date.getHours().toString(),           // 时
+        "H+": date.getHours().toString(),           // 时
+        "m+": date.getMinutes().toString(),         // 分
+        "S+": date.getSeconds().toString(),         // 秒
+        "s+": date.getSeconds().toString()          // 秒
+        // 有其他格式化字符需求可以继续添加,必须转化成字符串
+    };
+    for (let k in opt) {
+        ret = new RegExp("(" + k + ")").exec(fmt);
+        if (ret) {
+            fmt = fmt.replace(ret[1], (ret[1].length == 1) ? (opt[k]) : (opt[k].padStart(ret[1].length, "0")))
+        };
+    };
+    return fmt;
+}
+//时间戳转时间
+function getTime() {
+    return new Date(this.time)
+}
+//获取需要的时间
+function getNeedTime(num, type) {
+    let time=0
+    switch (type) {
+        case "days":
+            time= 3600 * 1000 * 24 * num;
+            break;
+        case "years":
+            time=3600 * 1000 * 24 *365 *num;
+            break;
+        case "months":
+            time = 3600 * 1000 * 24 *30* num;
+            break;
+        case "weeks":
+            time= 3600 * 1000 * 24 *7* num;
+            break;
+        default:
+            break;
+    }
+    return time;
+}
+export default DDmoment

+ 9 - 0
admin.ui.plus-master/src/lib/index.js

@@ -0,0 +1,9 @@
+import DDmoment from "./dd-moment"
+import { colors,colors2 } from "./modules/echarts-options"
+import { shortcuts } from "./currency";
+
+export {DDmoment,colors,colors2}
+
+export {
+    shortcuts
+}

+ 46 - 0
admin.ui.plus-master/src/lib/types.js

@@ -0,0 +1,46 @@
+/*
+ * @Author: daidai
+ * @Date: 2021-12-14 09:15:11
+ * @LastEditors: Please set LastEditors
+ * @LastEditTime: 2022-04-25 10:11:04
+ * @FilePath: \web-pc\src\lib\types.js
+ */
+
+export function hasOwn(obj, key) {
+    return hasOwnProperty.call(obj, key);
+  };
+  export function isVNode(node) {
+    return node !== null && typeof node === 'object' && hasOwn(node, 'componentOptions');
+  };
+  
+// 是否字符串
+export function isString2(str) {
+    return (typeof str == 'string') && str.constructor == String;
+}
+export function isString(obj) {
+    return Object.prototype.toString.call(obj) === '[object String]';
+}
+export function isObject(obj) {
+    return Object.prototype.toString.call(obj) === '[object Object]';
+}
+export function isNumber(obj) {
+    return Object.prototype.toString.call(obj) === '[object Number]';
+}
+// 是否完整的
+export function isDef(val) {
+    return val !== undefined && val !== null;
+}
+//
+export function isKorean(text) {
+    const reg = /([(\uAC00-\uD7AF)|(\u3130-\u318F)])+/gi;
+    return reg.test(text);
+}
+
+export function isHtmlElement(node) {
+    return node && node.nodeType === Node.ELEMENT_NODE;
+}
+export const isUndefined = (val) => {
+    return val === void 0;
+};
+
+

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

@@ -10,11 +10,24 @@ 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 ECharts   from '/@/components/echart/index.vue'
 import DataVVue3 from '@kjgl77/datav-vue3'
 
+// 数据大屏 全局引用
+import ItemWrap from '/@/views/admin/visualization/newDeviceVision/components/item-wrap/item-wrap.vue'
+import Echart from '/@/views/admin/visualization/newDeviceVision/components/echart/index.vue'
+import Reacquire from '/@/views/admin/visualization/newDeviceVision/components/reacquire/reacquire.vue'
+// import store from './stores/newDeviceVision'
+
+
 const app = createApp(App)
 
+// 数据大屏 自定义组件
+app.component("ItemWrap",ItemWrap)
+app.component("Echart",Echart)
+app.component("Reacquire",Reacquire)
+
+
 directive(app)
 other.elSvg(app)
 

Fichier diff supprimé car celui-ci est trop grand
+ 1108 - 1108
admin.ui.plus-master/src/router/route.ts


+ 37 - 0
admin.ui.plus-master/src/stores/newDeviceVision/index.js

@@ -0,0 +1,37 @@
+/*
+ * @Author: your name
+ * @Date: 2021-07-26 09:32:49
+ * @LastEditTime: 2022-04-26 09:12:33
+ * @LastEditors: Please set LastEditors
+ * @Description: In User Settings Edit
+ * @FilePath: \web-pc\src\pages\big-screen\store\index.js
+ */
+import Vuex from 'vuex';
+import Vue from 'vue';
+
+Vue.use(Vuex)
+const modulesFiles = require.context('./modules', true, /\.js$/)
+const modules = modulesFiles.keys().reduce((modules, modulePath) => {
+  const moduleName = modulePath.replace(/^\.\/(.*)\.\w+$/, '$1')
+  const value = modulesFiles(modulePath)
+  modules[moduleName]=value.default
+  modules[moduleName].namespaced = true;   //打开命名空间
+  return modules
+}, {})
+export default store = new Vuex.Store({
+  modules,
+  state: {
+
+  },
+  mutations: {
+      setCollapsed(state,value){
+      },
+  },
+  actions: {
+    getUserdata({commit}){
+
+    },
+    
+  },
+  
+})

+ 56 - 0
admin.ui.plus-master/src/stores/newDeviceVision/modules/setting.js

@@ -0,0 +1,56 @@
+/*
+ * @Author: daidai
+ * @Date: 2021-12-06 11:01:16
+ * @LastEditors: Please set LastEditors
+ * @LastEditTime: 2022-04-28 15:01:33
+ * @FilePath: \web-pc\src\store\modules\menus.js
+ */
+import {isObject} from '/@/lib/types'
+export default {
+    state: {
+        sbtxSwiper: true,//设备提醒轮播
+        ssyjSwiper:true,//实时预警轮播
+        isScale:true,//是否进行全局适配
+        defaultOption: {
+            step: 4, // 数值越大速度滚动越快
+            hover: true, // 是否开启鼠标悬停stop
+            openWatch: true, // 开启数据实时监控刷新dom
+            direction: 1, // 0向下 1向上 2向左 3向右
+            limitMoveNum: 4, // 开始无缝滚动的数据量 this.dataList.length
+            singleHeight: 0, // 单步运动停止的高度(默认值0是无缝不停止的滚动) direction => 0/1
+            singleWidth: 0, // 单步运动停止的宽度(默认值0是无缝不停止的滚动) direction => 2/3
+            waitTime: 3000 // 单步运动停止的时间(默认值1000ms)
+          },
+       echartsAutoTime:3000000,//echarts 图自动请求接口时间
+    },
+    getters: {
+        //根据菜单路径获取 菜单信息
+    },
+    mutations: {
+        initSwipers(state){
+            let flags = JSON.parse(localStorage.getItem('settingData'))
+            // console.log(flags);
+            if(flags && isObject(flags)){
+               for (const key in flags) {
+                   if (state.hasOwnProperty.call(flags, key)&&flags.hasOwnProperty.call(flags, key)) {
+                       const element = flags[key];
+                       state[key]=element
+                   }
+               }
+            }
+        },
+        updateSwiper(state, {val,type}) {
+            state[type]=val
+            localStorage.setItem('settingData',JSON.stringify({
+                sbtxSwiper:state.sbtxSwiper,
+                ssyjSwiper:state.ssyjSwiper,
+                aztpSwiper:state.aztpSwiper,
+                isScale:state.isScale
+            }))
+        },
+
+    },
+    actions: {
+       
+    },
+} 

+ 265 - 0
admin.ui.plus-master/src/theme/newDeviceVision/home.scss

@@ -0,0 +1,265 @@
+.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;
+        // -- border-box告诉浏览器去理解你设置的边框和内边距的值是包含在width内的。默认为content-box,即边框和内边距的宽度都会增加到最后绘制出来的元素宽度中。
+        box-sizing: border-box;
+        // -- 整个页面的背景图
+        background-image: url("/src/assets/deviceVision/pageBg.png");
+        // -- 背景图保持纵横比,并将图片缩放成覆盖背景定位区域的最小值
+        background-size: cover;
+        background-position: center center;
+    }
+
+    .host-body {
+        height: 100%;
+
+        .title_wrap {
+            height: 60px;
+            background-image: url("/src/assets/deviceVision/top.png");
+            background-size: cover;
+            background-position: center center;
+            position: relative;
+            margin-bottom: 4px;
+
+            .guang {
+                position: absolute;
+                bottom: -26px;
+                background-image: url("/src/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("/src/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 {
+                    // -- 网页浏览时用户鼠标的样式或形状(crosshair:十字线;pointer:手指;text:文本光标;wait:程序正在忙--转圈加载图标)
+                    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)
+    }
+}

+ 23 - 0
admin.ui.plus-master/src/theme/newDeviceVision/iconfont/iconfont.css

@@ -0,0 +1,23 @@
+@font-face {
+  font-family: "iconfont"; /* Project id 2995337 */
+  src: url('iconfont.woff2?t=1638871675242') format('woff2'),
+       url('iconfont.woff?t=1638871675242') format('woff'),
+       url('iconfont.ttf?t=1638871675242') format('truetype');
+}
+
+/* .iconfont {
+  font-family: "iconfont" !important;
+  font-size: 16px;
+  font-style: normal;
+  -webkit-font-smoothing: antialiased;
+  -moz-osx-font-smoothing: grayscale;
+} */
+
+.blq-icon-shezhi01:before {
+  content: "\e610";
+}
+
+.blq-icon-shezhi02:before {
+  content: "\e611";
+}
+

BIN
admin.ui.plus-master/src/theme/newDeviceVision/iconfont/iconfont.ttf


BIN
admin.ui.plus-master/src/theme/newDeviceVision/iconfont/iconfont.woff


BIN
admin.ui.plus-master/src/theme/newDeviceVision/iconfont/iconfont.woff2


+ 361 - 0
admin.ui.plus-master/src/theme/newDeviceVision/index.scss

@@ -0,0 +1,361 @@
+@import "./modules/reset.scss";
+@import "./modules/variables.scss";
+@import './theme/index.css';
+@import './iconfont//iconfont.css';
+
+[class*=" blq-icon-"],
+[class^=blq-icon-] {
+  font-family: iconfont !important;
+  speak: none;
+  font-style: normal;
+  font-weight: 400;
+  font-variant: normal;
+  text-transform: none;
+  line-height: 1;
+  vertical-align: middle;
+  display: inline-block;
+  -webkit-font-smoothing: antialiased;
+  -moz-osx-font-smoothing: grayscale
+}
+
+*,
+:after,
+:before {
+  box-sizing: content-box;
+}
+
+.clearfix {
+  &::after {
+    content: "";
+    display: table;
+    height: 0;
+    line-height: 0;
+    visibility: hidden;
+    clear: both;
+  }
+}
+
+.contents {
+  width: 100%;
+  display: flex;
+  min-height: calc(100% - 60px);
+  justify-content: space-between;
+}
+
+.beautify-scroll-def {
+  overflow-y: auto;
+
+  &::-webkit-scrollbar-thumb {
+    //滚动条的设置
+    background-color: rgba(14, 59, 150, 0);
+    background-clip: padding-box;
+    border-radius: 4px;
+  }
+
+  &:hover {
+    &::-webkit-scrollbar-thumb {
+      //滚动条的设置
+      background-color: rgba(14, 59, 150, 0.5);
+      background-clip: padding-box;
+      border-radius: 4px;
+    }
+  }
+
+  &::-webkit-scrollbar-track-piece {
+    //滚动条凹槽的颜色,还可以设置边框属性
+    background-color: transparent;
+  }
+
+  &::-webkit-scrollbar {
+    //滚动条的宽度
+    width: 8px;
+    height: 8px;
+  }
+
+
+
+  &::-webkit-scrollbar-thumb:hover {
+    background-color: rgba(14, 59, 150, .8);
+  }
+}
+
+
+.orderNum {
+  // min-width: 22px;
+  // height: 22px;
+  // background: #00b8ff;
+  // border-radius: 50%;
+  // text-align: center;
+  // line-height: 22px;
+  // font-size: 13px;
+  // font-weight: 900;
+  // color: #0f2854;
+  color: #00b8ff;
+}
+
+.yh-big-input {
+  width: 253px;
+  height: 14px;
+  background: transparent;
+  border: 1px solid rgba(255, 255, 255, .53);
+  border-radius: 4px;
+  color: #fff;
+  padding: 6px 10px;
+  font-size: 14px;
+  transition: border-color 0.2s cubic-bezier(0.645, 0.045, 0.355, 1);
+
+  &:focus {
+    outline: none;
+    border-color: #31abe3;
+  }
+}
+
+.yh-big-el-input {
+  width: 253px;
+  font-size: 14px;
+
+  .el-input__inner {
+    padding: 6px 10px;
+    border: 1px solid rgba(255, 255, 255, .53);
+    background-color: transparent;
+    font-size: 14px;
+    line-height: 1;
+    color: #fff;
+    &:hover{
+      border-color: rgba(255, 255, 255, .8);
+    }
+    &:focus {
+      outline: none;
+      border-color: #31abe3;
+    }
+
+  }
+
+}
+
+.yh-big-button {
+  width: 53px;
+  height: 26px;
+  background: #00b1d6;
+  border-radius: 4px;
+  // border-color: #00b1d6;
+  border-width: 1px;
+  border: none;
+  cursor: pointer;
+  color: #fff;
+  font-size: 15px;
+
+  &:hover,
+  &:focus {
+    // border-color: #0597b4;
+    background: #0597b4;
+  }
+}
+
+
+//浮动
+.float-r {
+  float: right;
+}
+
+//浮动
+.float-l {
+  float: left;
+}
+
+// 字体加粗
+.fw-b {
+  font-weight: bold;
+}
+
+//文章一行显示,多余省略号显示
+.title-item {
+  overflow: hidden;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+}
+
+//表格样式重置
+.ve-table {
+  $border-color: #525371;
+  // $border-color: rgba(255, 255, 255, .43);
+  box-sizing: border-box;
+
+  .ve-table-container {
+    &::-webkit-scrollbar-track-piece {
+      //滚动条凹槽的颜色,还可以设置边框属性
+      background-color: transparent;
+    }
+
+    &::-webkit-scrollbar {
+      //滚动条的宽度
+      width: 8px;
+      height: 8px;
+    }
+
+    &::-webkit-scrollbar-thumb {
+      //滚动条的设置
+      background-color: rgba(14, 59, 150, 0.5);
+      background-clip: padding-box;
+      border-radius: 4px;
+    }
+
+    &::-webkit-scrollbar-thumb:hover {
+      background-color: rgba(14, 59, 150, .8);
+    }
+
+    .ve-table-content {
+      &::after {
+        content: "";
+        position: absolute;
+        top: 0;
+        right: 0px;
+        width: 1px;
+        height: 100%;
+        background-color: $border-color;
+        z-index: 20;
+
+      }
+    }
+
+  }
+
+  &.ve-table-border-around {
+    border-color: $border-color;
+  }
+
+  .ve-table-container table.ve-table-content thead.ve-table-header tr.ve-table-header-tr {
+    height: 34px;
+    box-sizing: border-box;
+
+    th.ve-table-header-th {
+      background: #04004E;
+      color: #FFF;
+      border-color: $border-color;
+      box-sizing: border-box;
+      line-height: 1;
+    }
+  }
+
+  .ve-table-container table.ve-table-content tbody.ve-table-body {
+
+    tr.ve-table-body-tr td.ve-table-body-td,
+    tr.ve-table-expand-tr td.ve-table-body-td,
+    tr.ve-table-body-tr td.ve-table-expand-td,
+    tr.ve-table-expand-tr td.ve-table-expand-td {
+      background: transparent;
+      color: #FFF;
+      border-color: $border-color;
+      box-sizing: border-box;
+    }
+
+    tr.ve-table-body-tr,
+    tr.ve-table-expand-tr {
+      height: 34px;
+      box-sizing: border-box;
+    }
+
+    &.ve-table-row-hover tr.ve-table-body-tr:hover td {
+      background-color: rgba(0, 0, 0, .22);
+      box-sizing: border-box;
+    }
+  }
+
+
+
+  .ve-table-container .ve-table-border-x th,
+  .ve-table-container .ve-table-border-x td {
+    border-color: $border-color;
+    box-sizing: border-box;
+  }
+
+}
+
+
+
+//颜色
+@each $colorkey,
+$color in $colors {
+  .text-#{$colorkey} {
+    color: $color;
+  }
+
+  .bg-#{$colorkey} {
+    background-color: $color;
+  }
+}
+
+//对齐
+@each $var in (left, center, right) {
+  .text-#{$var} {
+    text-align: $var !important;
+  }
+}
+
+//flex
+@each $key,
+$value in $flex-jc {
+  .jc-#{$key} {
+    justify-content: $value;
+  }
+}
+
+@each $key,
+$value in $flex-ai {
+  .ai-#{$key} {
+    align-items: $value;
+  }
+}
+
+//字体
+@each $fontkey,
+$fontvalue in $font-sizes {
+  .fs-#{$fontkey} {
+    font-size: $fontvalue * $base-font-size;
+  }
+}
+
+//.mt-1 => margin top
+//spacing
+
+@each $typekey,
+$type in $spacing-types {
+
+  //.m-1
+  @each $sizekey,
+  $size in $spacing-sizes {
+    .#{$typekey}-#{$sizekey} {
+      #{$type}: $size * $spacing-base-size;
+    }
+  }
+
+  //.mx-1
+  @each $sizekey,
+  $size in $spacing-sizes {
+    .#{$typekey}x-#{$sizekey} {
+      #{$type}-left: $size * $spacing-base-size;
+      #{$type}-right: $size * $spacing-base-size;
+    }
+
+    .#{$typekey}y-#{$sizekey} {
+      #{$type}-top: $size * $spacing-base-size;
+      #{$type}-bottom: $size * $spacing-base-size;
+    }
+  }
+
+  //.mt-1
+  @each $directionkey,
+  $direction in $spacing-directions {
+
+    @each $sizekey,
+    $size in $spacing-sizes {
+      .#{$typekey}#{$directionkey}-#{$sizekey} {
+        #{$type}-#{$direction}: $size * $spacing-base-size;
+      }
+    }
+  }
+
+  .#{$typekey} {
+    #{$type}: 0;
+  }
+}

+ 200 - 0
admin.ui.plus-master/src/theme/newDeviceVision/modules/reset.scss

@@ -0,0 +1,200 @@
+/**
+ * Eric Meyer's Reset CSS v2.0 (http://meyerweb.com/eric/tools/css/reset/)
+ * http://cssreset.com
+ */
+html,
+body,
+div,
+span,
+applet,
+object,
+iframe,
+h1,
+h2,
+h3,
+h4,
+h5,
+h6,
+p,
+blockquote,
+pre,
+a,
+abbr,
+acronym,
+address,
+big,
+cite,
+code,
+del,
+dfn,
+em,
+img,
+ins,
+kbd,
+q,
+s,
+samp,
+small,
+strike,
+strong,
+sub,
+sup,
+tt,
+var,
+b,
+u,
+i,
+center,
+dl,
+dt,
+dd,
+ol,
+ul,
+li,
+fieldset,
+form,
+label,
+legend,
+table,
+caption,
+tbody,
+tfoot,
+thead,
+tr,
+th,
+td,
+article,
+aside,
+canvas,
+details,
+embed,
+figure,
+figcaption,
+footer,
+header,
+menu,
+nav,
+output,
+ruby,
+section,
+summary,
+time,
+mark,
+audio,
+video,
+input {
+  margin: 0;
+  padding: 0;
+  border: 0;
+  font-size: 100%;
+  font-weight: normal;
+  vertical-align: baseline;
+}
+
+/* HTML5 display-role reset for older browsers */
+article,
+aside,
+details,
+figcaption,
+figure,
+footer,
+header,
+menu,
+nav,
+section {
+  display: block;
+}
+
+body {
+  line-height: 1;
+}
+
+blockquote,
+q {
+  quotes: none;
+}
+
+blockquote:before,
+blockquote:after,
+q:before,
+q:after {
+  content: none;
+}
+
+table {
+  border-collapse: collapse;
+  border-spacing: 0;
+}
+
+/* custom */
+
+a {
+  color: #7e8c8d;
+  -webkit-backface-visibility: hidden;
+  text-decoration: none;
+}
+
+li {
+  list-style: none;
+}
+
+body {
+  -webkit-text-size-adjust: none;
+  -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
+}
+
+.olControlScaleLineBottom {
+  display: none;
+}
+
+.olControlScaleLineTop {
+  color: #000 !important;
+  border-bottom: solid 3px #000 !important;
+  border-left: solid 2px #000 !important;
+  border-right: solid 2px #000 !important;
+  background-color: rgba(255, 255, 255, .4);
+  font-size: 10px;
+  text-shadow: -1px -1px 0 #fff, 1px -1px 0 #fff, -1px 1px 0 #fff, 1px 1px 0 #fff;
+}
+
+.olControlScaleLine {
+  z-index: 900 !important;
+}
+/*清除浮动*/
+.clearfix:after {
+  content: ".";
+  display: block;
+  height: 0;
+  clear: both;
+  visibility: hidden;
+}
+.clearfix {display: inline-block;}
+/* 点击搜索框获取焦点 placeholder消失-开始 */
+/* WebKit browsers */
+
+// input:focus::-webkit-input-placeholder {
+//   color: transparent;
+// }
+
+
+// /* Mozilla Firefox 4 to 18 */
+
+// input:focus:-moz-placeholder {
+//   color: transparent;
+// }
+
+
+// /* Mozilla Firefox 19+ */
+
+// input:focus::-moz-placeholder {
+//   color: transparent;
+// }
+
+
+// /* Internet Explorer 10+ */
+
+// input:focus:-ms-input-placeholder {
+//   color: transparent;
+// }
+
+/* 点击搜索框获取焦点 placeholder消失-结束 */

+ 98 - 0
admin.ui.plus-master/src/theme/newDeviceVision/modules/variables.scss

@@ -0,0 +1,98 @@
+// 颜色
+$colors: (
+  "primary": #1A5CD7,
+  "info-1": #4394e4,
+  "info": #4b67af,
+  "white": #ffffff,
+  "light": #f9f9f9,
+  "grey-1": #999999,
+  "grey": #666666,
+  "dark-1": #5f5f5f,
+  "dark": #222222,
+  "black-1": #171823,
+  "black": #000000,
+  "icon": #5cd9e8
+);
+
+// 字体大小
+$base-font-size: 0.2rem;
+$font-sizes: (
+  xxs: 0.1,
+  //8px
+    xs: 0.125,
+  //10px
+    sm: 0.2875,
+  //12px
+    md: 0.1625,
+  //13px
+    lg: 0.175,
+  //14px
+    xl: 0.2,
+  //16px
+    xxl: 0.225,
+  //18px
+    xxxl: 0.25 //20px,,,,
+);
+
+// 宽高
+.w-100 {
+  width: 100%;
+}
+.h-100 {
+  height: 100%;
+}
+
+//flex
+.flex {
+  display: flex;
+}
+.flex-column {
+  flex-direction: column;
+}
+.flex-wrap {
+  flex-wrap: wrap;
+}
+.flex-nowrap {
+  flex-wrap: nowrap;
+}
+$flex-jc: (
+  start: flex-start,
+  end: flex-end,
+  center: center,
+  between: space-between,
+  around: space-around,
+  evenly: space-evenly,
+);
+
+$flex-ai: (
+  start: flex-start,
+  end: flex-end,
+  center: center,
+  stretch: stretch,
+);
+
+.flex-1 {
+  flex: 1;
+}
+
+//.mt-1 => margin top
+//spacing
+$spacing-types: (
+  m: margin,
+  p: padding,
+);
+$spacing-directions: (
+  t: top,
+  r: right,
+  b: bottom,
+  l: left,
+);
+$spacing-base-size: 0.5rem;
+$spacing-sizes: (
+  0: 0,
+  1: 0.5,
+  2: 1,
+  3: 1.5,
+  4: 2,
+  5: 2.5,
+);

+ 156 - 0
admin.ui.plus-master/src/theme/newDeviceVision/public.scss

@@ -0,0 +1,156 @@
+.flex {
+	display: flex;
+}
+
+.flex-direction {
+	flex-direction: column;
+}
+
+.flex-wrap {
+	flex-wrap: wrap;
+}
+
+.align-start {
+	align-items: flex-start;
+}
+
+.align-end {
+	align-items: flex-end;
+}
+
+.align-center {
+	align-items: center;
+}
+
+.align-stretch {
+	align-items: stretch;
+}
+
+.self-start {
+	align-self: flex-start;
+}
+
+.self-center {
+	align-self: flex-center;
+}
+
+.self-end {
+	align-self: flex-end;
+}
+
+.self-stretch {
+	align-self: stretch;
+}
+
+.align-stretch {
+	align-items: stretch;
+}
+
+.justify-start {
+	justify-content: flex-start;
+}
+
+.justify-end {
+	justify-content: flex-end;
+}
+
+.justify-center {
+	justify-content: center;
+}
+
+.justify-between {
+	justify-content: space-between;
+}
+
+.justify-around {
+	justify-content: space-around;
+}
+@for $i from 0 through 12 {
+  .rdx-flex-#{$i} {
+    flex: $i;
+  }
+}
+
+@for $i from 9 to 50 {
+  .rdx-font-#{$i} {
+    font-size: $i + px;
+  }
+}
+
+@for $i from 2 to 50 {
+  .rdx-radius-#{$i} {
+    border-radius: $i + px;
+  }
+}
+@for $i from 10 to 50 {
+  .rdx-line-height-#{$i} {
+    line-height: $i + px;
+  }
+}
+
+// 定义内外边距,历遍1-80
+@for $i from 0 through 80 {
+  // 只要双数和能被5除尽的数
+  @if $i % 2 == 0 or $i % 5 == 0 {
+    // 得出:u-margin-30或者u-m-30
+    .rdx-m-#{$i} {
+      margin: $i + px !important;
+    }
+    // 得出:u-padding-30或者u-p-30
+    .rdx-p-#{$i} {
+      padding: $i + px !important;
+    }
+
+    @each $short, $long in l left, t top, r right, b bottom {
+      // 缩写版,结果如: u-m-l-30
+      // 定义外边距
+      .rdx-m-#{$short}-#{$i} {
+        margin-#{$long}: $i + px !important;
+      }
+
+      // 定义内边距
+      .rdx-p-#{$short}-#{$i} {
+        padding-#{$long}: $i + px !important;
+      }
+
+	 //自定义左右内边距
+	  .rdx-p-lr-#{$i} {
+		padding-left:$i + px !important;
+		padding-right:$i + px !important;
+	  }
+	  //自定义上下内边距
+	   .rdx-p-tb-#{$i} {
+	  		padding-top:$i + px !important;
+	  		padding-bottom:$i + px !important;
+	   }
+    }
+  }
+}
+i{font-style: normal;}
+.position-re{position: relative;}
+.position-ab{position: absolute; z-index: 9;}
+.position-fixed{position: fixed; background: rgba(92, 116, 143, 0.45); width: 100%; height: 100%; left: 0px; top: 0px; z-index: 10;}
+.round{border-radius: 50%;}
+.font-strong{font-weight: bold;}
+.color-del{color:$del-color}
+.color-primary{color: $primary-color;}
+.color-remark{color: #666666;}
+.color-9{color: #999999;}
+.color-green{color: #38a800;}
+.bg-white{background-color: white;}
+.line-bottom{border-bottom: 1px solid #eeeeee;}
+.button-pointer{cursor: pointer;}
+.box-shadow-item{box-shadow: 0px 0px 4px 0px rgba(45, 45, 46, 0.1);}
+.search-form .search-form-item label {text-align: right; padding-right: 6px;}
+
+
+.break-all{
+  word-break: break-all;
+}
+.blocks{
+  width: 100%;
+  height: 100%;
+}
+.cursor-pointer{
+  cursor: pointer;
+}

BIN
admin.ui.plus-master/src/theme/newDeviceVision/theme/fonts/element-icons.ttf


BIN
admin.ui.plus-master/src/theme/newDeviceVision/theme/fonts/element-icons.woff


Fichier diff supprimé car celui-ci est trop grand
+ 0 - 0
admin.ui.plus-master/src/theme/newDeviceVision/theme/index.css


+ 50 - 0
admin.ui.plus-master/src/theme/newDeviceVision/variable.scss

@@ -0,0 +1,50 @@
+// 颜色
+$primary-color: #1890ff;
+$primary-color-hl: rgb(41, 52, 67);
+$default-color: #006569;
+$link: #1890ff;
+$active-color: rgb(0, 101, 105);
+$del-color: #ff1839;
+$content-background: #f3f5fa;
+$table-header-background: #d8eaff;
+
+$primary-color-rgba: rgba($color: $primary-color,
+  $alpha: 0.1,
+);
+//表格上面button按钮颜色
+$table-header-button: #18d1ff;
+// 阴影
+$primary-shadow: 0 2px 4px rgba(0, 0, 0, 0.12),
+0 0 6px rgba(0, 0, 0, 0.04);
+$primary-shadow-light: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
+$baidu-shadow: 1px 2px 1px rgba(0, 0, 0, 0.15);
+$gaode-shadow: 0 2px 6px 0 rgba(0, 0, 0, 0.2),
+0 2px 6px 0 rgba(0, 0, 0, 0.19);
+
+// box-shadow: 0 2px 6px 0 rgb(114 124 245 / 50%);
+
+$primary-border: $primary-color solid 1px;
+
+$tool-top: 20px;
+
+//header 的高度
+$index-height: 60px;
+$index-content-height: calc(100% - 60px);
+$index-tags-height: 36px;
+// 宽度侧边栏
+$aside-width: 200px;
+$content-padding: 16px;
+
+$default-zindex: 99;
+
+/*文本格式化,超出范围,显示省略号*/
+@mixin text-overflow($num: 1) {
+  word-break: break-all;
+  text-overflow: ellipsis;
+  overflow: hidden;
+  display: -webkit-box;
+  -webkit-line-clamp: $num;
+  -webkit-box-orient: vertical;
+}
+
+

+ 18 - 0
admin.ui.plus-master/src/theme/newDeviceVision/webfont/index.css

@@ -0,0 +1,18 @@
+/* @font-face {
+    font-family: 'webfont';
+    font-display: swap;
+    src: url('//at.alicdn.com/t/webfont_c14qx7m7htb.eot');
+    src: 
+    url('//at.alicdn.com/t/webfont_c14qx7m7htb.woff2') format('woff2'),
+    url('//at.alicdn.com/t/webfont_c14qx7m7htb.woff') format('woff'), 
+
+
+  }
+
+.number-font{
+    font-family:"webfont" !important;
+    font-size:16px;font-style:normal;
+    -webkit-font-smoothing: antialiased;
+    -webkit-text-stroke-width: 0.2px;
+    -moz-osx-font-smoothing: grayscale;
+} */

+ 75 - 0
admin.ui.plus-master/src/utils/newDeviceVision/drawMixin.js

@@ -0,0 +1,75 @@
+/*
+ * @Author: daidai
+ * @Date: 2022-02-28 10:48:02
+ * @LastEditors: Please set LastEditors
+ * @LastEditTime: 2022-04-26 14:55:41
+ * @FilePath: \web-pc\src\pages\big-screen\utils\drawMixin.js
+ */
+// 屏幕适配 mixin 函数
+
+// * 默认缩放值
+const scale = {
+  width: '1',
+  height: '1',
+}
+
+// * 设计稿尺寸(px)
+const baseWidth = 1920
+const baseHeight = 1080
+
+// * 需保持的比例(默认1.77778)
+const baseProportion = parseFloat((baseWidth / baseHeight).toFixed(5))
+
+export default {
+  data() {
+    return {
+      // * 定时函数
+      drawTiming: null,
+    }
+  },
+  computed: {
+    isScale(){
+      return this.$store.state.setting.isScale
+    }
+  },
+  mounted () {
+    if(!this.isScale){
+      return
+    }
+    this.calcRate()
+    window.addEventListener('resize', this.resize)
+  },
+  beforeDestroy () {
+       window.removeEventListener('resize', this.resize)
+  },
+  methods: {
+    calcRate () {
+      const appRef = this.$refs["appRef"]
+      if (!appRef) return 
+      // 当前宽高比
+      const currentRate = parseFloat((window.innerWidth / window.innerHeight).toFixed(5))
+      if (appRef) {
+        if (currentRate > baseProportion) {
+          // 表示更宽
+          scale.width = ((window.innerHeight * baseProportion) / baseWidth).toFixed(5)
+          scale.height = (window.innerHeight / baseHeight).toFixed(5)
+          appRef.style.transform = `scale(${scale.width}, ${scale.height}) translate(-50%, -50%)`
+        } else {
+          // 表示更高
+          scale.height = ((window.innerWidth / baseProportion) / baseHeight).toFixed(5)
+          scale.width = (window.innerWidth / baseWidth).toFixed(5)
+          appRef.style.transform = `scale(${scale.width}, ${scale.height}) translate(-50%, -50%)`
+        }
+      }
+    },
+    resize () {
+      if(!this.isScale){
+        return
+      }
+      clearTimeout(this.drawTiming)
+      this.drawTiming = setTimeout(() => {
+        this.calcRate()
+      }, 200)
+    }
+  },
+}

+ 58 - 0
admin.ui.plus-master/src/utils/newDeviceVision/index.js

@@ -0,0 +1,58 @@
+/*
+ * @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;
+  }
+}

Fichier diff supprimé car celui-ci est trop grand
+ 0 - 0
admin.ui.plus-master/src/utils/newDeviceVision/map/china.json


+ 217 - 0
admin.ui.plus-master/src/utils/newDeviceVision/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": "吉林省"
+    }
+}

+ 72 - 0
admin.ui.plus-master/src/views/admin/visualization/newDeviceVision/components/echart/index.vue

@@ -0,0 +1,72 @@
+<!--
+ * @Author: daidai
+ * @Date: 2022-02-28 16:29:08
+ * @LastEditors: Please set LastEditors
+ * @LastEditTime: 2022-09-27 15:05:45
+ * @FilePath: \web-pc\src\pages\big-screen\components\echart\index.vue
+-->
+
+<!-- 
+*** 初始化echarts图标容器,然后再开始渲染。
+
+加油机状态、油站分布图、报警次数      图形框架?
+饼图、地图、折线图 
+-->
+
+<template>
+  <div :id="props.id" :class="props.className" :style="{ height: props.height, width: props.width }" />
+</template>
+
+<script setup>
+import * as echarts from 'echarts';
+import { ref, defineProps, onMounted, onBeforeUnmount, watch, onUpdated } from 'vue';
+
+// -- 子组件 。 -- echarts/index的作用是初始化图表容器
+const props = defineProps({
+  className: {
+    type: String,
+    default: 'chart'
+  },
+  id: {
+    type: String,
+    default: 'chart'
+  },
+  width: {
+    type: String,
+    default: '100%'
+  },
+  height: {
+    type: String,
+    default: '100%'
+  },
+  options: {
+    type: Object,
+    default: () => ({})
+  }
+})
+
+let chart = ref(null)
+
+onUpdated(() => {
+  // -- 挂在完成 调用echart初始化方法
+  initChart();
+})
+
+onBeforeUnmount(() => {
+  // -- 销毁组件前 销毁echart实例
+  echarts.dispose(chart)
+  chart = null
+})
+
+const initChart = async () => {
+  // 初始化echart
+  chart = echarts.init(document.getElementById(props.id))
+  chart.setOption(props.options, true)
+}
+
+watch(props.options, (Val) => {
+  chart.setOption(Val, true)
+}, { deep: true })
+</script>
+
+<style></style>

+ 90 - 0
admin.ui.plus-master/src/views/admin/visualization/newDeviceVision/components/item-wrap/item-wrap.vue

@@ -0,0 +1,90 @@
+<!--
+ * @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="props.title !== ''">
+      <div class="zuo"></div>
+      <!--  左右两边的 方格内容的 标题 -->
+      <span class="title-inner"> &nbsp;&nbsp;{{ props.title }}&nbsp;&nbsp; </span>
+      <div class="you"></div>
+    </div>
+    <div :class="props.title !== '' ? 'item_title_content' : 'item_title_content_def'">
+      <slot></slot>
+    </div>
+  </dv-border-box-13>
+</template>
+
+<script setup>
+import { defineProps } from 'vue';
+
+const props = defineProps({
+  // -- props。在父组件中 向子组件传递值
+  title: {
+    type: String,
+    default: () => "",   // -- 传递的title默认值为 空
+  }
+})
+
+</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("/src/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>

+ 21 - 0
admin.ui.plus-master/src/views/admin/visualization/newDeviceVision/components/kong.vue

@@ -0,0 +1,21 @@
+<template>
+  <div class='kong'>
+    <slot></slot>
+  </div>
+</template>
+
+<script setup>
+  // const props = defineProps({
+  //   data:{
+  //       type:Array,
+  //       default:()=>[]
+  //     }
+  // })
+</script>
+
+<style lang='scss' scoped>
+  .kong {
+    width: 100%;
+    height: 100%;
+  }
+</style>

+ 45 - 0
admin.ui.plus-master/src/views/admin/visualization/newDeviceVision/components/reacquire/reacquire.vue

@@ -0,0 +1,45 @@
+<template>
+  <div class='reacquire flex justify-center  blocks  cursor-pointer' :style="{ lineHeight: emits.lineHeight }" @click="getData">
+    <span>
+      重新获取
+    </span>
+
+  </div>
+</template>
+
+<script setup>
+  import { defineEmits } from 'vue';
+
+  const emits = defineEmits({
+    lineHeight: {
+      type: String,
+      default: '200px'
+    }
+  })
+
+  const getData = (e) => {
+    emits("onclick", e)
+  }
+</script>
+
+<style lang='scss' scoped>
+  .reacquire {
+
+    user-select: none;
+    color: rgb(168, 168, 168);
+
+    span:hover {
+      // color:$primary-color ;
+      text-decoration: underline;
+    }
+  }
+
+  .blocks {
+    width: 100%;
+    height: 100%;
+  }
+
+  .cursor-pointer {
+    cursor: pointer;
+  }
+</style>

+ 279 - 0
admin.ui.plus-master/src/views/admin/visualization/newDeviceVision/components/scale-screen/scale-screen.vue

@@ -0,0 +1,279 @@
+<!--
+ * @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 setup>
+  import { nextTick } from 'process';
+  import { computed, onBeforeUnmount, onMounted, reactive, ref, defineProps, watch, inject } from 'vue';
+
+  /**
+   * 防抖函数
+   * @param {T} fn
+   * @param {number} delay
+   * @return
+   */
+  // -- 1、封装防抖函数
+  function debounce(fn, delay) {
+    // -- 创建一个标记用来存放定时器的返回值
+    let timer = null;
+    // -- args为屏幕大小变化监听到的内容
+    return function (...args) {
+      timer = setTimeout(
+        () => {
+          // -- 进行防抖的内容 -->apply和call都是用来改变this的指向的。(null这个对象代替function类里this对象;args这是个数组,作为参数传给function(args-->arguments))
+          typeof fn === "function" && fn.apply(null, args);
+          // -- 每当用户触发。。事件,把前一个setTimeout清除掉
+          clearTimeout(timer);
+        },
+        delay > 0 ? delay : 100
+      );
+    };
+  }
+
+  // 父传子。子组件接收
+  const props = defineProps({
+    // name:{
+    //   type:String,
+    //   default:'VScaleScreen'
+    // },
+    width: {
+      type: [String, Number],
+      default: 1920,
+    },
+    height: {
+      type: [String, Number],
+      default: 1080,
+    },
+    fullScreen: {
+      type: Boolean,
+      default: false,
+    },
+    autoScale: {
+      type: [Object, Boolean],
+      default: true,
+    },
+    selfAdaption: {
+      type: Boolean,
+      default: true,
+    },
+    delay: {
+      type: Number,
+      default: 500,
+    },
+    boxStyle: {
+      type: Object,
+      default: () => ({}),
+    },
+    wrapperStyle: {
+      type: Object,
+      default: () => ({}),
+    }
+  })
+
+  const data = reactive({
+    currentWidth: 0,
+    currentHeight: 0,
+    originalWidth: 0,
+    originalHeight: 0,
+    onResize: null,
+    observer: null,
+  })
+
+
+  const screenWrapper = ref()
+
+  // const screenWrapper = computed(() => {
+  //   return  this.$refs.screenWrapper;
+  // })
+
+  const initSize = (() => {
+    return new Promise((resolve, reject) => {
+      // console.log("初始化样式");
+      //给父元素设置 overflow:hidden
+      screenWrapper.value.style.overflow = "hidden";
+      screenWrapper.value.scrollLeft = 0;
+      screenWrapper.value.scrollTop = 0;
+
+      nextTick(() => {
+        // region 获取大屏真实尺寸
+        // *** width和height 是子组件传过来的高宽。 ***
+        if (props.width && props.height) {
+          data.currentWidth = props.width;
+          data.currentHeight = props.height;
+        } else {
+          data.currentWidth = screenWrapper.clientWidth;
+          data.currentHeight = screenWrapper.clientHeight;
+        }
+        // endregion
+        // region 获取画布尺寸
+        if (!data.originalHeight || !data.originalWidth) {
+          data.originalWidth = window.screen.width;
+          data.originalHeight = window.screen.height;
+        }
+        // endregion
+        resolve();
+      });
+    });
+  })
+
+  const updateSize = (() => {
+    if (data.currentWidth && data.currentHeight) {
+      screenWrapper.value.style.width = `${data.currentWidth}px`;
+      screenWrapper.value.style.height = `${data.currentHeight}px`;
+    } else {
+      screenWrapper.value.style.width = `${data.originalWidth}px`;
+      screenWrapper.value.style.height = `${data.originalHeight}px`;
+    }
+  })
+
+  const handleAutoScale = ((scale) => {
+    if (!props.autoScale) return;
+    const domWidth = screenWrapper.value.clientWidth;
+    const domHeight = screenWrapper.value.clientHeight;
+    const currentWidth = document.body.clientWidth;
+    const currentHeight = document.body.clientHeight;
+    screenWrapper.value.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 props.autoScale === "object") {
+      // @ts-ignore
+      !props.autoScale.x && (mx = 0);
+      // @ts-ignore
+      !props.autoScale.y && (my = 0);
+    }
+    // console.log({
+    //   mx,
+    //   my,
+    //   currentWidth,
+    //   currentHeight,
+    //   domWidth,
+    //   domHeight,
+    //   scale,
+    // });
+    screenWrapper.value.style.margin = `${my}px ${mx}px`;
+  })
+
+
+  // -- scalewidth是内部的宽度
+  const updateScale = (() => {
+    // 获取真实视口尺寸
+    const currentWidth = document.body.clientWidth;
+    const currentHeight = document.body.clientHeight;
+    // 获取大屏最终的宽高onResize
+    const realWidth = data.currentWidth || data.originalWidth;
+    const realHeight = data.currentHeight || data.originalHeight;
+    // 计算缩放比例
+    const widthScale = currentWidth / realWidth;
+    const heightScale = currentHeight / realHeight;
+    // console.log({currentWidth, currentHeight,realWidth,realHeight});
+
+    // 若要铺满全屏,则按照各自比例缩放
+    if (props.fullScreen) {
+      screenWrapper.value.style.transform = `scale(${widthScale},${heightScale})`;
+      return false;
+    }
+    // 按照宽高最小比例进行缩放
+    const scale = Math.min(widthScale, heightScale);
+    handleAutoScale(scale);
+  })
+
+  const initMutationObserver = (() => {
+    const observer = (data.observer = new MutationObserver(() => {
+      onResize();
+    }));
+
+    observer.observe(screenWrapper.value, {
+      attributes: true,
+      attributeFilter: ["style"],
+      attributeOldValue: true,
+    });
+  })
+
+  // -- vue中使用防抖,需要在组件销毁的钩子中去除监听事件,不然会产生意想不到的bug
+  const clearListener = (() => {
+    window.removeEventListener("resize", data.onResize);
+  })
+
+  // -- 添加监听事件。给window绑定resize事件,调用封装防抖函数(resize是在浏览器窗口大小发生变化时触发,利用该事件可以跟踪窗口大小的变化来动态控制调整页面的元素显示)
+  const addListener = (() => {
+    window.addEventListener("resize", data.onResize);
+  })
+
+  const clearStyle = (() => {
+    // console.log("清除");
+    screenWrapper.value.parentNode.style.overflow = "auto";
+    screenWrapper.value.style = "";
+  })
+
+  const resize = async () => {
+    if (!props.selfAdaption) {
+      return;
+    }
+    await initSize();
+    // -- 获取窗口高宽
+    updateSize();
+    updateScale();
+  }
+
+  onMounted(() => {
+    data.onResize = debounce(() => {
+      resize();
+    }, props.delay);
+    nextTick(() => {
+      if (props.selfAdaption) {
+        // -- 监听浏览器窗口变化,实时获取窗口的高宽
+        resize();
+        // -- 防抖,避免触发方法多次时,重复获取浏览器高宽
+        addListener();
+      }
+    });
+  })
+
+  onBeforeUnmount(() => {
+    // -- 组件销毁的钩子函数中,移除监听事件。
+    clearListener();
+    // this.observer.disconnect()
+  })
+
+
+
+
+  // ****** 此处出现问题 ******
+  // watch(props.selfAdaption, (val) => {
+  //   if (val) {
+  //     resize();
+  //     addListener();
+  //   } else {
+  //     clearListener();
+  //     clearStyle();
+  //   }
+  // })
+</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>

+ 126 - 0
admin.ui.plus-master/src/views/admin/visualization/newDeviceVision/home.vue

@@ -0,0 +1,126 @@
+<!--
+ * @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="app">
+        <!-- <div id="index" ref="appRef" class="index_home" :class="{ pageisScale: isScale }"> -->
+        <ScaleScreen :width="1920" :height="1080" class="scale-wrap" :selfAdaption="true" ref="parentDom">
+            <div class="bg">
+                <dv-loading v-if="data.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">
+                            {{ data.dateYear }} {{ data.dateWeek }} {{ data.dateDay }}
+                            <i class="blq-icon-shezhi02" style="margin-left: 10px" @click="showSetting"></i>
+                        </div>
+                    </div>
+                    <!-- 头部 e-->
+                    <!-- 内容  s-->
+                    <index></index>
+                    <!-- 内容 e -->
+                </div>
+            </div>
+            <!--  <Setting ref="setting" /> -->
+        </ScaleScreen>
+        <!-- </div> -->
+    </div>
+
+</template>
+
+<script setup>
+import { onBeforeUnmount, onMounted, reactive } from 'vue';
+import { NextLoading } from '/@/utils/loading';
+import {formatTime} from '/@/utils/newDeviceVision/index.js';
+import ScaleScreen from "./components/scale-screen/scale-screen.vue";
+import index from "/@/views/admin/visualization/newDeviceVision/indexs/index.vue";
+import Setting from "./setting.vue";
+
+
+onMounted(() => {
+    NextLoading.done()
+    timeFn();
+    cancelLoading();
+})
+
+// -- 钩子函数,被销毁前
+onBeforeUnmount(() => {
+    // -- 在使用setInterval函数时,使用clearInterval来停止执行
+    clearInterval(data.timing);
+})
+
+const data = reactive({
+    timing: null,
+    loading: true,
+    dateDay: null,
+    dateYear: null,
+    dateWeek: null,
+    weekday: ["周日", "周一", "周二", "周三", "周四", "周五", "周六"],
+})
+
+const showSetting = (() => {
+    // -- 使用子组件setting中的init方法
+    Setting.init();
+})
+
+const timeFn = (() => {
+    // -- setInterval定时器,每秒执行一次。
+    data.timing = setInterval(() => {
+        formatTime()
+        data.dateDay = formatTime(new Date(), "HH: mm: ss");
+        data.dateYear = formatTime(new Date(), "yyyy-MM-dd");
+        data.dateWeek = data.weekday[new Date().getDay()];
+    }, 1000);
+})
+
+const cancelLoading = (() => {
+    // -- setTimeout定时器。
+    let timer = setTimeout(() => {
+        data.loading = false;
+        clearTimeout(timer);
+    }, 500);
+})
+
+//     // -- 定义过滤器
+//     filters: {
+//         numsFilter(msg) {
+//             return msg || 0;
+//         },
+//     },
+
+
+
+
+// import index from "/@/views/admin/visualization/newDeviceVision/indexs/index.vue"
+// export default {
+//     components: { Setting, ScaleScreen, index },
+
+// };
+
+
+
+</script>
+
+<style lang="scss">
+#app {
+    width: 100vw;
+    height: 100vh;
+    background-color: black
+}
+
+// @import '/src/theme/newDeviceVison/css/public.scss';
+@import "/src/theme/newDeviceVision/index.scss";
+@import "/src/theme/newDeviceVision/home.scss";
+</style>

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

@@ -0,0 +1,393 @@
+<!--
+ * @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">{{ data.maptitle }}</span>
+      <div class="you"></div>
+    </div>
+    <div class="mapwrap">
+      <dv-border-box-13>
+        <div class="quanguo" @click="getData('china')" v-if="data.code !== 'china'">
+          中国
+        </div>
+        <Echart id="CenterMap" :options="options" ref="CenterMap" />
+      </dv-border-box-13>
+    </div>
+  </div>
+</template>
+
+<script setup>
+import xzqCode from "/@/utils/newDeviceVision/map/xzqCode";
+import { currentGET } from '/@/api/newDeviceVision/modules';
+import * as echarts from "echarts";
+import { GETNOBASE } from '/@/api/newDeviceVision/api.js';
+import jsondata from '/@/utils/newDeviceVision/map/china.json'; // 如果你使用的是 ES6 语法  
+import { onMounted, reactive, ref } from "vue";
+import { ElMessage } from "element-plus";
+
+
+const data = reactive({
+  maptitle: "油站分布图",
+  code: "china", //china 代表中国 其他地市是行政编码
+  echartBindClick: false,
+  isSouthChinaSea: false, //是否要展示南海群岛  修改此值请刷新页面
+})
+const options = ref({})
+
+onMounted(() => {
+  // console.log(xzqCode);
+  getData("china");
+
+})
+
+const getData = async (code) => {
+  // debugger
+  var fsdfsd = jsondata;
+  const jsonString = '{"success":true,"data":{"dataList":[{"name":"黑龙江省","value":15},{"name":"河北省","value":47},{"name":"河南省","value":5},{"name":"安徽省","value":7},{"name":"浙江省","value":16},{"name":"湖北省","value":16},{"name":"贵州省","value":6},{"name":"广东省","value":4}],"regionCode":"china"}}';
+  const jsonObject = JSON.parse(jsonString);
+  await getGeojson(jsonObject.data.regionCode, jsonObject.data.dataList);
+  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 {*}
+ */
+const getGeojson = (name, mydata) => {
+  data.code = name;
+  //如果要展示南海群岛并且展示的是中国的话
+  let geoname = name
+  if (data.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) => {
+        console.log("设备分布", res);
+        return res;
+      });
+      debugger
+      console.log("设备分布22", jsondata); */
+    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),
+      });
+    }
+  });
+  init(name, mydata, newData);
+
+}
+
+const 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
+  };
+  options.value = option;
+}
+
+const message = (text) => {
+  ElMessage({
+    text: text,
+    type: "warning",
+  });
+}
+
+
+const CenterMap = ref()
+const mapclick = () => {
+  if (data.echartBindClick) return;
+  //单击切换到级地图,当mapCode有值,说明可以切换到下级地图
+
+  CenterMap.on("click", (params) => {
+    // console.log(params);
+    let xzqData = xzqCode[params.name];
+    if (xzqData) {
+      getData(xzqData.adcode);
+    } else {
+      message("暂无下级地市!");
+    }
+  });
+  data.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("/src/assets/deviceVision/xiezuo.png") no-repeat;
+    }
+
+    .you {
+      background: url("/src/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>

+ 145 - 0
admin.ui.plus-master/src/views/admin/visualization/newDeviceVision/indexs/index.vue

@@ -0,0 +1,145 @@
+<!--
+ * @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是 每个图标区域的固定形式,包含边框、色彩等 -- 组件ItemWrap是通过全局引入的
+        -->
+      <ItemWrap class="contetn_left-top contetn_lr-item" title="加油机总览">
+        <LeftTop />
+      </ItemWrap>
+
+      <ItemWrap class="contetn_left-center contetn_lr-item" title="加油机状态">
+        <LeftCenter />
+      </ItemWrap>
+
+      <ItemWrap class="contetn_left-bottom contetn_lr-item" title="加油机在线状态" style="padding: 0 10px 16px 10px">
+        <LeftBottom />
+      </ItemWrap>
+
+    </div>
+
+    <div class="contetn_center">
+      <CenterMap class="contetn_center_top" />
+
+      <!--  <ItemWrap class="contetn_center-bottom" title="安装计划">
+          <CenterBottom />
+        </ItemWrap> -->
+    </div>
+
+    <div class="contetn_right">
+      <ItemWrap class="contetn_left-bottom contetn_lr-item" title="报警次数">
+        <RightTop />
+      </ItemWrap>
+
+      <ItemWrap class="contetn_left-bottom contetn_lr-item" title="报警排名(TOP8)" style="padding: 0 10px 16px 10px">
+        <RightCenter />
+      </ItemWrap>
+
+      <ItemWrap class="contetn_left-bottom contetn_lr-item" title="报警内容 ">
+        <RightBottom />
+      </ItemWrap>
+
+    </div>
+  </div>
+</template>
+
+<script setup>
+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";
+
+
+// filters: {
+//       numsFilter(msg) {
+//         return msg || 0;
+//       },
+//     },
+</script>
+<style lang="scss" scoped>
+// 内容
+.contents {
+
+  .contetn_left,
+  .contetn_right {
+    width: 540px;
+    box-sizing: border-box;
+    // padding: 16px 0;
+  }
+
+  .contetn_center {
+    width: 720px;
+  }
+
+  //左右两侧 三个块
+  .contetn_lr-item {
+    height: 310px;
+  }
+
+  .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>

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

@@ -0,0 +1,242 @@
+<!--
+ * @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="data.pageflag" class="left_boottom_wrap beautify-scroll-def"
+    :class="{ 'overflow-y-auto': !sbtxSwiperFlag }">
+    <component :is="data.components" :list="data.list" hover :step="data.defaultOption.step"
+      :singleHeight="data.defaultOption.singleHeight" :singleWaitTime="3000">
+      <ul class="left_boottom">
+        <li class="left_boottom_item" v-for="(item, i) in data.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.fuelId }}</span>
+              </div>
+              <div class="info">
+                <span class="labels">机型:</span>
+                <span class="contents " style="font-size: 12px">
+                  {{ item.model }}</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)  }} -->
+                {{ item.oilCompany }}
+              </span>
+            </div>
+          </div>
+        </li>
+      </ul>
+    </component>
+  </div>
+
+  <Reacquire v-else @onclick="getData" style="line-height: 200px" />
+</template>
+
+<script setup>
+import { currentPOST } from '/@/api/newDeviceVision/modules'
+import { Vue3SeamlessScroll } from 'vue3-seamless-scroll' // vue3引入方式
+import Kong from "/@/views/admin/visualization/newDeviceVision/components/kong.vue";
+import { onMounted, reactive, computed } from 'vue';
+import store from '/@/stores/newDeviceVision/modules/setting'
+
+
+const data = reactive({
+  list: [],
+  pageflag: true,
+  components: Vue3SeamlessScroll,
+  defaultOption: {
+    ...store.state.defaultOption,
+    singleHeight: 240,
+    limitMoveNum: 5,
+    step: 0,
+  },
+})
+
+const sbtxSwiperFlag = computed(() => {
+  let sbtxSwiper = store.state.sbtxSwiper;
+  if (sbtxSwiper) {
+    data.components = Vue3SeamlessScroll;
+  } else {
+    data.components = Kong;
+  }
+  return sbtxSwiper;
+})
+
+onMounted(() => {
+  getData();
+
+})
+
+const addressHandle = (item) => {
+  let name = item.provinceName;
+  if (item.cityName) {
+    name += "/" + item.cityName;
+    if (item.countyName) {
+      name += "/" + item.countyName;
+    }
+  }
+  return name;
+}
+
+const getData = () => {
+  data.pageflag = true;
+  // data.pageflag =false
+  currentPOST("big3", { limitNum: 20 }).then((res) => {
+    console.log("设备提醒", res);
+    if (res.success) {
+      // data.countUserNumData = res.data;
+      data.list = res.data;
+      let timer = setTimeout(() => {
+        clearTimeout(timer);
+        data.defaultOption.step = store.state.defaultOption.step;
+      }, store.state.defaultOption.waitTime);
+    } else {
+      data.pageflag = false;
+    }
+  });
+}
+</script>
+<style lang='scss'>
+.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("/src/assets/deviceVision/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>

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

@@ -0,0 +1,242 @@
+<!--
+ * @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="data.options" class="left_center_inner" v-if="data.pageflag" ref="charts"></Echart>
+  <Reacquire v-else @onclick="getData" style="line-height:200px">
+    重新获取
+  </Reacquire>
+</template>
+
+<script setup>
+import { onBeforeUnmount, onMounted, reactive, ref } from 'vue'
+import { currentPOST } from '/@/api/newDeviceVision/modules'
+import { nextTick } from 'process'
+import store from '/@/stores/newDeviceVision/modules/setting'
+
+
+let data = reactive({
+  options: {},
+  countUserNumData: {
+    enable: 0,
+    register: 0,
+    disable: 0,
+    factory: 0,
+    totalNum: 0,
+  },
+  pageflag: true,
+  timer: null,
+})
+
+onMounted(() => {
+  getData()
+})
+
+onBeforeUnmount(() => {
+  clearData()
+})
+
+const clearData = () => {
+  if (data.timer) {
+    clearInterval(data.timer)
+    data.timer = null
+  }
+}
+
+const getData = () => {
+  data.pageflag = true
+  // data.pageflag =false
+  /* 
+    data.countUserNumData = {
+  offlineNum: 26,
+  lockNum: 4,
+  totalNum: 218,
+  onlineNum: 188
+}
+  this.$nextTick(() => {
+    this.init()
+  }) */
+
+  currentPOST('big1').then((res) => {
+    //只打印一次
+    if (!data.timer) {
+      console.log('设备状态', JSON.stringify(res))
+
+    }
+    if (res.success) {
+      data.countUserNumData = res.data
+      nextTick(() => {
+        init()
+      })
+    } else {
+      data.pageflag = false
+    }
+  })
+}
+
+//轮询
+const switper = () => {
+  if (data.timer) {
+    return
+  }
+  let looper = (a) => {
+    getData()
+  }
+  data.timer = setInterval(looper, store.state.echartsAutoTime)
+  const charts = ref()
+  let myChart = charts
+  myChart.on('mouseover', (params) => {
+    clearData()
+  })
+  myChart.on('mouseout', (params) => {
+    data.timer = setInterval(looper, store.state.echartsAutoTime)
+  })
+}
+
+const init = () => {
+  let total = data.countUserNumData.totalNum
+  let colors = ['#ECA444', '#33A1DB', '#56B557']
+  let piedata = {
+    name: '设备状态',
+    type: 'pie',
+    radius: ['42%', '65%'],
+    avoidLabelOverlap: false,
+    itemStyle: {
+      borderRadius: 4,
+      borderColor: 'rgba(0,0,0,0)',
+      borderWidth: 2,
+    },
+
+    color: colors,
+    data: [
+      {
+        value: data.countUserNumData.enable,
+        name: '启用',
+        label: {
+          shadowColor: colors[0],
+        },
+      },
+      {
+        value: data.countUserNumData.register,
+        name: '备案',
+        label: {
+          shadowColor: colors[0],
+        },
+      },
+      {
+        value: data.countUserNumData.disable,
+        name: '维修',
+        label: {
+          shadowColor: colors[2],
+        },
+      },
+      {
+        value: data.countUserNumData.factory,
+        name: '出厂注册',
+        label: {
+          shadowColor: colors[1],
+        },
+      },],
+  }
+  data.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></style>

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

@@ -0,0 +1,257 @@
+<!--
+ * @Author: daidai
+ * @Date: 2022-02-28 16:16:42
+ * @LastEditors: Please set LastEditors
+ * @LastEditTime: 2022-07-20 17:57:11
+ * @FilePath: \web-pc\src\pages\big-screen\view\indexs\left-center.vue
+-->
+<template>
+  <ul class="user_Overview flex" v-if="data.pageflag">
+    <li class="user_Overview-item" style="color: #00fdfa">
+      <div class="user_Overview_nums allnum ">
+        <dv-digital-flop :config="data.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="data.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="data.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="data.laramnumconfig" style="width:100%;height:100%;" />
+      </div>
+      <p>告警次数</p>
+    </li>
+  </ul>
+  <Reacquire v-else @onclick="getData" line-height="200px">
+    重新获取
+  </Reacquire>
+</template>
+
+<script setup>
+import { reactive, onBeforeUnmount, onBeforeMount } from 'vue';
+import store from '/@/stores/newDeviceVision/modules/setting'
+
+import { currentPOST } from '/@/api/newDeviceVision/modules'
+let style = {
+  fontSize: 24
+}
+
+const data = reactive({
+  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;
+//         },
+//     },
+
+onBeforeMount(() => {
+  getData()
+})
+
+onBeforeUnmount(() => {
+  clearData()
+})
+
+const clearData = (() => {
+  if (data.timer) {
+    clearInterval(data.timer)
+    data.timer = null
+  }
+})
+
+const getData = (() => {
+  data.pageflag = true;
+  /*let json = {
+    data: {
+      alarmNum: 359,
+      offlineNum: 3,
+      totalNum: 22,
+      onlineNum: 123
+    }
+  };
+  this.userOverview = json.data;
+  this.onlineconfig = {
+      ...this.onlineconfig,
+      number: [json.data.onlineNum]
+  }
+  this.config = {
+      ...this.config,
+      number: [json.data.totalNum]
+  }
+  this.offlineconfig = {
+      ...this.offlineconfig,
+      number: [json.data.offlineNum]
+  }
+  this.laramnumconfig = {
+      ...this.laramnumconfig,
+      number: [json.data.alarmNum]
+  }
+  this.switper() */
+
+  // -- 访问数据接口,获取数据
+  currentPOST("big2").then((res) => {
+    console.log("设备总览", JSON.stringify(res));
+    if (!data.timer) { }
+    if (res.success) {
+      data.userOverview = res.data;
+      data.onlineconfig = {
+        ...data.onlineconfig,
+        number: [res.data.onlineNum]
+      }
+      data.config = {
+        ...data.config,
+        number: [res.data.totalNum]
+      }
+      data.offlineconfig = {
+        ...data.offlineconfig,
+        number: [res.data.offlineNum]
+      }
+      data.laramnumconfig = {
+        ...data.laramnumconfig,
+        number: [res.data.alarmNum]
+      }
+      switper()
+    } else {
+      data.pageflag = false;
+
+    }
+  });
+})
+
+//轮询
+const switper = (() => {
+  if (data.timer) {
+    return
+  }
+  let looper = (a) => {
+    getData()
+  };
+  data.timer = setInterval(looper, store.state.echartsAutoTime);
+})
+</script>
+<style lang='scss' scoped>
+.user_Overview {
+  li {
+    flex: 1;
+
+    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("/src/assets/deviceVision/left_top_lan.png");
+      &::before {
+        background-image: url("/src/assets/deviceVision/left_top_lan.png");
+
+      }
+    }
+
+    .online {
+      &::before {
+        background-image: url("/src/assets/deviceVision/left_top_lv.png");
+
+      }
+    }
+
+    .offline {
+      &::before {
+        background-image: url("/src/assets/deviceVision/left_top_huang.png");
+
+      }
+    }
+
+    .laramnum {
+      &::before {
+        background-image: url("/src/assets/deviceVision/left_top_hong.png");
+
+      }
+    }
+  }
+}
+</style>

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

@@ -0,0 +1,192 @@
+<!--
+ * @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="data.pageflag" class="right_center_wrap beautify-scroll-def"
+    :class="{ 'overflow-y-auto': !sbtxSwiperFlag }">
+    <component :is="data.components" :list="data.list" hover :step="data.defaultOption.step"
+      :singleHeight="data.defaultOption.singleHeight" :singleWaitTime="3000">
+      <ul class="right_center ">
+        <li class="right_center_item" v-for="(item, i) in data.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.fuelId }}</span>
+              </div>
+              <div class="info">
+                <span class="labels">机型:</span>
+                <span class="contents "> {{ item.model }}</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.oilCompany }}</span>
+              </div>
+              <div class="info time">
+                <span class="labels">时间:</span>
+                <span class="contents" style="font-size:12px"> {{ item.createdDate }}</span>
+              </div>
+
+            </div>
+            <div class="flex">
+
+              <div class="info">
+                <span class="labels">报警内容:</span>
+                <span class="contents ciyao" :class="{ warning: item.alarmDescription }"> {{ item.alarmDescription ||
+                  '无'
+                  }}</span>
+              </div>
+            </div>
+          </div>
+        </li>
+      </ul>
+    </component>
+  </div>
+  <Reacquire v-else @onclick="getData" style="line-height:200px" />
+
+</template>
+
+<script setup>
+import { currentPOST } from '/@/api/newDeviceVision/modules'
+import { Vue3SeamlessScroll } from 'vue3-seamless-scroll' // vue3引入方式
+import Kong from "/@/views/admin/visualization/newDeviceVision/components/kong.vue";
+import { computed, onBeforeMount, reactive } from 'vue';
+import store from '/@/stores/newDeviceVision/modules/setting'
+
+
+const data = reactive({
+  list: [],
+  pageflag: true,
+  defaultOption: {
+    ...store.state.defaultOption,
+    limitMoveNum: 3,
+    singleHeight: 250,
+    step: 0,
+  },
+  components: Vue3SeamlessScroll
+})
+
+const sbtxSwiperFlag = computed(() => {
+  let ssyjSwiper = store.state.ssyjSwiper
+  if (ssyjSwiper) {
+    data.components = Vue3SeamlessScroll
+  } else {
+    data.components = Kong
+  }
+  return ssyjSwiper
+})
+
+onBeforeMount(() => {
+  getData()
+})
+
+const getData = () => {
+  data.pageflag = true
+  // data.pageflag =false
+  currentPOST('big5', { limitNum: 50 }).then(res => {
+    console.log('实时预警', res);
+    if (res.success) {
+      data.list = res.data
+      let timer = setTimeout(() => {
+        clearTimeout(timer)
+        data.defaultOption.step = store.state.defaultOption.step
+      }, store.state.defaultOption.waitTime);
+    } else {
+      data.pageflag = false
+    }
+  })
+
+}
+
+</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>

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

@@ -0,0 +1,195 @@
+<!--
+ * @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 setup>
+import { currentGET } from '/@/api/newDeviceVision/modules'
+import { onBeforeMount, onBeforeUnmount, reactive } from 'vue';
+import store from '/@/stores/newDeviceVision/modules/setting'
+
+const data = reactive({
+  gatewayno: '',
+  timer: 0
+})
+const config = reactive({
+  showValue: true,
+  unit: "",
+  data: []
+})
+
+onBeforeMount(() => {
+  getData()
+})
+
+onBeforeUnmount(() => {
+  clearData()
+})
+
+const clearData = () => {
+  if (data.timer) {
+    clearInterval(data.timer)
+    data.timer = null
+  }
+}
+
+//轮询
+const switper = () => {
+  if (data.timer) {
+    return
+  }
+  let looper = (a) => {
+    getData()
+  };
+  data.timer = setInterval(looper, store.state.echartsAutoTime);
+}
+
+const getData = () => {
+  // data.pageflag = true
+
+  let json = {
+    "success": true,
+    "data": [
+      {
+        "value": 1995,
+        "name": "黑龙江"
+      },
+      {
+        "value": 1815,
+        "name": "河南"
+      },
+      {
+        "value": 1654,
+        "name": "安徽"
+      },
+      {
+        "value": 1503,
+        "name": "浙江"
+      },
+      {
+        "value": 1363,
+        "name": "河北"
+      },
+      {
+        "value": 1232,
+        "name": "湖北"
+      },
+      {
+        "value": 1131,
+        "name": "贵州"
+      },
+      {
+        "value": 925,
+        "name": "广东"
+      }]
+  };
+
+  // *** 数据请求失败
+  currentGET('big7').then(res => {
+
+    if (!data.timer) {
+      console.log('报警排名', JSON.stringify(res));
+    }
+    if (res.success) {
+      data.config = {
+        ...data.config,
+        data: json.data
+      }
+      this.switper()
+    } else {
+      data.pageflag = false
+      data.srcList = []
+    }
+  })
+  config.data = json.data
+}
+</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;
+      }
+    }
+  }
+
+  .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>

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

@@ -0,0 +1,292 @@
+<!--
+ * @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="data.pageflag" ref="charts" />
+  <Reacquire v-else @onclick="getData" style="line-height: 200px">
+    重新获取
+  </Reacquire>
+</template>
+
+<script setup>
+import { currentPOST } from '/@/api/newDeviceVision/modules'
+import { graphic } from "echarts"
+import { nextTick } from 'process';
+import { reactive, onMounted, onBeforeUnmount, ref } from "vue";
+import store from '/@/stores/newDeviceVision/modules/setting'
+
+const data = reactive({
+  pageflag: false,
+  timer: null,
+})
+const option = ref({})
+
+onMounted(() => {
+  getData();
+})
+
+onBeforeUnmount(() => {
+  clearData();
+})
+
+const clearData = () => {
+  if (data.timer) {
+    clearInterval(data.timer);
+    data.timer = null;
+  }
+}
+
+const getData = () => {
+  data.pageflag = true;
+  // data.pageflag = false
+  currentPOST("big4").then((res) => {
+    if (!data.timer) {
+      console.log("报警次数", res);
+    }
+    if (res.success) {
+      //this.countUserNumData = res.data;
+      nextTick(() => {
+        init(res.data.yearMonth, res.data.totalValue),
+          switper();
+      });
+    } else {
+      data.pageflag = false;
+    }
+  });
+}
+
+const charts = ref()
+//轮询
+const switper = () => {
+  if (data.timer) {
+    return;
+  }
+  let looper = (a) => {
+    getData();
+  };
+  data.timer = setInterval(
+    looper,
+    store.state.echartsAutoTime
+  );
+
+  // *** 为获取到echart实例,on方法用不了。未解决
+  // let myChart = charts.chart;
+  // myChart.on("mouseover", (params) => {
+  //   clearData();
+  // });
+  // myChart.on("mouseout", (params) => {
+  //   data.timer = setInterval(
+  //     looper,
+  //     store.state.echartsAutoTime
+  //   );
+  // });
+}
+
+
+
+const init = (xData, yData) => {
+  option.value = {
+    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: "报警次数",
+        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>

+ 102 - 0
admin.ui.plus-master/src/views/admin/visualization/newDeviceVision/setting.vue

@@ -0,0 +1,102 @@
+<template>
+    <transition name="yh-setting-fade">
+        <div class="setting" :class="{ settingShow: data.settingShow }" v-show="data.settingShow">
+            <div class="setting_dislog" @click="data.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="data.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="data.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="data.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 setup>
+import { onMounted, onUnmounted, reactive } from 'vue';
+
+
+const data = reactive({
+    settingShow: false,
+    sbtxradio: true,
+    ssyjradio: true,
+    isScaleradio: true,
+})
+
+const init = (() => {
+    data.settingShow = true
+})
+
+const 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()
+    }
+})
+
+// 在组件实例化时执行
+this.$store.commit('setting/initSwipers')
+data.sbtxradio = this.$store.state.setting.sbtxSwiper
+data.ssyjradio = this.$store.state.setting.ssyjSwiper
+data.isScaleradio = this.$store.state.setting.isScale
+
+onMounted(() => {
+    document.body.appendChild(this.$el);
+})
+
+onUnmounted(() => {
+    if (this.$el && this.$el.parentNode) {
+        this.$el.parentNode.removeChild(this.$el);
+    }
+})
+
+
+</script>
+
+<style lang='scss' scoped></style>

+ 27 - 14
admin.ui.plus-master/tsconfig.json

@@ -1,13 +1,17 @@
 {
   "compilerOptions": {
     /* Visit https://aka.ms/tsconfig.json to read more about this file */
-
     /* Basic Options */
     // "incremental": true,                   /* Enable incremental compilation */
     "target": "esnext" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */,
     "module": "esnext" /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */,
-    "lib": ["esnext", "dom", "dom.iterable", "scripthost"] /* Specify library files to be included in the compilation. */,
-    // "allowJs": true,                       /* Allow javascript files to be compiled. */
+    "lib": [
+      "esnext",
+      "dom",
+      "dom.iterable",
+      "scripthost"
+    ] /* Specify library files to be included in the compilation. */,
+    "allowJs": true, /* Allow javascript files to be compiled. */
     // "checkJs": true,                       /* Report errors in .js files. */
     "jsx": "preserve" /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */,
     // "declaration": true /* Generates corresponding '.d.ts' file. */,
@@ -23,7 +27,6 @@
     // "importHelpers": true /* Import emit helpers from 'tslib'. */,
     // "downlevelIteration": true /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */,
     "isolatedModules": true /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */,
-
     /* Strict Type-Checking Options */
     "strict": true /* Enable all strict type-checking options. */,
     // "noImplicitAny": true,                 /* Raise error on expressions and declarations with an implied 'any' type. */
@@ -33,42 +36,52 @@
     // "strictPropertyInitialization": true,  /* Enable strict checking of property initialization in classes. */
     // "noImplicitThis": true,                /* Raise error on 'this' expressions with an implied 'any' type. */
     // "alwaysStrict": true,                  /* Parse in strict mode and emit "use strict" for each source file. */
-
     /* Additional Checks */
     // "noUnusedLocals": true,                /* Report errors on unused locals. */
     // "noUnusedParameters": true,            /* Report errors on unused parameters. */
     // "noImplicitReturns": true,             /* Report error when not all code paths in function return a value. */
     // "noFallthroughCasesInSwitch": true,    /* Report errors for fallthrough cases in switch statement. */
     // "noUncheckedIndexedAccess": true,      /* Include 'undefined' in index signature results */
-
     /* Module Resolution Options */
     "moduleResolution": "node" /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */,
     "baseUrl": "." /* Base directory to resolve non-absolute module names. */,
     "paths": {
-      "/@/*": ["src/*"]
+      "/@/*": [
+        "src/*"
+      ]
     } /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */,
     // "rootDirs": [],                        /* List of root folders whose combined content represents the structure of the project at runtime. */
     // "typeRoots": [],                       /* List of folders to include type definitions from. */
-    "types": ["vite/client"] /* Type declaration files to be included in compilation. */,
+    "types": [
+      "vite/client"
+    ] /* Type declaration files to be included in compilation. */,
     "allowSyntheticDefaultImports": true /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */,
     "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */,
     // "preserveSymlinks": true,              /* Do not resolve the real path of symlinks. */
     // "allowUmdGlobalAccess": true,          /* Allow accessing UMD globals from modules. */
-
     /* Source Map Options */
     // "sourceRoot": "",                      /* Specify the location where debugger should locate TypeScript files instead of source locations. */
     // "mapRoot": "",                         /* Specify the location where debugger should locate map files instead of generated locations. */
     // "inlineSourceMap": true,               /* Emit a single file with source maps instead of having a separate file. */
     // "inlineSources": true,                 /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */
-
     /* Experimental Options */
     "experimentalDecorators": true /* Enables experimental support for ES7 decorators. */,
     // "emitDecoratorMetadata": true,         /* Enables experimental support for emitting type metadata for decorators. */
-
     /* Advanced Options */
     "skipLibCheck": true /* Skip type checking of declaration files. */,
     "forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */
   },
-  "include": ["src/**/*.ts", "src/**/*.vue", "src/**/*.tsx", "src/**/*.d.ts", "vite.config.ts"], // **Represents any directory, and * represents any file. Indicates that all files in the src directory will be compiled
-  "exclude": ["node_modules", "dist"] // Indicates the file directory that does not need to be compiled
-}
+  "include": [
+    "src/**/*.ts",
+    "src/**/*.vue",
+    "src/**/*.tsx",
+    "src/**/*.d.ts",
+    "vite.config.ts",
+    "src/stores/newDeviceVision/index.js",
+    // "src/plugins/*.js"
+  ], // **Represents any directory, and * represents any file. Indicates that all files in the src directory will be compiled
+  "exclude": [
+    "node_modules",
+    "dist"
+  ] // Indicates the file directory that does not need to be compiled
+}

Certains fichiers n'ont pas été affichés car il y a eu trop de fichiers modifiés dans ce diff