Browse Source

Merge branch 'yx' into update/V1.0.2

杨宽 3 years ago
parent
commit
003693742d

+ 5 - 3
package.json

@@ -10,14 +10,17 @@
   },
   "dependencies": {
     "@arcgis/core": "^4.19.3",
+    "axios": "^0.21.1",
     "core-js": "^3.6.5",
     "echarts": "^5.1.1",
     "echarts-gl": "^2.0.4",
-    "element-plus": "^1.0.2-beta.28",
+    "element-plus": "^1.0.2-beta.46",
     "font-awesome": "^4.7.0",
+    "stompjs": "^2.3.3",
     "three": "^0.129.0",
     "vivus": "^0.4.6",
     "vue": "^3.0.0",
+    "vue-axios": "^3.2.4",
     "vue-router": "^4.0.0-0",
     "vuex": "^4.0.0-0"
   },
@@ -40,8 +43,7 @@
     "sass-loader": "^10.0.4",
     "style-resources-loader": "^1.4.1",
     "svg-sprite-loader": "^6.0.7",
-    "svgo-loader": "^3.0.0",
-    "vue-cli-plugin-element-plus": "0.0.13"
+    "svgo-loader": "^3.0.0"
   },
   "eslintConfig": {
     "root": true,

+ 22 - 0
public/static/config/modeConfig.js

@@ -0,0 +1,22 @@
+
+// 本地联调开关
+const localTest = 0;
+
+// 服务器地址
+let baseURL = null;
+
+// websocket 服务器地址
+let websocketUrl = null;
+
+if (localTest) {
+  baseURL = "http://192.168.10.23:8082/" // 联机调试 - 石林
+  websocketUrl = (baseURL.replace(/http:\/\//g, "")) + "gyee-websocket";
+} else {
+  baseURL = "http://10.155.32.4:8082/" // 正式环境
+  websocketUrl = (baseURL.replace(/http:\/\//g, "")) + "gyee-websocket";
+}
+
+window.__MODE__ = {
+  baseURL,
+  websocketUrl
+};

File diff suppressed because it is too large
+ 79 - 105
src/App.vue


+ 32 - 0
src/api/AES.js

@@ -0,0 +1,32 @@
+import CryptoJS from 'crypto-js';
+/**
+ * CryptoJS加密
+ */
+export function localEncrypt(word, keyStr) {
+  keyStr = keyStr ? keyStr : "BTRH201911PERMIS";
+  let key = CryptoJS.enc.Utf8.parse(keyStr);
+  let srcs = CryptoJS.enc.Utf8.parse(word);
+  let encrypted = CryptoJS.AES.encrypt(srcs, key, {
+    mode: CryptoJS.mode.ECB,
+    padding: CryptoJS.pad.Pkcs7
+  });
+  return encrypted.toString();
+}
+
+/**
+ * CryptoJS解密
+ */
+export function localDecrypt(word, keyStr) {
+  keyStr = keyStr ? keyStr : "BTRH201911PERMIS";
+  var key = CryptoJS.enc.Utf8.parse(keyStr);
+  var decrypt = CryptoJS.AES.decrypt(word, key, {
+    mode: CryptoJS.mode.ECB,
+    padding: CryptoJS.pad.Pkcs7
+  });
+  return CryptoJS.enc.Utf8.stringify(decrypt).toString();
+}
+
+export default {
+  localEncrypt,
+  localDecrypt
+}

+ 116 - 0
src/api/axios.js

@@ -0,0 +1,116 @@
+// 引入axios
+import axios from 'axios';
+import BASE from '@tools/basicTool.js';
+
+axios.defaults.withCredentials = true;
+
+/**
+ * 通用请求函数
+ * @param {Object} options 详细配置项,使用方法与所有配置项说明如下:
+
+  this.API.requestData({
+    isMust: true, // 请求是否携带 token ,默认为 true ,可缺省
+    showLoading: false, // 请求是否显示加载中遮罩层,默认 false ,可缺省
+    method: "GET", // 请求方式,默认为 GET ,可缺省
+    baseURL: "http://192.168.10.23:8082/", // 请求服务器地址 + 端口,可缺省
+    subUrl: "api/repassword", // 请求接口地址,必传项
+    timeout: 3000, // 请求超时时间,默认 3s ,可缺省
+    data: { name: "admin", pasword: "123456" }, // 请求所携带参数,默认为空,可缺省
+    success (res) {
+      // 请求成功的回调
+    },
+    fail (error) {
+      // 请求失败的回调
+    }
+  });
+
+ */
+export function requestData (options) {
+  return new Promise((resolve, reject) => {
+
+    if (options.showLoading) {
+      BASE.showLoading();
+    }
+
+    // 包装请求头
+    let headers = options.headers || {
+      'Content-Type': 'application/x-www-form-urlencoded',
+      'Access-Control-Allow-Origin': '*',
+      'Access-Control-Allow-Credentials': 'true'
+    };
+
+    // 请求是否携带 token
+    const isMust = (options.isMust == true || options.isMust == false) ? options.isMust : true;
+    if (isMust) headers.authToken = localStorage.getItem('authToken');
+
+    // 创建请求实例
+    const XHRReq = axios.create({
+      headers,
+      withCredentials: true,
+      crossDomain: true,
+      baseURL: options.baseURL || window.__MODE__.baseURL || '/api/',
+      timeout: options.timeout || 3000, // 请求超时时间 - 3s
+    });
+
+    // 请求拦截器
+    XHRReq.interceptors.request.use((config) => {
+      return config;
+    }, (err) => {
+      return Promise.reject(err);
+    });
+
+    // 统一格式包装请求参数
+    let params = new URLSearchParams();
+    for (let key in (options.data || {})) {
+      params.append(key, options.data[key]);
+    }
+
+    // 发起请求
+    XHRReq({
+      url: options.subUrl,
+      method: options.method || 'GET',
+      params,
+    }).then(response => {
+      if (options.showLoading) {
+        BASE.closeLoading();
+      }
+      if (response.code === 501) { // 用户类请求错误code (账号密码错误、用户锁定、token过期等)
+
+        localStorage.removeItem('authToken');
+        BASE.showMsg({
+          msg: (response.data && response.data.msg) || ("请求出错[" + response.data.code + "]")
+        });
+
+        setTimeout(() => {
+          // window.location.reload();
+          // window.__STATICVUE__.$router.replace('/login');
+        }, 1000);
+
+      } else if (response.data.code === 200) { // 请求成功 code
+
+        options.success && options.success(response.data);
+        resolve(response);
+
+      } else { // 其他code
+
+        BASE.showMsg({
+          msg: (response.data && response.data.msg) || ("请求出错[" + response.data.code + "]")
+        });
+
+      }
+    }).catch(error => {
+
+      if (options.showLoading) {
+        BASE.closeLoading();
+      }
+
+      options.fail && options.fail(error);
+      reject(error);
+
+    });
+  });
+}
+
+export default {
+  requestData
+}

+ 13 - 0
src/api/config.js

@@ -0,0 +1,13 @@
+/**
+ * 国电电力宁夏新能源集中监控系统
+ * */
+
+//测试 - 国电
+export default {
+  webSoketUrl: 'ws://10.155.32.4:8082/gyee-websocket', // webSoket
+}
+
+//生产 - 国电
+// export default {
+//   webSoketUrl: '192.168.4.203:9008', // webSoket
+// }

+ 32 - 32
src/components/chart/line/multiple-line-chart.vue

@@ -41,15 +41,15 @@ export default {
             },
             {
               text: "4",
-              value: 3,
+              value: 4,
             },
             {
               text: "5",
-              value: 3,
+              value: 6,
             },
             {
               text: "6",
-              value: 3,
+              value: 2,
             },
             {
               text: "7",
@@ -57,7 +57,7 @@ export default {
             },
             {
               text: "8",
-              value: 3,
+              value: 8,
             },
             {
               text: "9",
@@ -65,15 +65,15 @@ export default {
             },
             {
               text: "10",
-              value: 3,
+              value: 2,
             },
             {
               text: "11",
-              value: 3,
+              value: 5,
             },
             {
               text: "12",
-              value: 3,
+              value: 8,
             },
             {
               text: "13",
@@ -81,7 +81,7 @@ export default {
             },
             {
               text: "14",
-              value: 3,
+              value: 9,
             },
             {
               text: "15",
@@ -89,11 +89,11 @@ export default {
             },
             {
               text: "16",
-              value: 3,
+              value: 2,
             },
             {
               text: "17",
-              value: 3,
+              value: 1,
             },
             {
               text: "18",
@@ -101,23 +101,23 @@ export default {
             },
             {
               text: "19",
-              value: 3,
+              value: 4,
             },
             {
               text: "20",
-              value: 3,
+              value: 9,
             },
             {
               text: "21",
-              value: 3,
+              value: 2,
             },
             {
               text: "22",
-              value: 3,
+              value: 1,
             },
             {
               text: "23",
-              value: 3,
+              value: 2,
             },
             {
               text: "24",
@@ -129,27 +129,27 @@ export default {
             },
             {
               text: "26",
-              value: 3,
+              value: 4,
             },
             {
               text: "27",
-              value: 3,
+              value: 9,
             },
             {
               text: "28",
-              value: 3,
+              value: 7,
             },
             {
               text: "29",
-              value: 3,
+              value: 4,
             },
             {
               text: "30",
-              value: 3,
+              value: 1,
             },
             {
               text: "31",
-              value: 3,
+              value: 2,
             },
           ],
         },
@@ -215,7 +215,7 @@ export default {
       default: () => ["(MW)", "(风速)"],
     },
   },
-  data() {
+  data () {
     return {
       id: "",
       chart: null,
@@ -223,17 +223,17 @@ export default {
     };
   },
   computed: {
-    datas() {
+    datas () {
       return this.list.map((t) => {
         return t.value;
       });
     },
-    xdata() {
+    xdata () {
       return this.list[0].value.map((t) => {
         return t.text;
       });
     },
-    series() {
+    series () {
       let result = [];
 
       this.list.forEach((value, index) => {
@@ -280,7 +280,7 @@ export default {
 
       return result;
     },
-    yAxis() {
+    yAxis () {
       let result = [];
       this.units.forEach((value, index) => {
         result.push({
@@ -304,7 +304,7 @@ export default {
     },
   },
   methods: {
-    hexToRgba(hex, opacity) {
+    hexToRgba (hex, opacity) {
       let rgbaColor = "";
       let reg = /^#[\da-f]{6}$/i;
       if (reg.test(hex)) {
@@ -312,7 +312,7 @@ export default {
       }
       return rgbaColor;
     },
-    initChart() {
+    initChart () {
       let option = {
         color: this.color,
         tooltip: {
@@ -322,7 +322,7 @@ export default {
             color: "#fff",
             fontSize: util.vh(16),
           },
-          formatter: function(param) {
+          formatter: function (param) {
             console.log(param);
             return param.name + "<br >" + param.marker + param.seriesName + ":" + param.value;
           },
@@ -354,16 +354,16 @@ export default {
       this.chart.setOption(option);
     },
   },
-  created() {
+  created () {
     this.id = "pie-chart-" + util.newGUID();
   },
-  mounted() {
+  mounted () {
     this.$el.style.width = this.width;
     this.$el.style.height = this.height;
     this.chart = echarts.init(this.$el);
     this.initChart();
   },
-  updated() {
+  updated () {
     this.initChart();
   },
 };

+ 13 - 12
src/components/coms/table/table-span.vue

@@ -2,13 +2,14 @@
   <table class="com-table">
     <thead>
       <tr>
-        <th v-for="(col, index) of data.column" :key="index" :class="{ light: col.is_light }">{{ col.name }}<br v-if="col.unit != ''" />{{ col.unit }}</th>
+        <th v-for="(col, index) of data.column" :key="index" :class="{ light: col.is_light }">{{ col.name }}<br v-if="col.unit != ''" />{{
+          col.unit }}</th>
       </tr>
     </thead>
     <tbody>
       <tr v-for="(row, index) of data.data" :key="index">
         <td :rowspan="rowspan(row, col)" :colspan="colspan(row, col)" v-for="(col, i) of data.column" :key="i" :class="{ light: col.is_light || row.is_light, num: col.is_num, remove: row[col.field] == '' }">
-          {{ row[col.field] }}
+          {{ row[col.field] || "a" }}
         </td>
       </tr>
     </tbody>
@@ -28,13 +29,13 @@ export default {
   // 自定义事件
   emits: {},
   // 数据
-  data() {
+  data () {
     return {};
   },
   computed: {},
   // 函数
   methods: {
-    rowspan: function(row, col) {
+    rowspan: function (row, col) {
       if (row.row_span.length == 0) {
         return 1;
       } else {
@@ -46,7 +47,7 @@ export default {
         }
       }
     },
-    colspan: function(row, col) {
+    colspan: function (row, col) {
       if (row.col_span.length == 0) {
         return 1;
       } else {
@@ -60,22 +61,22 @@ export default {
     },
   },
   // 生命周期钩子
-  beforeCreate() {
+  beforeCreate () {
     // 创建前
   },
-  created() {
+  created () {
     // 创建后
   },
-  beforeMount() {
+  beforeMount () {
     // 渲染前
   },
-  mounted() {
+  mounted () {
     // 渲染后
   },
-  beforeUpdate() {
+  beforeUpdate () {
     // 数据更新前
   },
-  updated() {
+  updated () {
     // 数据更新后
   },
 };
@@ -125,7 +126,7 @@ export default {
         }
 
         &.num {
-          font-family: "Bicubik";
+          font-family: 'Bicubik';
           font-weight: 400;
         }
 

+ 46 - 14
src/main.js

@@ -1,18 +1,50 @@
-import { createApp } from 'vue'
-import App from './App.vue'
-import router from './router'
-import store from './store'
-import 'font-awesome/css/font-awesome.min.css'
+import { createApp } from 'vue';
+import App from './App.vue';
+import router from './router';
+import store from './store';
+import 'font-awesome/css/font-awesome.min.css';
 
-import "@/lib/global-import.js";
-
-// element-ui
+// 引入 element-ui
 import ElementPlus from 'element-plus';
 import 'element-plus/lib/theme-chalk/index.css';
-import locale from 'element-plus/lib/locale/lang/zh-cn'
 
-let app = createApp(App)
-    .use(store)
-    .use(router)
-    .use(ElementPlus, { locale })
-    .mount('#app')
+// 引入环境配置
+import "@modeConfig/modeConfig.js";
+
+import "@/lib/global-import.js";
+
+// 引入请求工具
+import axios from "@api/axios";
+
+// 引入基础工具
+import basicTool from "@tools/basicTool";
+
+/**
+ * 对 Date 的扩展,将 Date 转化为指定格式的字符串
+ * @param {String} fmt 传入一个字符串,根据所传字符串的格式返回转换后特定格式的日期,调用姿势:new Date().formatDate("yyyy-MM-dd hh:mm:ss");
+ */
+Date.prototype.formatDate = function (fmt) {
+  let o = {
+    "M+": this.getMonth() + 1, //月份 
+    "d+": this.getDate(), //日 
+    "h+": this.getHours(), //小时 
+    "m+": this.getMinutes(), //分 
+    "s+": this.getSeconds(), //秒 
+    "q+": Math.floor((this.getMonth() + 3) / 3), //季度 
+    "S": this.getMilliseconds() //毫秒 
+  };
+  if (/(y+)/.test(fmt)) fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length));
+  for (let 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;
+}
+
+window.__STATICVUE__ = createApp(App);
+window.__STATICVUE__.use(ElementPlus);
+window.__STATICVUE__.use(store);
+window.__STATICVUE__.use(router);
+
+window.__STATICVUE__.config.globalProperties.API = axios; //全局注册
+window.__STATICVUE__.config.globalProperties.BASE = basicTool; //全局注册
+
+window.__STATICVUE__.mount('#app');

+ 1 - 0
src/router/index.js

@@ -78,6 +78,7 @@ const routes = [
 
 const router = createRouter({
   history: createWebHashHistory(),
+  base: '/zhfx/',
   routes
 })
 

+ 49 - 5
src/store/index.js

@@ -1,12 +1,56 @@
-import { createStore, createLogger } from 'vuex'
-import weather from './modules/weather'
+import { createStore, createLogger } from 'vuex';
+import weather from './modules/weather';
+import user from './modules/user';
 
-const debug = process.env.NODE_ENV !== 'production'
+const debug = process.env.NODE_ENV !== 'production';
+
+// 默认状态
+const state = {
+  websocketTimeSec: 5000,
+  loading: false, //全局 - 加载中....
+  themeName: "light", // 主题
+  windturbineMap: {},
+};
+
+//改变状态的方法
+const mutations = {
+  loadingStore (state, tag) {
+    state.loading = tag;
+  },
+  changeTheme (state, tag) {
+    state.themeName = tag;
+  },
+  update (state, newData) {
+    state.windturbineMap = newData.data
+  }
+};
+
+const actions = {
+  getupdate (context, newData) {
+    context.commit("update", newData);
+  },
+};
+
+const getters = {
+  authToken: state => state.user.authToken,  //建立token的快捷访问   user 是因为index.js中导入的时候名称定义为user
+  submitDDTag: state => state.submitDDTag,
+  loading: state => state.loading,
+  username: state => state.user.username,
+  themeName: state => state.themeName,
+  asidez: state => state.z,
+  mainy: state => state.y,
+  login: state => state.login
+}
 
 export default createStore({
   modules: {
-    weather
+    weather,
+    user
   },
+  state,
+  mutations,
+  actions,
+  getters,
   strict: debug,
   plugins: debug ? [createLogger()] : []
-})
+});

+ 46 - 0
src/store/modules/user.js

@@ -0,0 +1,46 @@
+// import {getToken,setToken,removeToken} from '@/utils/auth'
+// import { Message } from 'element-plus';
+const state = {
+  authToken: '', //
+  username: '',
+}
+const mutations = {
+  REMOVE_TOKEN (state) {
+    localStorage.removeItem('authToken');
+    localStorage.removeItem('username');
+    state.authToken = "";
+    state.username = "";
+    Message({
+      message: '退出成功',
+      type: 'success'
+    });
+    setTimeout(() => {
+      window.location.reload();
+    }, 1000);
+
+  },
+  SET_TOKEN: (state, token_name) => {
+    state.authToken = token_name.token;
+    state.username = token_name.username;
+    localStorage.setItem('authToken', token_name.token);
+    localStorage.setItem('username', token_name.username);
+  },
+  SET_NAME: (state, name) => {
+    state.username = name;
+  },
+}
+const actions = {
+  async login (context, data) {
+    const result = await login(data)
+    if (result.data.sucess) {
+      //调用vuex中setToken方法
+      context.commit('setToken', result.data.data)
+    }
+  }
+}
+export default {
+  namespaced: true,
+  state,
+  mutations,
+  actions,
+}

+ 264 - 0
src/tools/basicTool.js

@@ -0,0 +1,264 @@
+
+let loadingStatus = null;
+
+import { ElMessage } from 'element-plus';
+import { ElLoading } from 'element-plus';
+
+export default {
+  /**
+   * 页面顶部出现消息提示
+   * @param {Object} options 传入一个对象为配置项,其中:
+   * @param {Boolean} showClose 是否显示可手动关闭的 x 于提示框右侧,默认 false
+   * @param {Boolean} center 消息提示内容是否居中,默认 true
+   * @param {String} msg 消息提示的内容
+   * @param {String} type 消息提示的类型,可选值为 ['success(成功)','warning(警告)','error(错误)',或者直接传入空字符串],默认 error
+   */
+  showMsg (options) {
+    ElMessage({
+      showClose: (options.showClose == true || options.showClose == false) ? options.showClose : false,
+      center: (options.center == true || options.center == false) ? options.center : true,
+      message: options.msg,
+      type: (options.type || options.type === '') ? options.type : 'error'
+    });
+  },
+
+  /**
+   * 显示防穿透点击 loading 蒙版
+   * @param {Objectr} opt 传入一个对象为配置项,其中:
+   * @param {String} target 此蒙版需要绑定的 DOM 标签 ID 或者 CLASS 或者 TAGNAME,默认绑在 body 上
+   * @param {Boolean} body 是否插入蒙版至 boyd 上,默认 true
+   * @param {Boolean} fullscreen 蒙版是否全屏蒙住整个 html 页面,默认 true
+   * @param {Boolean} lock 蒙版出现时,是否锁定屏幕滚动,默认 false
+   * @param {String} text 蒙版上显示的提示文本
+   * @param {String} background 蒙版的背景颜色,写死 50% 透明度的纯黑色
+   */
+  showLoading (opt) {
+    let options = opt || {};
+    loadingStatus = ElLoading.service({
+      target: options.target || 'body',
+      body: (options.body == true || options.body == false) ? options.body : false,
+      fullscreen: (options.fullscreen == true || options.fullscreen == false) ? options.fullscreen : true,
+      lock: (options.lock == true || options.lock == false) ? options.lock : false,
+      text: options.text || '请稍等...',
+      background: 'rgba(0,0,0,.5)',
+    });
+  },
+
+  /**
+   * 获取标签上的自定义属性
+   * @param {any} node 传入 字符串 或 标准DOM对象 或 jQuery DOM对象 ,函数自动判断传入的类型并返回其 dataset 属性。
+   */
+  getCurrentData (node) {
+    // 如果传入的是 jQuery 对象
+    if (window.jQuery && node instanceof jQuery) {
+      return node[0].dataset;
+    } else {
+      // 判断传入的是否是标准 DOM 对象
+      let isDom = (typeof node === 'object') ?
+        function (obj) {
+          return obj instanceof HTMLElement;
+        } :
+        function (obj) {
+          return obj && typeof obj === 'object' && obj.nodeType === 1 && typeof obj.nodeName === 'string';
+        };
+
+      // 如果是标准 DOM 对象,输出 dataset
+      if (isDom(node)) {
+        return node.dataset;
+      } else {
+        // 如果是不是,则表示传入的是字符串,根据字符串取 DOM 后输出 dataset
+        let dom = document.querySelector(node);
+        return dom.dataset;
+      }
+    }
+  },
+
+  /**
+   * 关闭loading
+   */
+  closeLoading () {
+    loadingStatus.close();
+  },
+
+  /**
+   * 深拷贝 json 数组
+   * @param {Array} jsonArray 传入 Json 数组,返回一个指向新指针拷贝份数据
+   */
+  deepCopy (jsonArray) {
+    return JSON.parse(JSON.stringify(jsonArray));
+  },
+
+  /**
+   * 根据后端返回的 ID 遍历树形结构包装组件编辑用数据函数
+   * @param {String} key 需要找到的 ID
+   * @param {Array} treeData 树形 Array
+   */
+  getTreeDeepArr (key, treeData) {
+
+    let arr = []; // 在递归时操作的数组
+    let returnArr = []; // 存放结果的数组
+    let depth = 0; // 定义全局层级
+
+    // 定义递归函数
+    function childrenEach (childrenData, depthN) {
+
+      for (var j = 0; j < childrenData.length; j++) {
+
+        depth = depthN; // 将执行的层级赋值 到 全局层级
+        arr[depthN] = (childrenData[j].id);
+
+        if (childrenData[j].id == key) {
+
+          // returnArr = arr; // 原写法不行, 因 此赋值存在指针关系
+          returnArr = arr.slice(0, depthN + 1); //将目前匹配的数组,截断并保存到结果数组
+          break;
+
+        } else {
+
+          if (childrenData[j].children) {
+
+            depth++;
+            childrenEach(childrenData[j].children, depth);
+
+          }
+
+        }
+
+      }
+
+      return returnArr;
+
+    }
+
+    return childrenEach(treeData, depth);
+
+  },
+
+  /**
+   * 获取数据的类型
+   * @param {any} options 传入一个数据,返回其类型 (object, array, string, number等)
+   */
+  getType (options) {
+    return Object.prototype.toString.call(options).slice(8, Object.prototype.toString.call(options).length - 1).toLowerCase();
+  },
+
+  /**
+   * 控制页面滚动到指定位置
+   * @param {Object} options 传入一个配置项,其中:
+   * @param {String} el 需要滚动的 DOM 元素选择器,可以为 CLASS 或 ID
+   * @param {Number} scrollTop 需要滚动到顶部的位置,数值越低滚动的越靠近顶部,默认 0
+   * @param {Number} scrollLeft 需要滚动到顶部的位置,数值越低滚动的越靠近顶部,默认 0
+   * @param {Number} speed 滚动到指定位置需要的时间 (动画时间),默认 200
+   * @param {Function} success 滚动执行完毕后的回调函数
+   */
+  scrollTo (options) {
+    if (!options || !options.el) {
+      this.showMsg({
+        msg: 'scrollTo() 方法需要传入 el 属性'
+      });
+      return;
+    }
+    if ($(options.el)[0] && ($(options.el)[0].scrollHeight > (window.innerHeight || document.documentElement.clientHeight))) {
+      $(options.el).animate({
+        scrollTop: options.scrollTop || 0,
+        scrollLeft: options.scrollLeft || 0,
+      }, options.speed || 200, () => {
+        options.success && options.success();
+      });
+    } else {
+      options.success && options.success();
+    }
+  },
+
+  /**
+   * 导出 Json 为 excel 表格
+   * @param {Object} options 传入一个配置项,根据传入的配置项导出对应的 excel 表格,其中:
+   * @param {Array} tTitle 表格的标题,置空则为默认以日期为标题的表格
+   * @param {Array} tHeader 表格的表头,必传
+   * @param {Array} tBody 表格需要展示的字段名,必传
+   * @param {Array} tMerges 表格标题需要合并的单元格,置空则为默认 A1 格为表格标题显示区域
+   * @param {Array} tData 表格渲染所用的数据源,必传
+   * @param {Boolean} autoWidth 表是否根据表格内容自动撑开列宽,置空则为默认 true 
+   * @param {String} exportName 所导出的表格文件名,置空则以时间戳为文件名称进行导出
+   */
+  exportExcelForJson (options) {
+    const {
+      export_json_to_excel
+    } = __getExport2Excel();
+
+    let title = options.tTitle;
+
+    if (!title || !title.length) {
+      title = []
+      options.tBody.forEach((ele, index) => {
+        if (!index) {
+          title.push(new Date().formatDate("yyyy-MM-dd") + '导出的表格');
+        } else {
+          title.push("");
+        }
+      });
+    }
+
+    let header = options.tHeader;
+    let data = options.tData.map(data => options.tBody.map(key => data[key]));
+    let merges = options.tMerges || [];
+    let filename = options.exportName || new Date().getTime();
+    let bookType = "xlsx";
+    let autoWidth = (options.autoWidth == true || options.autoWidth == false) ? options.autoWidth : true;
+
+    data.map(item => {
+      item.map((i, index) => {
+        if (!i) item[index] = "";
+      });
+    });
+
+    export_json_to_excel({
+      title,
+      header,
+      data,
+      merges,
+      filename,
+      bookType,
+      autoWidth
+    });
+  },
+
+  /**
+   * 颜色进制转换  16 <--> 10 互转
+   * @param {String} colorStr 传入一个颜色字符串, 16进制 或者 10进制 ,返回转换后的结果,例:传入 #1890ff ,返回 rgb(24, 144, 255),反之亦然
+   */
+  replaceColor (colorStr) {
+    if (!colorStr) return '';
+
+    let colorString = colorStr.replace(/#|rgb|\(|\)|\|;|\s+/g, "");
+
+    if (colorString.indexOf(",") === -1) {
+      let color10 = [];
+      for (let i = 0; i < colorString.length; i++) {
+        if (!((i + 1) % 2)) {
+          color10.push(parseInt((colorString[i - 1] + colorString[i]), 16));
+        }
+      }
+      return "rgb(" + color10.toString() + ")";
+    } else {
+      let colorArray = colorString.split(',');
+      let color16 = '';
+      colorArray.forEach(ele => {
+        color16 += (parseInt(ele).toString(16));
+      });
+      return "#" + color16;
+    }
+  },
+
+  // 正则表达式
+  regs: {
+    // 是否为手机号
+    isPhone: /^1(3|4|5|6|7|8|9)\d{9}$/,
+    // 是否为合法 15 或 18 位身份证号
+    isIdentityCard: /^[1-9]\d{7}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}$|^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}([0-9]|X)$/,
+    // 是否是邮箱
+    isMail: /^[a-zA-Z0-9_.-]+@[a-zA-Z0-9-]+(\.[a-zA-Z0-9-]+)*\.[a-zA-Z0-9]{2,6}$/,
+    // 是否是数字
+    isNumber: /^(-?\d+)(\.\d+)?$/
+  }
+};

+ 56 - 0
src/tools/websocket.js

@@ -0,0 +1,56 @@
+import Stomp from "stompjs";
+import store from '@store/index';
+var projectconfig = `ws://${window.__MODE__.websocketUrl}`;
+// ============================一般使用的变量============================
+let number = 0;
+export const datainit = initialize;
+export const webtest = test;
+
+// ============================  大函数体   ============================
+function initialize (topic, adpClient) {
+
+  if (adpClient != null) {
+    adpClient.disconnect();
+  }
+
+  var url = projectconfig;
+  // let socket = new SockJS(url);  // 这个地址要找你们后端
+  // adpClient = Stomp.over(socket);
+  adpClient = Stomp.client(url);
+  adpClient.debug = null;
+
+  adpClient.connect({ topic: topic, authToken: localStorage.getItem('authToken') }, adpClient2 => connectCallBackSubscribe(adpClient, topic), error => reconnect(error, adpClient, topic));
+
+  return adpClient;
+}
+// 断线重连
+function reconnect (error, adpClient, topic) {
+  //连接失败时再次调用函数
+  number++;
+  adpClient.connected = false;
+  clearTimeout(setTimeout(initialize(topic), 1000 * 60 * 5));
+  debugX("DataAdapter reconnect:" + number + " 次");
+  return;
+}
+// ============================  订阅函数体  ============================
+function connectCallBackSubscribe (adpClient, topic) {
+  number = 0;
+  adpClient.connected = true;
+  adpClient.subscribe(topic, stompMessage => reflexWindturbineBasicInformation(stompMessage));
+}
+// ============================  解析函数体  ============================
+function reflexWindturbineBasicInformation (stompMessage) {
+  var newdata = JSON.parse(stompMessage.body);
+  store.dispatch('getupdate', newdata);
+  // console.log("newdata", newdata);
+
+}
+// ============================  其他  ============================
+function debugX (text) {
+  console.log("text", text);
+}
+
+function test () {
+  clearTimeout(setTimeout(initialize('/topic/detial/param_MG01_02'), 1000 * 60 * 2));
+}
+

+ 78 - 21
src/views/Agc/Agc.vue

@@ -1,10 +1,11 @@
 <template>
   <div class="agc">
     <div class="btn-group-tabs">
-      <BtnGroup2 :btnGroups="btnGroups" :rowIndex="0" :index="1" @select="select"></BtnGroup2>
+      <!-- <BtnGroup2 :btnGroups="btnGroups" :rowIndex="0" :index="1" @select="select"></BtnGroup2> -->
     </div>
     <div class="panel-groups">
-      <AgcPanel class="panel-item" v-for="(data, index) of datas" :key="index" :data="data"></AgcPanel>
+      <AgcPanel class="panel-item" v-for="(data, index) of datas" :key="index" :data="data" chartType="multiple"
+        :chartData="data.tb"></AgcPanel>
     </div>
   </div>
 </template>
@@ -12,6 +13,9 @@
 <script>
 import BtnGroup2 from "@com/coms/btn/btn-group-double.vue";
 import AgcPanel from "./components/agc-panel.vue";
+
+import store from "@store/index.js";
+
 export default {
   // 名称
   name: "Agc",
@@ -21,8 +25,9 @@ export default {
     AgcPanel,
   },
   // 数据
-  data() {
+  data () {
     return {
+      timmer: null, // 计时器
       datas: [
         {
           title: "某某风电场",
@@ -83,21 +88,74 @@ export default {
   },
   // 函数
   methods: {
-    select: function(item) {
-      console.log(item);
+    select: function (item) {
+      // console.log(item);
     },
+
+    // 请求服务
+    requestData (showLoading) {
+      let that = this;
+      that.API.requestData({
+        showLoading,
+        method: "POST",
+        subUrl: "genreset/getAgcValues",
+        success (res) {
+          let datas = [];
+          if (res.data) {
+            res.data.forEach(pEle => {
+
+              pEle.jcxx.icon = "fa fa-gears";
+              pEle.jcxx.color = pEle.jcxx.zt === 0 ? "red" : "green";
+
+              let keys = ["llgl", "sjgl", "xdzl", "ycgl"];
+
+              let tb = [{
+                title: "理论功率",
+                yAxisIndex: 0,
+                value: [],
+              }, {
+                title: "实际功率",
+                yAxisIndex: 0,
+                value: [],
+              }, {
+                title: "限电指令",
+                yAxisIndex: 0,
+                value: [],
+              }, {
+                title: "预测功率",
+                yAxisIndex: 0,
+                value: [],
+              }];
+
+              keys.forEach((key, keyIndex) => {
+                pEle.tb.forEach((cEle, cIndex) => {
+                  tb[keyIndex].value.push({ text: String((cIndex + 1)), value: cEle[keys[keyIndex]] || 0 });
+                });
+              });
+
+              pEle.tb = tb;
+              datas.push(pEle);
+            });
+            that.datas = datas;
+          } else {
+            that.datas = datas;
+          }
+        }
+      });
+    }
   },
-  // 生命周期钩子
-  beforeCreate() {
-    // 创建前
-  },
-  created() {
-    // 创建后
-  },
-  beforeMount() {
-    // 渲染前
+
+  created () {
+    let that = this;
+    that.$nextTick(() => {
+      that.requestData(true);
+      that.timmer = setInterval(() => {
+        that.requestData(false);
+      }, that.$store.state.websocketTimeSec);
+    });
   },
-  mounted() {
+
+  mounted () {
     // 渲染后
     for (let i = 1; i < 12; i++) {
       this.datas.push(JSON.parse(JSON.stringify(this.datas[0])));
@@ -106,12 +164,11 @@ export default {
       }
     }
   },
-  beforeUpdate() {
-    // 数据更新前
-  },
-  updated() {
-    // 数据更新后
-  },
+
+  unmounted () {
+    clearInterval(this.timmer);
+    this.timmer = null;
+  }
 };
 </script>
 

+ 32 - 19
src/views/Agc/components/agc-panel.vue

@@ -1,19 +1,20 @@
 <template>
-  <ComPanel :title="data.title" :icon="data.icon" :subTitle="data.subTitle" :color="data.color">
+  <ComPanel v-if="data && data.jcxx" :title="data.jcxx.name || '---'" :icon="data.jcxx.icon" :subTitle="data.jcxx.ddmc || '---'"
+    :color="data.jcxx.color">
     <table class="panel-table">
       <tbody>
         <tr>
           <td colspan="2">
             <div class="data-item">
               <span class="data-item-name">有功设定限制</span>
-              <span class="data-item-count">47.40</span>
+              <span class="data-item-count">{{data.jcxx.AGC002}}</span>
               <span class="data-item-unit">MW</span>
             </div>
           </td>
           <td colspan="2">
             <div class="data-item">
               <span class="data-item-name">实发有功</span>
-              <span class="data-item-count">47.40</span>
+              <span class="data-item-count">{{data.jcxx.SSZGL}}</span>
               <span class="data-item-unit">MW</span>
             </div>
           </td>
@@ -22,14 +23,14 @@
           <td colspan="2">
             <div class="data-item">
               <span class="data-item-name">AGC可调上限</span>
-              <span class="data-item-count">47.40</span>
+              <span class="data-item-count">{{data.jcxx.AGC003}}</span>
               <span class="data-item-unit">MW</span>
             </div>
           </td>
           <td colspan="2">
             <div class="data-item">
               <span class="data-item-name">理论功率</span>
-              <span class="data-item-count">47.40</span>
+              <span class="data-item-count">{{data.jcxx.ZZSGL}}</span>
               <span class="data-item-unit">MW</span>
             </div>
           </td>
@@ -38,14 +39,14 @@
           <td colspan="2">
             <div class="data-item">
               <span class="data-item-name">AGC可调下限</span>
-              <span class="data-item-count">47.40</span>
+              <span class="data-item-count">{{data.jcxx.AGC004}}</span>
               <span class="data-item-unit">MW</span>
             </div>
           </td>
           <td colspan="2">
             <div class="data-item">
               <span class="data-item-name">预测功率</span>
-              <span class="data-item-count">47.40</span>
+              <span class="data-item-count">{{data.jcxx.ycgl || 0}}</span>
               <span class="data-item-unit">MW</span>
             </div>
           </td>
@@ -54,37 +55,40 @@
           <td>
             <div class="data-item">
               <span class="data-item-name">AGC投入</span>
-              <i class="data-item-icon fa fa-chrome green"></i>
+              <i :class="'data-item-icon fa fa-chrome ' + (data.jcxx.AGC004 === 1 ? 'green' : 'red')"></i>
             </div>
           </td>
           <td>
             <div class="data-item">
               <span class="data-item-name">AGC远方</span>
-              <i class="data-item-icon fa fa-chrome green"></i>
+              <i :class="'data-item-icon fa fa-chrome ' + (data.jcxx.AGC005 === 1 ? 'green' : 'red')"></i>
             </div>
           </td>
           <td>
             <div class="data-item">
               <span class="data-item-name">有功增闭锁</span>
-              <i class="data-item-icon fa fa-chrome red"></i>
+              <i :class="'data-item-icon fa fa-chrome ' + (data.jcxx.AGC008 === 1 ? 'green' : 'red')"></i>
             </div>
           </td>
           <td>
             <div class="data-item">
               <span class="data-item-name">有功减闭锁</span>
-              <i class="data-item-icon fa fa-chrome red"></i>
+              <i :class="'data-item-icon fa fa-chrome ' + (data.jcxx.AGC007 === 1 ? 'green' : 'red')"></i>
             </div>
           </td>
         </tr>
       </tbody>
     </table>
-    <DoubleLineChart height="13.889vh"></DoubleLineChart>
+    <!-- 查看默认实例去除末尾参数 :list 即可 -->
+    <DoubleLineChart v-if="chartType=== 'double'" height="13.889vh" :list="chartData"></DoubleLineChart>
+    <MultipleLineChart v-if="chartType=== 'multiple'" height="13.889vh" :list="chartData"></MultipleLineChart>
   </ComPanel>
 </template>
 
 <script>
 import ComPanel from "@com/coms/panel/panel2.vue";
 import DoubleLineChart from "@com/chart/line/double-line-chart.vue";
+import MultipleLineChart from "@com/chart/line/multiple-line-chart.vue";
 export default {
   // 名称
   name: "AgcPanel",
@@ -92,36 +96,45 @@ export default {
   components: {
     ComPanel,
     DoubleLineChart,
+    MultipleLineChart
   },
   // 传入参数
   props: {
     data: Object,
+    chartType: {
+      type: String,
+      default: "double"
+    },
+    chartData: {
+      type: Array,
+      default: []
+    }
   },
   // 自定义事件
   emits: {},
   // 数据
-  data() {
+  data () {
     return {};
   },
   // 函数
   methods: {},
   // 生命周期钩子
-  beforeCreate() {
+  beforeCreate () {
     // 创建前
   },
-  created() {
+  created () {
     // 创建后
   },
-  beforeMount() {
+  beforeMount () {
     // 渲染前
   },
-  mounted() {
+  mounted () {
     // 渲染后
   },
-  beforeUpdate() {
+  beforeUpdate () {
     // 数据更新前
   },
-  updated() {
+  updated () {
     // 数据更新后
   },
 };

+ 157 - 115
src/views/LightMatrix/LightMatrix.vue

@@ -15,7 +15,7 @@
             </div>
             <div class="panel-item-gf-right">
               <div class="panel-item-gf-up">{{ panelData.first.text }}</div>
-              <div class="panel-item-gf-down">{{ panelData.first.num }}</div>
+              <div class="panel-item-gf-down">{{ sourceMap[panelData.first.key] || "---" }}</div>
             </div>
           </div>
         </Col>
@@ -29,7 +29,8 @@
                 </span>
               </div>
               <div class="panel-item-li">
-                <span>{{ data.num }}</span>
+                <span v-if="data.calcStr && sourceMap">{{ calcGfStr(data.calcStr) || "---" }}</span>
+                <span v-else>{{ sourceMap[data.key] || "---" }}</span>
                 <span class="svg-icon svg-icon-sm" :class="'svg-icon-' + data.color">
                   <SvgIcon :svgid="data.numIcon"></SvgIcon>
                 </span>
@@ -38,11 +39,11 @@
             <div class="panel-item-right">
               <div class="panel-item-ri">
                 <span>{{ data.text1 }}</span>
-                <span>{{ data.num1 }}</span>
+                <span>{{ sourceMap[data.key1] || "---" }}</span>
               </div>
               <div class="panel-item-ri">
                 <span>{{ data.text2 }}</span>
-                <span>{{ data.num2 }}</span>
+                <span>{{ sourceMap[data.key2] || "---" }}</span>
               </div>
             </div>
           </div>
@@ -50,25 +51,25 @@
       </Row>
     </div>
     <div class="panel-box">
-      <div v-for="(table, k) of tables" :key="k">
+      <div v-for="(pItem, pIndex) in sourceMap.fjmap" :key="pIndex">
         <div class="panel-title">
-          <div class="panel-title-name">
+          <div v-for="(cItem, cIndex) in pItem" :key="cIndex" class="panel-title-name">
             <i class="fa fa-send"></i>
-            <span>某某某风电场</span>
-            <div class="sub-title-item" v-for="(data, index) of table.subTitleDatas" :key="index">
+            <span>{{ sourceMap.fczbmap[pItem[pIndex].wpId].name }}</span>
+            <div class="sub-title-item" v-for="(data, index) in tables[0].subTitleDatas" :key="index">
               <span class="sub-title">{{ data.text }}</span>
-              <span class="sub-count" :class="data.color">{{ data.num }}</span>
+              <span class="sub-count" :class="data.color">{{ sourceMap.fczbmap[pItem[pIndex].wpId][data.key] }}</span>
             </div>
           </div>
         </div>
         <div class="panel-body">
-          <div class="card" v-for="(col, j) of table.datas" :key="j" :class="col.color">
+          <div class="card" v-for="(cItem, cIndex) in pItem" :key="cIndex" :class="cItem.color">
             <div class="card-panel">
               <div class="card-left">
-                <div class="tag">{{ col.tag }}</div>
+                <div class="tag">{{ cItem.wtnum }}</div>
                 <div class="icon">
                   <span class="svg-icon svg-icon-sm" :class="col.color == 'black' ? 'svg-icon-black' : col.color == 'gray' ? 'svg-icon-gray' : 'svg-icon-write'">
-                    <SvgIcon :svgid="col.icon"></SvgIcon>
+                    <SvgIcon :svgid="cItem.icon"></SvgIcon>
                   </span>
                 </div>
               </div>
@@ -77,19 +78,19 @@
                   <i class="svg-icon svg-icon-sm" :class="'svg-icon-' + col.color">
                     <SvgIcon svgid="svg-A"></SvgIcon>
                   </i>
-                  <span>{{ col.num1 }}</span>
+                  <span>{{ cItem.fdl }}</span>
                 </div>
                 <div class="num">
                   <i class="svg-icon svg-icon-sm" :class="'svg-icon-' + col.color">
                     <SvgIcon svgid="svg-W"></SvgIcon>
                   </i>
-                  <span>{{ col.num2 }}</span>
+                  <span>{{ cItem.gl }}</span>
                 </div>
                 <div class="num">
                   <i class="svg-icon svg-icon-sm" :class="'svg-icon-' + col.color">
                     <SvgIcon svgid="svg-V"></SvgIcon>
                   </i>
-                  <span>{{ col.num3 }}</span>
+                  <span>{{ cItem.fs }}</span>
                 </div>
               </div>
             </div>
@@ -107,101 +108,108 @@ import Row from "@com/coms/grid/row.vue";
 import Col from "@com/coms/grid/col.vue";
 import SvgIcon from "@com/coms/icon/svg-icon.vue";
 import util from "@/helper/util.js";
+
+import store from "@store/index.js";
+
 export default {
   // 名称
   name: "LightMatrix",
+
   // 使用组件
   components: {
     Row,
     Col,
     SvgIcon,
   },
+
   // 数据
   data() {
     return {
+      timmer: null, // 计时器
+      sourceMap: {}, // 核心数据
       panelData: {
         first: {
           icon: "svg-photovoltaic",
           text: "接入光伏",
-          num: 256,
+          key: "gfjrnum",
         },
         datas: [
           {
             color: "green",
             name: "待机",
             nameIcon: "svg-standby",
-            num: 50,
+            calcStr: ["gfdjnum", "gfsdtjnum"],
             numIcon: "svg-manual",
             text1: "待风",
-            num1: 30,
+            key1: "gfdjnum",
             text2: "手动停机",
-            num2: 30,
+            key2: "gfsdtjnum",
           },
           {
             color: "blue",
             name: "运行",
             nameIcon: "svg-normal-power",
-            num: 50,
+            calcStr: ["gfzcfdnum", "gfqxjclnum"],
             numIcon: "svg-drop-output",
             text1: "正常发电",
-            num1: 30,
-            text2: "降出力",
-            num2: 30,
+            key1: "gfzcfdnum",
+            text2: "降出力运行",
+            key2: "gfqxjclnum",
           },
           {
-            color: "pink",
+            color: "purple",
             name: "限电",
             nameIcon: "svg-limit-power",
-            num: 50,
+            calcStr: ["gfxdjclnum", "gfxdtjnum"],
             numIcon: "svg-downtime",
-            text1: "降出力",
-            num1: 30,
+            text1: "限电降出力",
+            key1: "gfxdjclnum",
             text2: "停机",
-            num2: 30,
+            key2: "gfxdtjnum",
           },
           {
             color: "red",
             name: "故障",
             nameIcon: "svg-gz-downtime",
-            num: 50,
+            calcStr: ["gfgztjnum", "gfcnsltjnum"],
             numIcon: "svg-field-involved",
             text1: "故障停机",
-            num1: 30,
+            key1: "gfgztjnum",
             text2: "场内受累",
-            num2: 30,
+            key2: "gfcnsltjnum",
           },
           {
             color: "orange",
-            name: "检",
+            name: "检",
             nameIcon: "svg-jx-downtime",
-            num: 50,
+            calcStr: ["gfjcnum", "gfcnsljxnum"],
             numIcon: "svg-field-involved",
             text1: "检修停机",
-            num1: 30,
+            key1: "gfjxtjnum",
             text2: "产内受累",
-            num2: 30,
-          },
-          {
-            color: "gray",
-            name: "离线",
-            nameIcon: "svg-offline",
-            num: 50,
-            numIcon: "svg-unknown",
-            text1: "离线",
-            num1: 30,
-            text2: "未知",
-            num2: 30,
+            key2: "gfcnsljxnum",
           },
           {
             color: "write",
             name: "受累",
+            calcStr: ["gfdwslnum", "gfhjslnum"],
             nameIcon: "svg-intranet-involvement",
-            num: 50,
             numIcon: "svg-environment",
             text1: "电网",
-            num1: 30,
+            key1: "gfdwslnum",
             text2: "环境",
-            num2: 30,
+            key2: "gfhjslnum",
+          },
+          {
+            color: "gray",
+            name: "离线",
+            nameIcon: "svg-offline",
+            key: "gflxnum",
+            numIcon: "svg-unknown",
+            text1: "离线",
+            key1: "gflxnum",
+            text2: "未知",
+            key2: "gfwznum",
           },
         ],
       },
@@ -211,78 +219,78 @@ export default {
           subTitleDatas: [
             {
               text: "接入台数",
-              num: 256,
               color: "write",
+              key: "jrts",
             },
             {
               text: "待机台数",
-              num: 256,
               color: "green",
+              key: "djts",
             },
             {
               text: "并网台数",
-              num: 256,
               color: "blue",
+              key: "yxts",
             },
             {
               text: "限电台数",
-              num: 256,
-              color: "pink",
+              color: "purple",
+              key: "xdts",
             },
             {
               text: "故障台数",
-              num: 256,
               color: "red",
+              key: "gzts",
             },
             {
               text: "检修台数",
-              num: 256,
               color: "orange",
+              key: "whts",
             },
             {
               text: "受累台数",
-              num: 256,
               color: "write",
+              key: "slts",
             },
             {
               text: "离线台数",
-              num: 256,
               color: "gray",
+              key: "lxts",
             },
             {
               text: "风速",
-              num: 256,
               color: "gray",
+              key: "ssfs",
             },
             {
               text: "预测功率",
-              num: 256,
               color: "gray",
+              key: "ycgl",
             },
             {
               text: "保证功率",
-              num: 256,
               color: "gray",
+              key: "bzgl",
             },
             {
               text: "应发功率",
-              num: 256,
               color: "gray",
+              key: "yfgl",
             },
             {
               text: "实际功率",
-              num: 256,
               color: "gray",
+              key: "sjgl",
             },
             {
               text: "AGC指令",
-              num: 256,
               color: "gray",
+              key: "agcygsd",
             },
             {
               text: "出线功率",
-              num: 256,
               color: "gray",
+              key: "agccxyg",
             },
           ],
           datas: [
@@ -299,52 +307,86 @@ export default {
       ],
     };
   },
+
   // 函数
-  methods: {},
-  // 生命周期钩子
-  beforeCreate() {
-    // 创建前
-  },
-  created() {
-    // 创建后
-    let tempData = [];
-    for (let i = 0; i < 45; i++) {
-      tempData.push(util.copy(this.tables[0].datas[0]));
-      if (i == 39) {
-        tempData[i].color = "green";
-      }
-      if (i == 40) {
-        tempData[i].color = "pink";
-      }
-      if (i == 41) {
-        tempData[i].color = "orange";
+  methods: {
+    // 根据风机状态码返回对应 class
+    getColor(fjzt) {
+      switch (fjzt) {
+        case 0:
+          return "green";
+          break;
+        case 1:
+          return "blue";
+          break;
+        case 2:
+          return "red";
+          break;
+        case 3:
+          return "gray";
+          break;
+        case 4:
+          return "orange";
+          break;
+        case 5:
+          return "purple";
+          break;
+        case 6:
+          return "write";
+          break;
       }
-      if (i == 42) {
-        tempData[i].color = "red";
-      }
-      if (i == 43) {
-        tempData[i].color = "black";
-      }
-      if (i == 44) {
-        tempData[i].color = "gray";
-      }
-    }
-    this.tables[0].datas = util.copy(tempData);
-    for (let i = 0; i < 5; i++) {
-      this.tables.push(util.copy(this.tables[0]));
-    }
-  },
-  beforeMount() {
-    // 渲染前
-  },
-  mounted() {
-    // 渲染后
+    },
+
+    calcGfStr(calcStr) {
+      return parseInt(this.sourceMap[calcStr[0]]) + parseInt(this.sourceMap[calcStr[1]]) + "";
+    },
+
+    // 请求服务
+    requestData(showLoading) {
+      let that = this;
+      that.API.requestData({
+        showLoading,
+        method: "POST",
+        subUrl: "matrix/matrixDetialGfPush",
+        success(res) {
+          if (res.data) {
+            let sourceMap = res.data;
+            for (let key in sourceMap) {
+              if (key !== "fczbmap" && key !== "fjmap") {
+                sourceMap[key] += "";
+              } else if (key === "fjmap") {
+                sourceMap[key].forEach((pItem) => {
+                  pItem.forEach((cItem) => {
+                    cItem.color = that.getColor(cItem.fjzt);
+                    cItem.isShow = that;
+                  });
+                });
+              }
+            }
+            that.sourceMap = sourceMap;
+          } else {
+            that.sourceMap = {};
+          }
+        },
+      });
+    },
   },
-  beforeUpdate() {
-    // 数据更新前
+
+  created() {
+    let that = this;
+    that.$nextTick(() => {
+      that.requestData(true);
+      that.timmer = setInterval(() => {
+        that.requestData(false);
+      }, that.$store.state.websocketTimeSec);
+    });
   },
-  updated() {
-    // 数据更新后
+
+  mounted() {},
+
+  unmounted() {
+    clearInterval(this.timmer);
+    this.timmer = null;
   },
 };
 </script>
@@ -367,26 +409,26 @@ export default {
     background-color: fade(@darkgray, 20%);
 
     .dot {
-      width: 0.185vh;
-      height: 0.185vh;
+      width: 2px;
+      height: 2px;
       border-radius: 50%;
       background-color: @write;
       position: absolute;
 
       &.left {
-        left: 0.37vh;
+        left: 4px;
       }
 
       &.right {
-        right: 0.37vh;
+        right: 4px;
       }
 
       &.top {
-        top: 0.37vh;
+        top: 4px;
       }
 
       &.bottom {
-        bottom: 0.37vh;
+        bottom: 4px;
       }
     }
 
@@ -417,7 +459,7 @@ export default {
 
         .panel-item-gf-up {
           height: @panelHeight / 2;
-          border-bottom: 0.093vh solid fade(@darkgray, 40%);
+          border-bottom: 1px solid fade(@gray, 40%);
           line-height: @panelHeight / 2;
           padding-right: 1.111vh;
           font-size: @fontsize;
@@ -468,7 +510,7 @@ export default {
           padding: 0 1.111vh;
 
           &:first-child {
-            border-bottom: 0.093vh solid;
+            border-bottom: 1px solid;
           }
 
           span {

+ 260 - 234
src/views/LightMatrix1/LightMatrix1.vue

@@ -10,12 +10,40 @@
           <div class="item">
             <div class="loop"></div>
             <span class="svg-icon svg-icon-gray svg-icon-md">
-              <SvgIcon :svgid="panel1Data.first.icon"></SvgIcon>
+              <SvgIcon svgid="svg-wind-site"></SvgIcon>
             </span>
           </div>
-          <div class="item" :class="data.color" v-for="(data, index) of panel1Data.datas" :key="index">
-            <div>{{ data.test }}</div>
-            <div>{{ data.num }}</div>
+          <div class="item write" @click="changeShow('jrfj_FDC')">
+            <div>接入风机</div>
+            <div>{{ sourceMap.fcjrnum || "---" }}</div>
+          </div>
+          <div class="item blue" @click="changeShow('yx_FDC', 1)">
+            <div>· 运行</div>
+            <div>{{ sourceMap.fcyxnum || "---" }}</div>
+          </div>
+          <div class="item green" @click="changeShow('dj_FDC', 0)">
+            <div>· 待机</div>
+            <div>{{ sourceMap.fcdjnum || "---" }}</div>
+          </div>
+          <div class="item purple" @click="changeShow('xd_FDC', 5)">
+            <div>· 限电</div>
+            <div>{{ sourceMap.fcxdnum || "---" }}</div>
+          </div>
+          <div class="item red" @click="changeShow('gz_FDC', 2)">
+            <div>· 故障</div>
+            <div>{{ sourceMap.fcgznum || "---" }}</div>
+          </div>
+          <div class="item orange" @click="changeShow('jx_FDC', 4)">
+            <div>· 检修</div>
+            <div>{{ sourceMap.fcwhnum || "---" }}</div>
+          </div>
+          <div class="item write" @click="changeShow('sl_FDC', 6)">
+            <div>· 受累</div>
+            <div>{{ sourceMap.fcslnum || "---" }}</div>
+          </div>
+          <div class="item gray" @click="changeShow('lx_FDC', 3)">
+            <div>· 离线</div>
+            <div>{{ sourceMap.fclxnum || "---" }}</div>
           </div>
         </div>
       </Col>
@@ -28,34 +56,62 @@
           <div class="item">
             <div class="loop"></div>
             <span class="svg-icon svg-icon-gray svg-icon-md">
-              <SvgIcon :svgid="panel2Data.first.icon"></SvgIcon>
+              <SvgIcon svgid="svg-photovoltaic"></SvgIcon>
             </span>
           </div>
-          <div class="item" :class="data.color" v-for="(data, index) of panel2Data.datas" :key="index">
-            <div>{{ data.test }}</div>
-            <div>{{ data.num }}</div>
+          <div class="item write" @click="changeShow('jrfj1_GDC')">
+            <div>接入风机</div>
+            <div>{{ sourceMap.gfjrnum || "---" }}</div>
+          </div>
+          <div class="item blue" @click="changeShow('yx1_GDC', 1)">
+            <div>· 运行</div>
+            <div>{{ sourceMap.gfyxnum || "---" }}</div>
+          </div>
+          <div class="item green" @click="changeShow('dj1_GDC', 0)">
+            <div>· 待机</div>
+            <div>{{ sourceMap.gfdjnum || "---" }}</div>
+          </div>
+          <div class="item purple" @click="changeShow('xd1_GDC', 5)">
+            <div>· 限电</div>
+            <div>{{ sourceMap.gfxdnum || "---" }}</div>
+          </div>
+          <div class="item red" @click="changeShow('gz1_GDC', 2)">
+            <div>· 故障</div>
+            <div>{{ sourceMap.gfgznum || "---" }}</div>
+          </div>
+          <div class="item orange" @click="changeShow('jx1_GDC', 4)">
+            <div>· 检修</div>
+            <div>{{ sourceMap.gfwhnum || "---" }}</div>
+          </div>
+          <div class="item write" @click="changeShow('sl1_GDC', 6)">
+            <div>· 受累</div>
+            <div>{{ sourceMap.gfslnum || "---" }}</div>
+          </div>
+          <div class="item gray" @click="changeShow('lx1_GDC', 3)">
+            <div>· 离线</div>
+            <div>{{ sourceMap.gflxnum || "---" }}</div>
           </div>
         </div>
       </Col>
     </Row>
     <div class="panel-box">
-      <div v-for="(table, k) of tables" :key="k">
+      <div v-for="(pItem, pIndex) in sourceMap.fjmap" :key="pIndex">
         <div class="panel-title">
           <div class="panel-title-name">
             <i class="fa fa-send"></i>
-            <span>某某某风电场</span>
-            <div class="sub-title-item" v-for="(data, index) of table.subTitleDatas" :key="index">
-              <span class="sub-title">{{ data.text }}</span>
-              <span class="sub-count" :class="data.color">{{ data.num }}</span>
+            <span>{{ sourceMap.fczbmap[sourceMap.fjmap[pIndex][0].wpId].name || "------" }}</span>
+            <div class="sub-title-item" v-for="(fcItem, fcIndex) in fcStateArray" :key="fcIndex">
+              <span class="sub-title">{{ fcItem.text }}</span>
+              <span class="sub-count" :class="fcItem.color">{{ sourceMap.fczbmap[sourceMap.fjmap[pIndex][0].wpId][fcItem.key] }}</span>
             </div>
           </div>
         </div>
         <div class="panel-body">
-          <div class="card" v-for="(col, j) of table.datas" :key="j" :class="col.color">
-            {{ col.tag }}
+          <div class="card" v-for="(cItem, cIndex) of pItem" :key="cIndex" v-show="cItem.isShow" :class="cItem.color">
+            {{ cItem.wtnum }}
           </div>
           <!-- 站位用 保证卡片布局最后一行不会有问题 -->
-          <i class="blank" v-for="i in table.datas.length" :key="i"></i>
+          <i class="blank" v-for="i in pItem.length" :key="i"></i>
         </div>
       </div>
     </div>
@@ -67,6 +123,11 @@ import Row from "@/components/coms/grid/row.vue";
 import Col from "@/components/coms/grid/col.vue";
 import SvgIcon from "@com/coms/icon/svg-icon.vue";
 import util from "@/helper/util.js";
+
+import store from "@store/index.js";
+import { isNumber } from "util";
+import { setInterval, clearInterval } from "timers";
+
 export default {
   // 名称
   name: "LightMatrix1",
@@ -76,239 +137,204 @@ export default {
     Col,
     SvgIcon,
   },
+
   // 数据
   data() {
     return {
-      panel1Data: {
-        first: {
-          icon: "svg-wind-site",
+      timmer: null, // 计时器
+      sourceMap: {}, // 核心数据
+      fillCategory: null, // 过滤条件
+      fillFjzt: null, // 过滤条件
+      fcStateArray: [
+        {
+          text: "接入台数",
+          color: "write",
+          key: "jrts",
+        },
+        {
+          text: "待机台数",
+          color: "green",
+          key: "djts",
+        },
+        {
+          text: "并网台数",
+          color: "blue",
+          key: "yxts",
+        },
+        {
+          text: "限电台数",
+          color: "purple",
+          key: "xdts",
+        },
+        {
+          text: "故障台数",
+          color: "red",
+          key: "gzts",
+        },
+        {
+          text: "检修台数",
+          color: "orange",
+          key: "whts",
+        },
+        {
+          text: "受累台数",
+          color: "write",
+          key: "slts",
+        },
+        {
+          text: "离线台数",
+          color: "gray",
+          key: "lxts",
         },
-        datas: [
-          {
-            color: "write",
-            test: "接入风机",
-            num: 256,
-          },
-          {
-            color: "blue",
-            test: "· 运行",
-            num: 256,
-          },
-          {
-            color: "green",
-            test: "· 待机",
-            num: 256,
-          },
-          {
-            color: "pink",
-            test: "· 限电",
-            num: 256,
-          },
-          {
-            color: "red",
-            test: "· 故障",
-            num: 256,
-          },
-          {
-            color: "orange",
-            test: "· 检修",
-            num: 256,
-          },
-          {
-            color: "write",
-            test: "· 受累",
-            num: 256,
-          },
-          {
-            color: "gray",
-            test: "· 离线",
-            num: 256,
-          },
-        ],
-      },
-      panel2Data: {
-        first: {
-          icon: "svg-photovoltaic",
+        {
+          text: "风速",
+          color: "gray",
+          key: "ssfs",
         },
-        datas: [
-          {
-            color: "write",
-            test: "接入风机",
-            num: 256,
-          },
-          {
-            color: "blue",
-            test: "· 运行",
-            num: 256,
-          },
-          {
-            color: "green",
-            test: "· 待机",
-            num: 256,
-          },
-          {
-            color: "pink",
-            test: "· 限电",
-            num: 256,
-          },
-          {
-            color: "red",
-            test: "· 故障",
-            num: 256,
-          },
-          {
-            color: "orange",
-            test: "· 检修",
-            num: 256,
-          },
-          {
-            color: "write",
-            test: "· 受累",
-            num: 256,
-          },
-          {
-            color: "gray",
-            test: "· 离线",
-            num: 256,
-          },
-        ],
-      },
-      tables: [
         {
-          col: 42,
-          subTitleDatas: [
-            {
-              text: "接入台数",
-              num: 256,
-              color: "write",
-            },
-            {
-              text: "待机台数",
-              num: 256,
-              color: "green",
-            },
-            {
-              text: "并网台数",
-              num: 256,
-              color: "blue",
-            },
-            {
-              text: "限电台数",
-              num: 256,
-              color: "pink",
-            },
-            {
-              text: "故障台数",
-              num: 256,
-              color: "red",
-            },
-            {
-              text: "检修台数",
-              num: 256,
-              color: "orange",
-            },
-            {
-              text: "受累台数",
-              num: 256,
-              color: "write",
-            },
-            {
-              text: "离线台数",
-              num: 256,
-              color: "gray",
-            },
-            {
-              text: "风速",
-              num: 256,
-              color: "gray",
-            },
-            {
-              text: "预测功率",
-              num: 256,
-              color: "gray",
-            },
-            {
-              text: "保证功率",
-              num: 256,
-              color: "gray",
-            },
-            {
-              text: "应发功率",
-              num: 256,
-              color: "gray",
-            },
-            {
-              text: "实际功率",
-              num: 256,
-              color: "gray",
-            },
-            {
-              text: "AGC指令",
-              num: 256,
-              color: "gray",
-            },
-            {
-              text: "出线功率",
-              num: 256,
-              color: "gray",
-            },
-          ],
-          datas: [
-            {
-              tag: "A01",
-              color: "blue",
-            },
-          ],
+          text: "预测功率",
+          color: "gray",
+          key: "ycgl",
+        },
+        {
+          text: "保证功率",
+          color: "gray",
+          key: "bzgl",
+        },
+        {
+          text: "应发功率",
+          color: "gray",
+          key: "yfgl",
+        },
+        {
+          text: "实际功率",
+          color: "gray",
+          key: "sjgl",
+        },
+        {
+          text: "AGC指令",
+          color: "gray",
+          key: "agcygsd",
+        },
+        {
+          text: "出线功率",
+          color: "gray",
+          key: "agccxyg",
         },
       ],
     };
   },
+
   // 函数
-  methods: {},
-  // 生命周期钩子
-  beforeCreate() {
-    // 创建前
-  },
-  created() {
-    // 创建后
-    let tempData = [];
-    for (let i = 0; i < 108; i++) {
-      tempData.push(util.copy(this.tables[0].datas[0]));
-      if (i % 13 == 0) {
-        tempData[i].color = "green";
-      }
-      if (i % 17 == 0) {
-        tempData[i].color = "pink";
-      }
-      if (i % 23 == 0) {
-        tempData[i].color = "orange";
-      }
-      if (i % 29 == 0) {
-        tempData[i].color = "red";
+  methods: {
+    // 根据风机状态码返回对应 class
+    getColor(fjzt) {
+      switch (fjzt) {
+        case 0:
+          return "green";
+          break;
+        case 1:
+          return "blue";
+          break;
+        case 2:
+          return "red";
+          break;
+        case 3:
+          return "gray";
+          break;
+        case 4:
+          return "orange";
+          break;
+        case 5:
+          return "purple";
+          break;
+        case 6:
+          return "write";
+          break;
       }
-      if (i % 31 == 0) {
-        tempData[i].color = "write";
-      }
-      if (i % 37 == 0) {
-        tempData[i].color = "gray";
+    },
+
+    // 切换显示种类
+    changeShow(category, fjzt, skipFill) {
+      if (!skipFill) {
+        if (this.fillCategory === category) {
+          this.fillCategory = null;
+          this.fillFjzt = null;
+        } else {
+          this.fillCategory = category;
+          this.fillFjzt = fjzt;
+        }
       }
-    }
-    this.tables[0].datas = util.copy(tempData);
-    for (let i = 0; i < 5; i++) {
-      this.tables.push(util.copy(this.tables[0]));
-    }
-  },
-  beforeMount() {
-    // 渲染前
-  },
-  mounted() {
-    // 渲染后
+
+      let fjmap = this.BASE.deepCopy(this.sourceMap.fjmap);
+
+      fjmap.forEach((pEle) => {
+        pEle.forEach((cEle) => {
+          cEle.isShow = true;
+          if (!this.fillCategory) {
+            cEle.isShow = true;
+          } else if (cEle.wpId.indexOf(category.split("_")[1]) !== -1) {
+            if (isNumber(fjzt)) {
+              cEle.fjzt === fjzt ? (cEle.isShow = true) : (cEle.isShow = false);
+            } else {
+              cEle.isShow = true;
+            }
+          } else {
+            cEle.isShow = true;
+          }
+        });
+      });
+      this.sourceMap.fjmap = fjmap;
+    },
+
+    // 请求服务
+    requestData(showLoading) {
+      let that = this;
+      that.API.requestData({
+        showLoading,
+        method: "POST",
+        subUrl: "matrix/matrixPush",
+        success(res) {
+          if (res) {
+            let sourceMap = res.data;
+            let fjmap = [];
+            for (let key in sourceMap) {
+              if (key !== "fczbmap" && key !== "fjmap") {
+                sourceMap[key] += "";
+              } else if (key === "fjmap") {
+                sourceMap[key].forEach((pItem) => {
+                  pItem.forEach((cItem) => {
+                    cItem.color = that.getColor(cItem.fjzt);
+                    cItem.isShow = true;
+                  });
+                });
+              }
+            }
+            that.sourceMap = sourceMap;
+            if (that.fillCategory) {
+              that.changeShow(that.fillCategory, that.fillFjzt, true);
+            }
+          } else {
+            that.sourceMap = {};
+          }
+        },
+      });
+    },
   },
-  beforeUpdate() {
-    // 数据更新前
+
+  created() {
+    let that = this;
+    that.$nextTick(() => {
+      that.requestData(true);
+      that.timmer = setInterval(() => {
+        that.requestData(false);
+      }, that.$store.state.websocketTimeSec);
+    });
   },
-  updated() {
-    // 数据更新后
+
+  unmounted() {
+    clearInterval(this.timmer);
+    this.timmer = null;
   },
 };
 </script>

+ 119 - 82
src/views/LightMatrix2/LightMatrix2.vue

@@ -12,7 +12,7 @@
           </div>
           <div class="item" :class="data.color" v-for="(data, index) of panel1Data.datas" :key="index">
             <div>{{ data.test }}</div>
-            <div>{{ data.num }}</div>
+            <div>{{ sourceMap[data.key] }}</div>
           </div>
         </div>
       </Col>
@@ -24,34 +24,34 @@
           <div class="dot right bottom"></div>
           <div class="item2" v-for="(data, index) of panel2Data.datas" :key="index">
             <div class="name">{{ data.test }}</div>
-            <div class="num2">{{ data.num2 }}</div>
-            <div class="num1">×{{ data.num1 }}</div>
+            <div class="num2">{{ sourceMap[data.key] }}</div>
+            <!-- <div class="num1">×{{ data.num1 }}</div> -->
             <div class="num3">{{ data.num3 }}</div>
           </div>
         </div>
       </Col>
     </Row>
     <div class="panel-box">
-      <div v-for="(table, k) of tables" :key="k">
+      <div v-for="(pItem, pIndex) of sourceMap.fjmap" :key="pIndex">
         <div class="panel-title">
           <div class="panel-title-name">
             <i class="fa fa-send"></i>
-            <span>某某某风电场</span>
-            <div class="sub-title-item" v-for="(data, index) of table.subTitleDatas" :key="index">
+            <span>{{ sourceMap.fczbmap[pItem[pIndex].wpId].name }}</span>
+            <div class="sub-title-item" v-for="(data, index) in tables[0].subTitleDatas" :key="index">
               <span class="sub-title">{{ data.text }}</span>
-              <span class="sub-count" :class="data.color">{{ data.num }}</span>
+              <span class="sub-count" :class="data.color">{{ sourceMap.fczbmap[pItem[pIndex].wpId][data.key] }}</span>
             </div>
           </div>
         </div>
         <div class="panel-body">
-          <div class="card" v-for="(col, j) of table.datas" :key="j" :class="col.color">
+          <div class="card" v-for="(cItem, cIndex) in pItem" :key="cIndex" :class="cItem.color">
             <div class="card-panel">
               <div class="card-left">
-                <div class="tag">{{ col.tag }}</div>
+                <div class="tag">{{ cItem.wtnum }}</div>
               </div>
               <div class="card-right">
-                <div class="num">{{ col.num1 }}</div>
-                <div class="num">{{ col.num2 }}</div>
+                <div class="num">{{ cItem.gl }}</div>
+                <div class="num">{{ cItem.fs }}</div>
               </div>
             </div>
             <div class="card-percent">
@@ -60,7 +60,7 @@
               <div class="split-item"></div>
               <div class="split-item"></div>
               <div class="split-item"></div>
-              <div class="percent" :style="'width: ' + col.percent + '%'"></div>
+              <div class="percent" :style="'width: ' + cItem.lyl + '%'"></div>
             </div>
           </div>
           <!-- 站位用 保证卡片布局最后一行不会有问题 -->
@@ -75,6 +75,9 @@
 import Row from "@/components/coms/grid/row.vue";
 import Col from "@/components/coms/grid/col.vue";
 import util from "@/helper/util.js";
+
+import store from "@store/index.js";
+
 export default {
   // 名称
   name: "LightMatrix2",
@@ -86,6 +89,8 @@ export default {
   // 数据
   data() {
     return {
+      timmer: null, // 计时器
+      sourceMap: {}, // 核心数据
       panel1Data: {
         first: {
           icon: "fa fa-user",
@@ -94,42 +99,42 @@ export default {
           {
             color: "write",
             test: "接入风机",
-            num: 256,
+            key: "fcjrnum",
           },
           {
             color: "blue",
             test: "· 运行",
-            num: 256,
+            key: "fcyxnum",
           },
           {
             color: "green",
             test: "· 待机",
-            num: 256,
+            key: "fcdjnum",
           },
           {
             color: "pink",
             test: "· 限电",
-            num: 256,
+            key: "fcxdnum",
           },
           {
             color: "red",
             test: "· 故障",
-            num: 256,
+            key: "fcgznum",
           },
           {
             color: "orange",
             test: "· 检修",
-            num: 256,
+            key: "fcwhnum",
           },
           {
             color: "write",
             test: "· 受累",
-            num: 256,
+            key: "fcslnum",
           },
           {
             color: "gray",
             test: "· 离线",
-            num: 256,
+            key: "fclxnum",
           },
         ],
       },
@@ -138,31 +143,31 @@ export default {
           {
             test: "欠发电量",
             num1: 5,
-            num2: 7.34,
+            key: "r0qf",
             num3: "0%~5%",
           },
           {
             test: "欠发电量",
             num1: 4,
-            num2: 7.34,
+            key: "r1qf",
             num3: "5%~10%",
           },
           {
             test: "欠发电量",
             num1: 3,
-            num2: 7.34,
+            key: "r2qf",
             num3: "10%~20%",
           },
           {
             test: "欠发电量",
             num1: 2,
-            num2: 7.34,
+            key: "r3qf",
             num3: "20%~40%",
           },
           {
             test: "欠发电量",
             num1: 1,
-            num2: 7.34,
+            key: "r4qf",
             num3: ">40%",
           },
         ],
@@ -173,78 +178,78 @@ export default {
           subTitleDatas: [
             {
               text: "接入台数",
-              num: 256,
               color: "write",
+              key: "jrts",
             },
             {
               text: "待机台数",
-              num: 256,
               color: "green",
+              key: "djts",
             },
             {
               text: "并网台数",
-              num: 256,
               color: "blue",
+              key: "yxts",
             },
             {
               text: "限电台数",
-              num: 256,
               color: "pink",
+              key: "xdts",
             },
             {
               text: "故障台数",
-              num: 256,
               color: "red",
+              key: "gzts",
             },
             {
               text: "检修台数",
-              num: 256,
               color: "orange",
+              key: "whts",
             },
             {
               text: "受累台数",
-              num: 256,
               color: "write",
+              key: "slts",
             },
             {
               text: "离线台数",
-              num: 256,
               color: "gray",
+              key: "lxts",
             },
             {
               text: "风速",
-              num: 256,
               color: "gray",
+              key: "ssfs",
             },
             {
               text: "预测功率",
-              num: 256,
               color: "gray",
+              key: "ycgl",
             },
             {
               text: "保证功率",
-              num: 256,
               color: "gray",
+              key: "bzgl",
             },
             {
               text: "应发功率",
-              num: 256,
               color: "gray",
+              key: "yfgl",
             },
             {
               text: "实际功率",
-              num: 256,
               color: "gray",
+              key: "sjgl",
             },
             {
               text: "AGC指令",
-              num: 256,
               color: "gray",
+              key: "agcygsd",
             },
             {
               text: "出线功率",
-              num: 256,
               color: "gray",
+              key: "agccxyg",
             },
           ],
           datas: [
@@ -261,51 +266,83 @@ export default {
     };
   },
   // 函数
-  methods: {},
-  // 生命周期钩子
-  beforeCreate() {
-    // 创建前
-  },
-  created() {
-    // 创建后
-    let tempData = [];
-    for (let i = 0; i < 45; i++) {
-      tempData.push(util.copy(this.tables[0].datas[0]));
-      if (i == 39) {
-        tempData[i].color = "green";
-      }
-      if (i == 40) {
-        tempData[i].color = "pink";
-      }
-      if (i == 41) {
-        tempData[i].color = "orange";
+  methods: {
+    getColor(fjzt) {
+      switch (fjzt) {
+        case 0:
+          return "green";
+          break;
+        case 1:
+          return "blue";
+          break;
+        case 2:
+          return "red";
+          break;
+        case 3:
+          return "gray";
+          break;
+        case 4:
+          return "orange";
+          break;
+        case 5:
+          return "purple";
+          break;
+        case 6:
+          return "write";
+          break;
       }
-      if (i == 42) {
-        tempData[i].color = "red";
-      }
-      if (i == 43) {
-        tempData[i].color = "write";
-      }
-      if (i == 44) {
-        tempData[i].color = "gray";
-      }
-    }
-    this.tables[0].datas = util.copy(tempData);
-    for (let i = 0; i < 5; i++) {
-      this.tables.push(util.copy(this.tables[0]));
-    }
-  },
-  beforeMount() {
-    // 渲染前
-  },
-  mounted() {
-    // 渲染后
+    },
+
+    calcGfStr(calcStr) {
+      return parseInt(this.sourceMap[calcStr[0]]) + parseInt(this.sourceMap[calcStr[1]]) + "";
+    },
+
+    // 请求服务
+    requestData(showLoading) {
+      let that = this;
+      that.API.requestData({
+        showLoading,
+        method: "POST",
+        subUrl: "matrix/matrixQfPush",
+        success(res) {
+          if (res.data) {
+            let sourceMap = res.data;
+            for (let key in sourceMap) {
+              if (key !== "fczbmap" && key !== "fjmap") {
+                sourceMap[key] += "";
+              } else if (key === "fjmap") {
+                sourceMap[key].forEach((pItem) => {
+                  pItem.forEach((cItem) => {
+                    cItem.color = that.getColor(cItem.fjzt);
+                    cItem.isShow = true;
+                  });
+                });
+              }
+            }
+            that.sourceMap = sourceMap;
+          } else {
+            that.sourceMap = {};
+          }
+        },
+      });
+    },
   },
-  beforeUpdate() {
-    // 数据更新前
+
+  created() {
+    let that = this;
+    that.$nextTick(() => {
+      that.requestData(true);
+      that.timmer = setInterval(() => {
+        that.requestData(false);
+      }, that.$store.state.websocketTimeSec);
+    });
   },
-  updated() {
-    // 数据更新后
+
+  mounted() {},
+
+  unmounted() {
+    clearInterval(this.timmer);
+    this.timmer = null;
   },
 };
 </script>

+ 151 - 110
src/views/LightMatrix3/LightMatrix3.vue

@@ -15,7 +15,7 @@
             </div>
             <div class="panel-item-gf-right">
               <div class="panel-item-gf-up">{{ panelData.first.text }}</div>
-              <div class="panel-item-gf-down">{{ panelData.first.num }}</div>
+              <div class="panel-item-gf-down">{{ sourceMap[panelData.first.key] || "---" }}</div>
             </div>
           </div>
         </Col>
@@ -29,7 +29,8 @@
                 </span>
               </div>
               <div class="panel-item-li">
-                <span>{{ data.num }}</span>
+                <span v-if="data.calcStr && sourceMap">{{ calcGfStr(data.calcStr) || "---" }}</span>
+                <span v-else>{{ sourceMap[data.key] || "---" }}</span>
                 <span class="svg-icon svg-icon-sm" :class="'svg-icon-' + data.color">
                   <SvgIcon :svgid="data.numIcon"></SvgIcon>
                 </span>
@@ -38,11 +39,11 @@
             <div class="panel-item-right">
               <div class="panel-item-ri">
                 <span>{{ data.text1 }}</span>
-                <span>{{ data.num1 }}</span>
+                <span>{{ sourceMap[data.key1] || "---" }}</span>
               </div>
               <div class="panel-item-ri">
                 <span>{{ data.text2 }}</span>
-                <span>{{ data.num2 }}</span>
+                <span>{{ sourceMap[data.key2] || "---" }}</span>
               </div>
             </div>
           </div>
@@ -50,44 +51,44 @@
       </Row>
     </div>
     <div class="panel-box">
-      <div v-for="(table, k) of tables" :key="k">
+      <div v-for="(pItem, pIndex) in sourceMap.fjmap" :key="pIndex">
         <div class="panel-title">
           <div class="panel-title-name">
             <i class="fa fa-send"></i>
-            <span>某某某风电场</span>
-            <div class="sub-title-item" v-for="(data, index) of table.subTitleDatas" :key="index">
+            <span>{{ sourceMap.fczbmap[pItem[pIndex].wpId].name }}</span>
+            <div class="sub-title-item" v-for="(data, index) of tables[0].subTitleDatas" :key="index">
               <span class="sub-title">{{ data.text }}</span>
-              <span class="sub-count" :class="data.color">{{ data.num }}</span>
+              <span class="sub-count" :class="data.color">{{ sourceMap.fczbmap[pItem[pIndex].wpId][data.key] }}</span>
             </div>
           </div>
         </div>
         <div class="panel-body">
-          <div class="card" v-for="(col, j) of table.datas" :key="j" :class="col.color">
-            <span class="center-icon svg-icon svg-icon-md" :class="col.color == 'black' ? 'svg-icon-black' : 'svg-icon-write'">
-              <SvgIcon :svgid="mapping[col.color]"></SvgIcon>
+          <div class="card" v-for="(cItem, cIndex) in pItem" :key="cIndex" :class="cItem.color">
+            <span class="center-icon svg-icon svg-icon-md" :class="cItem.color == 'black' ? 'svg-icon-black' : 'svg-icon-write'">
+              <SvgIcon :svgid="mapping[cItem.color]"></SvgIcon>
             </span>
             <div class="card-panel">
               <div class="card-left">
-                <div class="tag">{{ col.tag }}</div>
+                <div class="tag">{{ cItem.wtnum }}</div>
                 <div class="num">
-                  <i class="svg-icon svg-icon-sm" :class="'svg-icon-' + col.color">
+                  <i class="svg-icon svg-icon-sm" :class="'svg-icon-' + cItem.color">
                     <SvgIcon svgid="svg-W"></SvgIcon>
                   </i>
-                  <div>{{ col.num1 }}</div>
+                  <div>{{ cItem.fdl }}</div>
                 </div>
               </div>
               <div class="card-right">
                 <div class="num">
-                  <i class="svg-icon svg-icon-sm" :class="'svg-icon-' + col.color">
+                  <i class="svg-icon svg-icon-sm" :class="'svg-icon-' + cItem.color">
                     <SvgIcon svgid="svg-R"></SvgIcon>
                   </i>
-                  <div>{{ col.num2 }}</div>
+                  <div>{{ cItem.gl }}</div>
                 </div>
                 <div class="num">
-                  <i class="svg-icon svg-icon-sm" :class="'svg-icon-' + col.color">
+                  <i class="svg-icon svg-icon-sm" :class="'svg-icon-' + cItem.color">
                     <SvgIcon svgid="svg-P"></SvgIcon>
                   </i>
-                  <div>{{ col.num3 }}</div>
+                  <div>{{ cItem.fs }}</div>
                 </div>
               </div>
             </div>
@@ -105,6 +106,9 @@ import Row from "@/components/coms/grid/row.vue";
 import Col from "@/components/coms/grid/col.vue";
 import SvgIcon from "@com/coms/icon/svg-icon.vue";
 import util from "@/helper/util.js";
+
+import store from "@store/index.js";
+
 export default {
   // 名称
   name: "LightMatrix3",
@@ -114,9 +118,12 @@ export default {
     Col,
     SvgIcon,
   },
+
   // 数据
   data() {
     return {
+      timmer: null, // 遮罩开关
+      sourceMap: {}, // 核心数据
       mapping: {
         green: "svg-standby",
         blue: "svg-normal-power",
@@ -128,87 +135,87 @@ export default {
       },
       panelData: {
         first: {
-          icon: "svg-wind-site",
-          text: "接入电机",
-          num: 256,
+          icon: "svg-photovoltaic",
+          text: "接入风场",
+          key: "fcjrnum",
         },
         datas: [
           {
             color: "green",
             name: "待机",
             nameIcon: "svg-standby",
-            num: 50,
+            calcStr: ["fcdjnum", "fcsdtjnum"],
             numIcon: "svg-manual",
             text1: "待风",
-            num1: 30,
+            key1: "fcdjnum",
             text2: "手动停机",
-            num2: 30,
+            key2: "fcsdtjnum",
           },
           {
             color: "blue",
             name: "运行",
             nameIcon: "svg-normal-power",
-            num: 50,
+            calcStr: ["fczcfdnum", "fcqxjclnum"],
             numIcon: "svg-drop-output",
             text1: "正常发电",
-            num1: 30,
-            text2: "降出力",
-            num2: 30,
+            key1: "fczcfdnum",
+            text2: "降出力运行",
+            key2: "fcqxjclnum",
           },
           {
             color: "pink",
             name: "限电",
             nameIcon: "svg-limit-power",
-            num: 50,
+            calcStr: ["fcxdjclnum", "fcxdtjnum"],
             numIcon: "svg-downtime",
-            text1: "降出力",
-            num1: 30,
+            text1: "限电降出力",
+            key1: "fcxdjclnum",
             text2: "停机",
-            num2: 30,
+            key2: "fcxdtjnum",
           },
           {
             color: "red",
             name: "故障",
             nameIcon: "svg-gz-downtime",
-            num: 50,
+            calcStr: ["fcgztjnum", "fccnsltjnum"],
             numIcon: "svg-field-involved",
             text1: "故障停机",
-            num1: 30,
+            key1: "fcgztjnum",
             text2: "场内受累",
-            num2: 30,
+            key2: "fccnsltjnum",
           },
           {
             color: "orange",
-            name: "检",
+            name: "检",
             nameIcon: "svg-jx-downtime",
-            num: 50,
+            calcStr: ["fcjcnum", "fccnsljxnum"],
             numIcon: "svg-field-involved",
             text1: "检修停机",
-            num1: 30,
+            key1: "fcjxtjnum",
             text2: "产内受累",
-            num2: 30,
-          },
-          {
-            color: "gray",
-            name: "离线",
-            nameIcon: "svg-offline",
-            num: 50,
-            numIcon: "svg-unknown",
-            text1: "离线",
-            num1: 30,
-            text2: "未知",
-            num2: 30,
+            key2: "fccnsljxnum",
           },
           {
             color: "write",
             name: "受累",
+            calcStr: ["fcdwslnum", "fchjslnum"],
             nameIcon: "svg-intranet-involvement",
-            num: 50,
             numIcon: "svg-environment",
             text1: "电网",
-            num1: 30,
+            key1: "fcdwslnum",
             text2: "环境",
-            num2: 30,
+            key2: "fchjslnum",
+          },
+          {
+            color: "gray",
+            name: "离线",
+            nameIcon: "svg-offline",
+            key: "fclxnum",
+            numIcon: "svg-unknown",
+            text1: "离线",
+            key1: "fclxnum",
+            text2: "未知",
+            key2: "fcwznum",
           },
         ],
       },
@@ -218,78 +225,78 @@ export default {
           subTitleDatas: [
             {
               text: "接入台数",
-              num: 256,
               color: "write",
+              key: "jrts",
             },
             {
               text: "待机台数",
-              num: 256,
               color: "green",
+              key: "djts",
             },
             {
               text: "并网台数",
-              num: 256,
               color: "blue",
+              key: "yxts",
             },
             {
               text: "限电台数",
-              num: 256,
               color: "pink",
+              key: "xdts",
             },
             {
               text: "故障台数",
-              num: 256,
               color: "red",
+              key: "gzts",
             },
             {
               text: "检修台数",
-              num: 256,
               color: "orange",
+              key: "whts",
             },
             {
               text: "受累台数",
-              num: 256,
               color: "write",
+              key: "slts",
             },
             {
               text: "离线台数",
-              num: 256,
               color: "gray",
+              key: "lxts",
             },
             {
               text: "风速",
-              num: 256,
               color: "gray",
+              key: "ssfs",
             },
             {
               text: "预测功率",
-              num: 256,
               color: "gray",
+              key: "ycgl",
             },
             {
               text: "保证功率",
-              num: 256,
               color: "gray",
+              key: "bzgl",
             },
             {
               text: "应发功率",
-              num: 256,
               color: "gray",
+              key: "yfgl",
             },
             {
               text: "实际功率",
-              num: 256,
               color: "gray",
+              key: "sjgl",
             },
             {
               text: "AGC指令",
-              num: 256,
               color: "gray",
+              key: "agcygsd",
             },
             {
               text: "出线功率",
-              num: 256,
               color: "gray",
+              key: "agccxyg",
             },
           ],
           datas: [
@@ -305,52 +312,86 @@ export default {
       ],
     };
   },
+
   // 函数
-  methods: {},
-  // 生命周期钩子
-  beforeCreate() {
-    // 创建前
-  },
-  created() {
-    // 创建后
-    let tempData = [];
-    for (let i = 0; i < 45; i++) {
-      tempData.push(util.copy(this.tables[0].datas[0]));
-      if (i == 39) {
-        tempData[i].color = "green";
-      }
-      if (i == 40) {
-        tempData[i].color = "pink";
-      }
-      if (i == 41) {
-        tempData[i].color = "orange";
-      }
-      if (i == 42) {
-        tempData[i].color = "red";
+  methods: {
+    // 根据风机状态码返回对应 class
+    getColor(fjzt) {
+      switch (fjzt) {
+        case 0:
+          return "green";
+          break;
+        case 1:
+          return "blue";
+          break;
+        case 2:
+          return "red";
+          break;
+        case 3:
+          return "gray";
+          break;
+        case 4:
+          return "orange";
+          break;
+        case 5:
+          return "purple";
+          break;
+        case 6:
+          return "black";
+          break;
       }
-      if (i == 43) {
-        tempData[i].color = "black";
-      }
-      if (i == 44) {
-        tempData[i].color = "gray";
-      }
-    }
-    this.tables[0].datas = util.copy(tempData);
-    for (let i = 0; i < 5; i++) {
-      this.tables.push(util.copy(this.tables[0]));
-    }
-  },
-  beforeMount() {
-    // 渲染前
-  },
-  mounted() {
-    // 渲染后
+    },
+
+    calcGfStr(calcStr) {
+      return parseInt(this.sourceMap[calcStr[0]]) + parseInt(this.sourceMap[calcStr[1]]) + "";
+    },
+
+    // 请求服务
+    requestData(showLoading) {
+      let that = this;
+      that.API.requestData({
+        showLoading,
+        method: "POST",
+        subUrl: "matrix/matrixDetialPush",
+        success(res) {
+          if (res.data) {
+            let sourceMap = res.data;
+            for (let key in sourceMap) {
+              if (key !== "fczbmap" && key !== "fjmap") {
+                sourceMap[key] += "";
+              } else if (key === "fjmap") {
+                sourceMap[key].forEach((pItem) => {
+                  pItem.forEach((cItem) => {
+                    cItem.color = that.getColor(cItem.fjzt);
+                    cItem.isShow = true;
+                  });
+                });
+              }
+            }
+            that.sourceMap = sourceMap;
+          } else {
+            that.sourceMap = {};
+          }
+        },
+      });
+    },
   },
-  beforeUpdate() {
-    // 数据更新前
+
+  created() {
+    let that = this;
+    that.$nextTick(() => {
+      that.requestData(true);
+      that.timmer = setInterval(() => {
+        that.requestData(false);
+      }, that.$store.state.websocketTimeSec);
+    });
   },
-  updated() {
-    // 数据更新后
+
+  mounted() {},
+
+  unmounted() {
+    clearInterval(this.timmer);
+    this.timmer = null;
   },
 };
 </script>

+ 138 - 483
src/views/Status/Status.vue

@@ -11,8 +11,12 @@
 
 <script>
 import StatusPanel from "./components/status-panel.vue";
-import ComTable from "@com/coms/table/table-span.vue";
+import ComTable from '@com/coms/table/table.vue';
 import util from "@/helper/util.js";
+
+import { datainit, webtest } from "@tools/websocket.js";
+import store from "@store/index.js";
+
 export default {
   // 名称
   name: "Status",
@@ -22,88 +26,28 @@ export default {
     ComTable,
   },
   // 数据
-  data() {
+  data () {
     return {
-      datas: [
-        {
-          title: "某某某风电场",
-          weather: {
-            type: "cloudy",
-            temperature: 11,
-          },
-          breakOff: false,
-          category: {
-            score: 66,
-            datas: [
-              { text: "运行", num: 30, color: "green" },
-              { text: "待机", num: 27, color: "purple" },
-              { text: "限电", num: 30, color: "yellow" },
-              { text: "检修", num: 30, color: "orange" },
-              { text: "故障", num: 13, color: "red" },
-              { text: "受累", num: 30, color: "blue" },
-              { text: "离线", num: 30, color: "gray" },
-            ],
-          },
-          items: [
-            {
-              f1: "AGC宋六:",
-              f2: "设定",
-              f3: "66",
-              f4: "出线",
-              f5: "11",
-              is_light: true,
-            },
-            {
-              f1: "升压站:",
-              f2: "出线Uab/La",
-              f3: "23/3 23/3",
-              f4: "电压",
-              f5: "103 103",
-              is_light: false,
-            },
-            {
-              f1: "风功:",
-              f2: "未来15分钟",
-              f3: "103",
-              f4: "",
-              f5: "",
-              is_light: false,
-            },
-            {
-              f1: "测风塔:",
-              f2: "风速",
-              f3: "103KM",
-              f4: "风向",
-              f5: "103 62",
-              is_light: false,
-            },
-            {
-              f1: "电能量表:",
-              f2: "",
-              f3: "103 62",
-              f4: "",
-              f5: "",
-              is_light: false,
-            },
-          ],
-        },
-      ],
+      loadingFlg: false, // 遮罩开关
+      websocketServe: null, // websocket 服务实例
+      sourceMap: {}, // 核心数据
+      datas: [],
       tableData: {
         column: [
           {
             name: "场站名称",
-            field: "name",
-            unit: "",
-            is_num: false,
-            is_light: false,
-          },
-          {
-            name: "调度名称",
-            field: "ddname",
+            field: "wpName",
             unit: "",
             is_num: false,
             is_light: false,
           },
+          // {
+          //   name: "调度名称",
+          //   field: "ddname",
+          //   unit: "",
+          //   is_num: false,
+          //   is_light: false,
+          // },
           {
             name: "装机容量",
             field: "zjrl",
@@ -144,7 +88,7 @@ export default {
             field: "gl",
             unit: "MW",
             is_num: true,
-            is_light: true,
+            is_light: false,
           },
           {
             name: "出线功率",
@@ -176,7 +120,7 @@ export default {
           },
           {
             name: "AGC指令",
-            field: "agc",
+            field: "aGCzl",
             unit: "MW",
             is_num: true,
             is_light: false,
@@ -190,457 +134,168 @@ export default {
           },
           {
             name: "SCADA发电量",
-            field: "scada",
+            field: "scadafdl",
             unit: "万kwh",
             is_num: true,
             is_light: false,
           },
           {
             name: "维修损失电量",
-            field: "wxssdl",
+            field: "whss",
             unit: "万kwh",
             is_num: true,
             is_light: false,
           },
           {
             name: "故障损失电量",
-            field: "gzssdl",
+            field: "gzss",
             unit: "万kwh",
             is_num: true,
             is_light: false,
           },
           {
             name: "受理损失电量",
-            field: "slssdl",
+            field: "slss",
             unit: "万kwh",
             is_num: true,
             is_light: false,
           },
           {
             name: "限电损失电量",
-            field: "xdssdl",
+            field: "xdss",
             unit: "万kwh",
             is_num: true,
             is_light: false,
           },
           {
             name: "性能损失电量",
-            field: "xnssdl",
+            field: "xnss",
             unit: "万kwh",
             is_num: true,
             is_light: false,
           },
         ],
-        data: [
-          {
-            name: "风电场",
-            ddname: "牛二",
-            zjrl: 99,
-            fdl: 99,
-            swdl: 99,
-            lyxs: 99,
-            fs: 99,
-            gl: 99,
-            cxgl: 99,
-            llgl: 99,
-            bzgl: 99,
-            ycgl: 99,
-            agc: 99,
-            llfdl: 99,
-            scada: 99,
-            wxssdl: 99,
-            gzssdl: 99,
-            slssdl: 99,
-            xdssdl: 99,
-            xnssdl: 99,
-            row_span: [],
-            col_span: [],
-            is_light: false,
-          },
-          {
-            name: "风电场",
-            ddname: "牛二",
-            zjrl: 99,
-            fdl: 99,
-            swdl: 99,
-            lyxs: 99,
-            fs: 99,
-            gl: 99,
-            cxgl: 99,
-            llgl: 99,
-            bzgl: 99,
-            ycgl: 99,
-            agc: 99,
-            llfdl: 99,
-            scada: 99,
-            wxssdl: 99,
-            gzssdl: 99,
-            slssdl: 99,
-            xdssdl: 99,
-            xnssdl: 99,
-            row_span: [],
-            col_span: [],
-            is_light: false,
-          },
-          {
-            name: "风电场",
-            ddname: "牛二",
-            zjrl: 99,
-            fdl: 99,
-            swdl: 99,
-            lyxs: 99,
-            fs: 99,
-            gl: 99,
-            cxgl: 99,
-            llgl: 99,
-            bzgl: 99,
-            ycgl: 99,
-            agc: 99,
-            llfdl: 99,
-            scada: 99,
-            wxssdl: 99,
-            gzssdl: 99,
-            slssdl: 99,
-            xdssdl: 99,
-            xnssdl: 99,
-            row_span: [["name", 2]],
-            col_span: [],
-            is_light: false,
-          },
-          {
-            name: "",
-            ddname: "牛二",
-            zjrl: 99,
-            fdl: 99,
-            swdl: 99,
-            lyxs: 99,
-            fs: 99,
-            gl: 99,
-            cxgl: 99,
-            llgl: 99,
-            bzgl: 99,
-            ycgl: 99,
-            agc: 99,
-            llfdl: 99,
-            scada: 99,
-            wxssdl: 99,
-            gzssdl: 99,
-            slssdl: 99,
-            xdssdl: 99,
-            xnssdl: 99,
-            row_span: [],
-            col_span: [],
-            is_light: false,
-          },
-          {
-            name: "风电场",
-            ddname: "牛二",
-            zjrl: 99,
-            fdl: 99,
-            swdl: 99,
-            lyxs: 99,
-            fs: 99,
-            gl: 99,
-            cxgl: 99,
-            llgl: 99,
-            bzgl: 99,
-            ycgl: 99,
-            agc: 99,
-            llfdl: 99,
-            scada: 99,
-            wxssdl: 99,
-            gzssdl: 99,
-            slssdl: 99,
-            xdssdl: 99,
-            xnssdl: 99,
-            row_span: [["name", 2]],
-            col_span: [],
-            is_light: false,
-          },
-          {
-            name: "",
-            ddname: "牛二",
-            zjrl: 99,
-            fdl: 99,
-            swdl: 99,
-            lyxs: 99,
-            fs: 99,
-            gl: 99,
-            cxgl: 99,
-            llgl: 99,
-            bzgl: 99,
-            ycgl: 99,
-            agc: 99,
-            llfdl: 99,
-            scada: 99,
-            wxssdl: 99,
-            gzssdl: 99,
-            slssdl: 99,
-            xdssdl: 99,
-            xnssdl: 99,
-            row_span: [],
-            col_span: [],
-            is_light: false,
-          },
-          {
-            name: "风电场",
-            ddname: "牛二",
-            zjrl: 99,
-            fdl: 99,
-            swdl: 99,
-            lyxs: 99,
-            fs: 99,
-            gl: 99,
-            cxgl: 99,
-            llgl: 99,
-            bzgl: 99,
-            ycgl: 99,
-            agc: 99,
-            llfdl: 99,
-            scada: 99,
-            wxssdl: 99,
-            gzssdl: 99,
-            slssdl: 99,
-            xdssdl: 99,
-            xnssdl: 99,
-            row_span: [],
-            col_span: [],
-            is_light: false,
-          },
-          {
-            name: "风电合计",
-            ddname: "",
-            zjrl: 99,
-            fdl: 99,
-            swdl: 99,
-            lyxs: 99,
-            fs: 99,
-            gl: 99,
-            cxgl: 99,
-            llgl: 99,
-            bzgl: 99,
-            ycgl: 99,
-            agc: 99,
-            llfdl: 99,
-            scada: 99,
-            wxssdl: 99,
-            gzssdl: 99,
-            slssdl: 99,
-            xdssdl: 99,
-            xnssdl: 99,
-            row_span: [],
-            col_span: [["name", 2]],
-            is_light: true,
-          },
-          {
-            name: "风电场",
-            ddname: "牛二",
-            zjrl: 99,
-            fdl: 99,
-            swdl: 99,
-            lyxs: 99,
-            fs: 99,
-            gl: 99,
-            cxgl: 99,
-            llgl: 99,
-            bzgl: 99,
-            ycgl: 99,
-            agc: 99,
-            llfdl: 99,
-            scada: 99,
-            wxssdl: 99,
-            gzssdl: 99,
-            slssdl: 99,
-            xdssdl: 99,
-            xnssdl: 99,
-            row_span: [],
-            col_span: [],
-            is_light: false,
-          },
-          {
-            name: "风电场",
-            ddname: "牛二",
-            zjrl: 99,
-            fdl: 99,
-            swdl: 99,
-            lyxs: 99,
-            fs: 99,
-            gl: 99,
-            cxgl: 99,
-            llgl: 99,
-            bzgl: 99,
-            ycgl: 99,
-            agc: 99,
-            llfdl: 99,
-            scada: 99,
-            wxssdl: 99,
-            gzssdl: 99,
-            slssdl: 99,
-            xdssdl: 99,
-            xnssdl: 99,
-            row_span: [],
-            col_span: [],
-            is_light: false,
-          },
-          {
-            name: "风电场",
-            ddname: "牛二",
-            zjrl: 99,
-            fdl: 99,
-            swdl: 99,
-            lyxs: 99,
-            fs: 99,
-            gl: 99,
-            cxgl: 99,
-            llgl: 99,
-            bzgl: 99,
-            ycgl: 99,
-            agc: 99,
-            llfdl: 99,
-            scada: 99,
-            wxssdl: 99,
-            gzssdl: 99,
-            slssdl: 99,
-            xdssdl: 99,
-            xnssdl: 99,
-            row_span: [],
-            col_span: [],
-            is_light: false,
-          },
-          {
-            name: "风电场",
-            ddname: "牛二",
-            zjrl: 99,
-            fdl: 99,
-            swdl: 99,
-            lyxs: 99,
-            fs: 99,
-            gl: 99,
-            cxgl: 99,
-            llgl: 99,
-            bzgl: 99,
-            ycgl: 99,
-            agc: 99,
-            llfdl: 99,
-            scada: 99,
-            wxssdl: 99,
-            gzssdl: 99,
-            slssdl: 99,
-            xdssdl: 99,
-            xnssdl: 99,
-            row_span: [],
-            col_span: [],
-            is_light: false,
-          },
-          {
-            name: "风电场",
-            ddname: "牛二",
-            zjrl: 99,
-            fdl: 99,
-            swdl: 99,
-            lyxs: 99,
-            fs: 99,
-            gl: 99,
-            cxgl: 99,
-            llgl: 99,
-            bzgl: 99,
-            ycgl: 99,
-            agc: 99,
-            llfdl: 99,
-            scada: 99,
-            wxssdl: 99,
-            gzssdl: 99,
-            slssdl: 99,
-            xdssdl: 99,
-            xnssdl: 99,
-            row_span: [],
-            col_span: [],
-            is_light: false,
-          },
-          {
-            name: "光电合计",
-            ddname: "",
-            zjrl: 99,
-            fdl: 99,
-            swdl: 99,
-            lyxs: 99,
-            fs: 99,
-            gl: 99,
-            cxgl: 99,
-            llgl: 99,
-            bzgl: 99,
-            ycgl: 99,
-            agc: 99,
-            llfdl: 99,
-            scada: 99,
-            wxssdl: 99,
-            gzssdl: 99,
-            slssdl: 99,
-            xdssdl: 99,
-            xnssdl: 99,
-            row_span: [],
-            col_span: [["name", 2]],
-            is_light: false,
-          },
-          {
-            name: "总计",
-            ddname: "",
-            zjrl: 99,
-            fdl: 99,
-            swdl: 99,
-            lyxs: 99,
-            fs: 99,
-            gl: 99,
-            cxgl: 99,
-            llgl: 99,
-            bzgl: 99,
-            ycgl: 99,
-            agc: 99,
-            llfdl: 99,
-            scada: 99,
-            wxssdl: 99,
-            gzssdl: 99,
-            slssdl: 99,
-            xdssdl: 99,
-            xnssdl: 99,
-            row_span: [],
-            col_span: [["name", 2]],
-            is_light: false,
-          },
-        ],
+        data: [],
       },
     };
   },
   // 函数
   methods: {},
   // 生命周期钩子
-  beforeCreate() {
+  beforeCreate () {
     // 创建前
   },
-  created() {
-    // 创建后
-    let tempDatas = [];
-    for (let i = 0; i < 10; i++) {
-      let temp = util.copy(this.datas[0]);
-      if (i == 8) {
-        temp.breakOff = true;
-      }
-      tempDatas.push(temp);
-    }
-    this.datas = util.copy(tempDatas);
-  },
-  beforeMount() {
-    // 渲染前
-  },
-  mounted() {
-    // 渲染后
-  },
-  beforeUpdate() {
-    // 数据更新前
+  created () {
+    let that = this;
+    that.loadingFlg = true;
+    that.BASE.showLoading();
+    that.$nextTick(() => {
+      that.websocketServe && that.websocketServe.disconnect();
+      that.API.requestData({
+        method: "POST",
+        subUrl: "admin/websocketdisconnect",
+        success () {
+          that.websocketServe = datainit("/topic/wpInfoPush");
+        }
+      });
+    });
   },
-  updated() {
-    // 数据更新后
+
+  mounted () {
+
   },
+
+  watch: {
+    // 监听 websocket 回调并包装数据用于展示
+    '$store.state.windturbineMap': function (res) {
+      this.loadingFlg && this.BASE.closeLoading();
+      this.loadingFlg = false;
+      if (res) {
+        let sourceMap = JSON.parse(res);
+        let datas = [];
+        let data = [];
+        sourceMap.maps.forEach(ele => {
+          datas.push({
+            title: ele.name,
+            weather: {
+              type: "cloudy",
+              temperature: 11,
+            },
+            breakOff: ele.fczt === 3,
+            category: {
+              score: ele.zjts,
+              datas: [
+                { text: "运行", num: ele.yxts, color: "green" },
+                { text: "待机", num: ele.djts, color: "purple" },
+                { text: "限电", num: ele.xdts, color: "yellow" },
+                { text: "检修", num: ele.whts, color: "orange" },
+                { text: "故障", num: ele.gzts, color: "red" },
+                { text: "受累", num: ele.slts || 0, color: "blue" },
+                { text: "离线", num: ele.lxts, color: "gray" },
+              ],
+            },
+            items: [
+              {
+                f1: ("AGC" + ele.name.replace(/风电场/g, "") + ":"),
+                f2: "设定",
+                f3: ele.agcygsd,
+                f4: "出线",
+                f5: ele.agccxyg,
+                is_light: true,
+              },
+              {
+                f1: "升压站:",
+                f2: "出线Uab",
+                f3: ele.uab,
+                f4: "电流La",
+                f5: ele.ia,
+                is_light: false,
+              },
+              {
+                f1: "风功:",
+                f2: "未来15分钟",
+                f3: ele.ycgl,
+                f4: "",
+                f5: "",
+                is_light: false,
+              },
+              {
+                f1: "测风塔:",
+                f2: "风速",
+                f3: ((ele.cftfs || 0) + "m/s"),
+                f4: "风向",
+                f5: ele.cftfx || 0,
+                is_light: false,
+              },
+              {
+                f1: "电能量表:",
+                f2: "",
+                f3: ele.dnlb,
+                f4: "",
+                f5: "",
+                is_light: false,
+              },
+            ],
+          });
+        });
+
+        sourceMap.vos.forEach(ele => {
+          ele.row_span = [];
+          ele.col_span = [];
+          ele.is_light = false;
+          data.push(ele);
+        });
+
+        this.sourceMap = sourceMap;
+        this.datas = datas;
+        this.tableData.data = data;
+      } else {
+        this.sourceMap = {};
+        this.datas = [];
+        this.tableData.data = [];
+      }
+    }
+  }
 };
 </script>
 
@@ -677,7 +332,7 @@ export default {
 
     &::after,
     &::before {
-      content: "";
+      content: '';
       position: absolute;
       width: 0.185vh;
       height: 0.185vh;

+ 235 - 239
src/views/Status/components/status-panel.vue

@@ -1,277 +1,273 @@
 <template>
-    <div class="status-panel">
-        <div class="pause" v-if="data.breakOff">中断</div>
-        <ComPanel class="status-com-panel" :title="data.title">
-            <div class="p-body">
-                <div class="category-box">
-                    <div class="score">
-                        <span>{{data.category.score}}</span>
-                    </div>
-                    <div class="box">
-                        <div class="category-item" v-for="(item, index) of data.category.datas" :key="index">
-                            <div>{{item.text}}</div>
-                            <div :class="item.color">{{item.num}}</div>
-                        </div>
-                    </div>
-                </div>
-                <div class="item-box">
-                    <div class="data-item" v-for="(item, index) of data.items" :key="index" :class="{ 'light': item.is_light }">
-                        <div class="f1">{{item.f1}}</div>
-                        <div class="f2">{{item.f2}}</div>
-                        <div class="f3">{{item.f3}}</div>
-                        <div class="f4">{{item.f4}}</div>
-                        <div class="f5">{{item.f5}}</div>
-                    </div>
-                </div>
+  <div class="status-panel">
+    <div class="pause" v-if="data.breakOff">中断</div>
+    <ComPanel class="status-com-panel" :title="data.title">
+      <div class="p-body">
+        <div class="category-box">
+          <div class="score">
+            <span>{{data.category.score}}</span>
+          </div>
+          <div class="box">
+            <div class="category-item" v-for="(item, index) of data.category.datas" :key="index">
+              <div>{{item.text}}</div>
+              <div :class="item.color">{{item.num}}</div>
             </div>
-        </ComPanel>
-    </div>
+          </div>
+        </div>
+        <div class="item-box">
+          <div class="data-item" v-for="(item, index) of data.items" :key="index" :class="{ 'light': item.is_light }">
+            <div class="f1">{{item.f1}}</div>
+            <div class="f2">{{item.f2}}</div>
+            <div class="f3">{{item.f3}}</div>
+            <div class="f4">{{item.f4}}</div>
+            <div class="f5">{{item.f5}}</div>
+          </div>
+        </div>
+      </div>
+    </ComPanel>
+  </div>
 </template>
 
 <script>
-    import ComPanel from '@com/coms/panel/panel.vue'
-    export default {
-        // 名称
-        name: "StatusPanel",
-        // 使用组件
-        components: {
-            ComPanel
-        },
-        /**
-         * {
-                title: "某某某风电场",
-                weather: {
-                    type: "cloudy",
-                    temperature: 11
-                },
-                breakOff: false,
-                category: {
-                    score: 66,
-                    datas: [
-                        { text: "运行", num: 30, color: 'green' },
-                        { text: "待机", num: 27, color: 'purple' },
-                        { text: "限电", num: 30, color: 'yellow' },
-                        { text: "检修", num: 30, color: 'orange' },
-                        { text: "故障", num: 13, color: 'red' },
-                        { text: "受累", num: 30, color: 'blue' },
-                        { text: "离线", num: 30, color: 'gray' },
-                    ]
-                },
-                items: [
-                    { f1: 'AGC宋六:', f2: '设定', f3: '66', f4: '出线', f5: '11', is_light: true },
-                    { f1: '升压站:', f2: '出线Uab/La', f3: '23/3 23/3', f4: '电压', f5: '103 103', is_light: false },
-                    { f1: '风功:', f2: '未来15分钟', f3: '103', f4: '', f5: '', is_light: false },
-                    { f1: '测风塔:', f2: '风速', f3: '103KM', f4: '风向', f5: '103 62', is_light: false },
-                    { f1: '电能量表:', f2: '', f3: '103 62', f4: '', f5: '', is_light: false },
-                ]
-            }
-         */
-        props: {
-            data: Object
-        },
-        // 数据
-        data() {
-            return {
+import ComPanel from '@com/coms/panel/panel.vue'
+export default {
+  // 名称
+  name: "StatusPanel",
+  // 使用组件
+  components: {
+    ComPanel
+  },
+  /**
+   * {
+          title: "某某某风电场",
+          weather: {
+              type: "cloudy",
+              temperature: 11
+          },
+          breakOff: false,
+          category: {
+              score: 66,
+              datas: [
+                  { text: "运行", num: 30, color: 'green' },
+                  { text: "待机", num: 27, color: 'purple' },
+                  { text: "限电", num: 30, color: 'yellow' },
+                  { text: "检修", num: 30, color: 'orange' },
+                  { text: "故障", num: 13, color: 'red' },
+                  { text: "受累", num: 30, color: 'blue' },
+                  { text: "离线", num: 30, color: 'gray' },
+              ]
+          },
+          items: [
+              { f1: 'AGC宋六:', f2: '设定', f3: '66', f4: '出线', f5: '11', is_light: true },
+              { f1: '升压站:', f2: '出线Uab/La', f3: '23/3 23/3', f4: '电压', f5: '103 103', is_light: false },
+              { f1: '风功:', f2: '未来15分钟', f3: '103', f4: '', f5: '', is_light: false },
+              { f1: '测风塔:', f2: '风速', f3: '103KM', f4: '风向', f5: '103 62', is_light: false },
+              { f1: '电能量表:', f2: '', f3: '103 62', f4: '', f5: '', is_light: false },
+          ]
+      }
+   */
+  props: {
+    data: Object
+  },
+  // 数据
+  data () {
+    return {
 
-            }
-        },
-        // 函数
-        methods: {},
-        // 生命周期钩子
-        beforeCreate() {
-            // 创建前
-        },
-        created() {
-            // 创建后
-        },
-        beforeMount() {
-            // 渲染前
-        },
-        mounted() {
-            // 渲染后
-        },
-        beforeUpdate() {
-            // 数据更新前
-        },
-        updated() {
-            // 数据更新后
-        },
     }
+  },
+  // 函数
+  methods: {},
+  // 生命周期钩子
+  beforeCreate () {
+    // 创建前
+  },
+  created () {
+    // 创建后
+  },
+  beforeMount () {
+    // 渲染前
+  },
+  mounted () {
+    // 渲染后
+  },
+  beforeUpdate () {
+    // 数据更新前
+  },
+  updated () {
+    // 数据更新后
+  },
+}
 </script>
 
 <style lang="less" scoped>
-    .status-panel {
-        position: relative;
-        height: 22.315vh;
+.status-panel {
+  position: relative;
+  height: 22.315vh;
 
-        .pause {
-            position: absolute;
-            width: 100%;
-            height: 100%;
-            z-index: 1;
-            left: 0;
-            top: 0;
-            background-color: fade(@darkgray, 50%);
-            color: fade(@write, 60%);
-            font-size: 5.556vh;
-            font-weight: 600;
-            display: flex;
-            align-items: center;
-            justify-content: center;
-            opacity: 0.9;
-            backdrop-filter: blur(0.370vh);
-        }
-
-        .status-com-panel {
-            width: 100%;
-            height: 100%;
+  .pause {
+    position: absolute;
+    width: 100%;
+    height: 100%;
+    z-index: 1;
+    left: 0;
+    top: 0;
+    background-color: fade(@darkgray, 50%);
+    color: fade(@write, 60%);
+    font-size: 5.556vh;
+    font-weight: 600;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    opacity: 0.9;
+    backdrop-filter: blur(0.37vh);
+  }
 
-            .p-body {
-                width: 100%;
-                height: 19.074vh;
-                display: flex;
-                flex-direction: column;
-                margin-top: -0.926vh;
+  .status-com-panel {
+    width: 100%;
+    height: 100%;
 
-                .category-box {
-                    width: 100%;
-                    background-color: fade(@darkgray, 30%);
-                    display: flex;
-                    margin-bottom: 0.37vh;
+    .p-body {
+      width: 100%;
+      height: 19.074vh;
+      display: flex;
+      flex-direction: column;
+      margin-top: -0.926vh;
 
-                    .score {
-                        padding: 0.833vh 1.481vh;
+      .category-box {
+        width: 100%;
+        background-color: fade(@darkgray, 30%);
+        display: flex;
+        margin-bottom: 0.37vh;
 
-                        span {
-                            width: 3.889vh;
-                            height: 3.889vh;
-                            border-radius: 50%;
-                            display: flex;
-                            align-items: center;
-                            justify-content: center;
-                            color: @green;
-                            border: 0.093vh solid @green;
-                            background-color: fade(@green, 20%);
-                            font-size: @fontsize;
-                        }
-                    }
+        .score {
+          padding: 0.833vh 1.481vh;
 
-                    .box {
-                        flex-grow: 1;
-                        display: flex;
+          span {
+            width: 3.889vh;
+            height: 3.889vh;
+            border-radius: 50%;
+            display: flex;
+            align-items: center;
+            justify-content: center;
+            color: @green;
+            border: 0.093vh solid @green;
+            background-color: fade(@green, 20%);
+            font-size: @fontsize;
+          }
+        }
 
-                        .category-item {
-                            flex: 1;
-                            display: flex;
-                            flex-direction: column;
-                            align-items: center;
-                            justify-content: center;
-                            font-weight: 600;
+        .box {
+          flex-grow: 1;
+          display: flex;
 
-                            div {
-                                flex: 1;
-                                font-size: @fontsize-s;
+          .category-item {
+            flex: 1;
+            display: flex;
+            flex-direction: column;
+            align-items: center;
+            justify-content: center;
+            font-weight: 600;
 
-                                &:first-child {
-                                    display: flex;
-                                    align-items: flex-end;
-                                    color: @gray;
-                                }
-                            }
-                        }
-                    }
-                }
+            div {
+              flex: 1;
+              font-size: @fontsize-s;
 
-                .item-box {
-                    flex-grow: 1;
-                    display: flex;
-                    flex-direction: column;
+              &:first-child {
+                display: flex;
+                align-items: flex-end;
+                color: @gray;
+              }
+            }
+          }
+        }
+      }
 
-                    .data-item {
-                        flex: 1;
-                        display: flex;
-                        flex-direction: row;
-                        background-color: fade(@darkgray, 20%);
-                        margin-top: 0.278vh;
+      .item-box {
+        flex-grow: 1;
+        display: flex;
+        flex-direction: column;
 
-                        div {
-                            font-size: @fontsize-s;
-                            overflow: hidden;
-                            display: flex;
-                            align-items: center;
-                        }
+        .data-item {
+          flex: 1;
+          display: flex;
+          flex-direction: row;
+          background-color: fade(@darkgray, 20%);
+          margin-top: 0.278vh;
 
-                        .f1,
-                        .f2,
-                        .f4 {
-                            text-align: right;
-                            color: @gray;
-                            justify-content: flex-end;
-                        }
+          div {
+            font-size: @fontsize-s;
+            overflow: hidden;
+            display: flex;
+            align-items: center;
+          }
 
-                        .f3,
-                        .f5 {
-                            font-family: "Bicubik";
-                            text-align: left;
-                            color: @green;
-                            justify-content: flex-start;
-                        }
+          .f1,
+          .f2,
+          .f4 {
+            text-align: right;
+            color: @gray;
+            justify-content: flex-end;
+          }
 
-                        .f1 {
-                            flex: 2;
-                        }
+          .f3,
+          .f5 {
+            font-family: 'Bicubik';
+            text-align: left;
+            color: @green;
+            justify-content: flex-start;
+          }
 
-                        .f2 {
-                            flex: 3;
-                            margin-right: 0.556vh;
-                        }
+          .f1 {
+            flex: 2;
+          }
 
-                        .f3 {
-                            flex: 3;
-                        }
+          .f2 {
+            flex: 3;
+            margin-right: 0.556vh;
+          }
 
-                        .f4 {
-                            flex: 1;
-                            margin-right: 0.556vh;
-                        }
+          .f3 {
+            flex: 3;
+          }
 
-                        .f5 {
-                            flex: 2;
-                            margin-right: 0;
-                        }
+          .f4 {
+            flex: 1;
+            margin-right: 0.556vh;
+          }
 
+          .f5 {
+            flex: 2;
+            margin-right: 0;
+          }
 
-                        &.light {
-                            background-color: fade(@darkgray, 50%);
-                            position: relative;
-                            
-                            &::after {
-                                content: '';
-                                position: absolute;
-                                height: 100%;
-                                width: 0.278vh;
-                                background-color: @green;
-                                top: 0;
-                                left: 0;
-                            }
-                            
-                            .f1,
-                            .f2,
-                            .f4 {
-                                color: @write;
-                            }
-                            
-                            .f3,
-                            .f5 {
-                                color: fade(@write, 60%);
-                            }
-                        }
+          &.light {
+            background-color: fade(@darkgray, 50%);
+            position: relative;
 
-                    }
-                }
+            &::after {
+              content: '';
+              position: absolute;
+              height: 100%;
+              width: 0.278vh;
+              background-color: @green;
+              top: 0;
+              left: 0;
             }
 
+            .f1,
+            .f2,
+            .f4 {
+              color: @write;
+            }
 
+            .f3,
+            .f5 {
+              color: fade(@write, 60%);
+            }
+          }
         }
+      }
     }
+  }
+}
 </style>

+ 153 - 121
vue.config.js

@@ -2,134 +2,166 @@ const path = require("path");
 const resolve = (dir) => path.join(__dirname, dir);
 // const SVGSpriteLoaderPlugin = require("svg-sprite-loader/plugin");
 
-function extendDefaultPlugins(arr) {
-    let plug = [
-        'removeDoctype',
-        'removeXMLProcInst',
-        'removeComments',
-        'removeMetadata',
-        'removeEditorsNSData',
-        'cleanupAttrs',
-        'mergeStyles',
-        'inlineStyles',
-        'minifyStyles',
-        'cleanupIDs',
-        'removeUselessDefs',
-        'cleanupNumericValues',
-        'convertColors',
-        'removeUnknownsAndDefaults',
-        'removeNonInheritableGroupAttrs',
-        'removeUselessStrokeAndFill',
-        'removeViewBox',
-        'cleanupEnableBackground',
-        'removeHiddenElems',
-        'removeEmptyText',
-        'convertShapeToPath',
-        'convertEllipseToCircle',
-        'moveElemsAttrsToGroup',
-        'moveGroupAttrsToElems',
-        'collapseGroups',
-        'convertPathData',
-        'convertTransform',
-        'removeEmptyAttrs',
-        'removeEmptyContainers',
-        'mergePaths',
-        'removeUnusedNS',
-        'sortDefsChildren',
-        'removeTitle',
-        'removeDesc'
-    ];
-    return plug.concat(arr);
+function extendDefaultPlugins (arr) {
+  let plug = [
+    'removeDoctype',
+    'removeXMLProcInst',
+    'removeComments',
+    'removeMetadata',
+    'removeEditorsNSData',
+    'cleanupAttrs',
+    'mergeStyles',
+    'inlineStyles',
+    'minifyStyles',
+    'cleanupIDs',
+    'removeUselessDefs',
+    'cleanupNumericValues',
+    'convertColors',
+    'removeUnknownsAndDefaults',
+    'removeNonInheritableGroupAttrs',
+    'removeUselessStrokeAndFill',
+    'removeViewBox',
+    'cleanupEnableBackground',
+    'removeHiddenElems',
+    'removeEmptyText',
+    'convertShapeToPath',
+    'convertEllipseToCircle',
+    'moveElemsAttrsToGroup',
+    'moveGroupAttrsToElems',
+    'collapseGroups',
+    'convertPathData',
+    'convertTransform',
+    'removeEmptyAttrs',
+    'removeEmptyContainers',
+    'mergePaths',
+    'removeUnusedNS',
+    'sortDefsChildren',
+    'removeTitle',
+    'removeDesc'
+  ];
+  return plug.concat(arr);
 }
 
 // 添加less继承
-function addStyleResource(rule) {
-    rule.use('style-resource')
-        .loader('style-resources-loader')
-        .options({
-            patterns: [
-                resolve('src/assets/styles/common/common.less')
-            ]
-        })
+function addStyleResource (rule) {
+  rule.use('style-resource')
+    .loader('style-resources-loader')
+    .options({
+      patterns: [
+        resolve('src/assets/styles/common/common.less')
+      ]
+    })
 }
 
 
 module.exports = {
-    chainWebpack: (config) => {
-
-        // 路径别名
-        config.resolve.alias
-            .set("@", resolve("src"))
-            .set("@node", resolve("node_modules"))
-            .set("@com", resolve("src/components"))
-            .set("@assets", resolve("src/assets"));
-
-        // less 继承
-        const types = ['vue-modules', 'vue', 'normal-modules', 'normal'];
-        types.forEach(type => addStyleResource(config.module.rule('less').oneOf(type)));
-
-        // svg 雪碧图
-        config.module // 排除其他svg-loader
-            .rule('svg')
-            .exclude.add(resolve('src/assets/icon/svg'))
-            .end()
-            .exclude.add(resolve('src/assets/icon/svg_fill'))
-            .end();
-
-        // svg雪碧图
-        const svgRule = config.module.rule('icons');
-        svgRule.test(/\.svg$/)
-            .include.add(resolve('src/assets/icon/svg'))
-            .end()
-            .use('svg-sprite-loader')
-            .loader('svg-sprite-loader')
-            .options({
-                symbolId: 'svg-[name]',
-                // extract: true,
-                // publicPath: "img/",
-                // spriteFilename: "svg-sprite-[hash:8].svg",
-            });
-
-        // config
-        //     .plugin("svgsprite")
-        //     .use(SVGSpriteLoaderPlugin, [{ 
-        //       plainSprite: true
-        //     }]);
-
-        // svgo 去除svg中无用元素
-        svgRule.use('svgo-loader').loader('svgo-loader').options({
-            plugins: extendDefaultPlugins([{
-                name: "removeAttrs",
-                params: {
-                    attrs: 'fill',
-                }
-            }])
-        });
-
-        // svg雪碧图 不去除fill属性
-        // const svgRuleFill = config.module.rule('icons_fill');
-        // svgRuleFill.test(/\.svg$/)
-        //     .include.add(resolve('src/assets/icon/svg_fill'))
-        //     .end()
-        //     .use('svg-sprite-loader')
-        //     .loader('svg-sprite-loader')
-        //     .options({
-        //         symbolId: 'fill-[name]',
-        //         // extract: true,
-        //         // publicPath: "img/",
-        //         // spriteFilename: "svg-sprite-[hash:8].svg",
-        //     });
-
-        // // config
-        // //     .plugin("svgsprite")
-        // //     .use(SVGSpriteLoaderPlugin, [{ 
-        // //       plainSprite: true
-        // //     }]);
-
-        // // svgo 去除svg中无用元素
-        // svgRuleFill.use('svgo-loader').loader('svgo-loader').options({
-        //     plugins: extendDefaultPlugins([])
-        // });
 
+  publicPath: "./", // 默认'/',部署应用包时的基本 URL
+  indexPath: 'index.html', // 相对于打包路径index.html的路径
+  outputDir: 'dist', // 'dist', 生产环境构建文件的目录
+  assetsDir: 'static', // 相对于outputDir的静态资源(js、css、img、fonts)目录
+  lintOnSave: false, // 是否在开发环境下通过 eslint-loader 在每次保存时 lint 代码
+  runtimeCompiler: true, // 是否使用包含运行时编译器的 Vue 构建版本
+
+  chainWebpack: (config) => {
+
+    config.resolve.symlinks(true); // 修复热更新失效
+
+    // 路径别名
+    config.resolve.alias
+      .set("@", resolve("src"))
+      .set("@node", resolve("node_modules"))
+      .set("@com", resolve("src/components"))
+      .set("@assets", resolve("src/assets"))
+      .set("@api", resolve("src/api"))
+      .set("@store", resolve("src/store"))
+      .set("@modeConfig", resolve("public/static/config"))
+      .set("@tools", resolve("src/tools"));
+
+    // less 继承
+    const types = ['vue-modules', 'vue', 'normal-modules', 'normal'];
+    types.forEach(type => addStyleResource(config.module.rule('less').oneOf(type)));
+
+    // svg 雪碧图
+    config.module // 排除其他svg-loader
+      .rule('svg')
+      .exclude.add(resolve('src/assets/icon/svg'))
+      .end()
+      .exclude.add(resolve('src/assets/icon/svg_fill'))
+      .end();
+
+    // svg雪碧图
+    const svgRule = config.module.rule('icons');
+    svgRule.test(/\.svg$/)
+      .include.add(resolve('src/assets/icon/svg'))
+      .end()
+      .use('svg-sprite-loader')
+      .loader('svg-sprite-loader')
+      .options({
+        symbolId: 'svg-[name]',
+        // extract: true,
+        // publicPath: "img/",
+        // spriteFilename: "svg-sprite-[hash:8].svg",
+      });
+
+    // config
+    //     .plugin("svgsprite")
+    //     .use(SVGSpriteLoaderPlugin, [{ 
+    //       plainSprite: true
+    //     }]);
+
+    // svgo 去除svg中无用元素
+    svgRule.use('svgo-loader').loader('svgo-loader').options({
+      plugins: extendDefaultPlugins([{
+        name: "removeAttrs",
+        params: {
+          attrs: 'fill',
+        }
+      }])
+    });
+
+    // svg雪碧图 不去除fill属性
+    // const svgRuleFill = config.module.rule('icons_fill');
+    // svgRuleFill.test(/\.svg$/)
+    //     .include.add(resolve('src/assets/icon/svg_fill'))
+    //     .end()
+    //     .use('svg-sprite-loader')
+    //     .loader('svg-sprite-loader')
+    //     .options({
+    //         symbolId: 'fill-[name]',
+    //         // extract: true,
+    //         // publicPath: "img/",
+    //         // spriteFilename: "svg-sprite-[hash:8].svg",
+    //     });
+
+    // // config
+    // //     .plugin("svgsprite")
+    // //     .use(SVGSpriteLoaderPlugin, [{ 
+    // //       plainSprite: true
+    // //     }]);
+
+    // // svgo 去除svg中无用元素
+    // svgRuleFill.use('svgo-loader').loader('svgo-loader').options({
+    //     plugins: extendDefaultPlugins([])
+    // });
+
+  },
+
+  devServer: {
+    //代理配置
+    proxy: {
+      '/cbk': {
+        target: 'https://h5.caibeike.com.cn/', // 请求地址
+
+        changeOrigin: true, // 在vue-cli3中,默认changeOrigin的值是true,意味着服务器host设置成target,这与vue-cli2不一致,vue-cli2这个默认值是false
+        // changeOrigin的值是true,target是host, request URL是http://baidu.com
+        // 如果设置changeOrigin: false,host就是浏览器发送过来的host,也就是localhost:8082。
+
+        pathRewrite: {  // 路径重写,eg:把api接口替换为''
+          '^/cbk': ''
+        }
+      }
     },
+    open: false, // 是否打开浏览器
+  }
 }