he wei
2022-01-14 3a1f7c24e1dcb2f62275b5430d89c827cfdc3c6a
U 一体机相关
13个文件已添加
8个文件已修改
7527 ■■■■■ 已修改文件
package.json 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/js/api.js 19 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/js/tools/getPageMenu.js 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/js/websocket/getWsUrl.js 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/js/websocket/index.js 54 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/rtmpVideo.vue 187 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/router/index.js 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/dataTest/btsStatus.vue 237 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/dataTest/components/HomeListAio.vue 332 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/dataTest/components/activateDialogContent.vue 1109 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/dataTest/components/endoscopeVideo.vue 89 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/dataTest/historyAio.vue 2700 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/dataTest/historyInfoMager.vue 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/dataTest/js/btsStatus.js 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/dataTest/js/draw_diagram.js 464 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/dataTest/js/history.js 74 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/dataTest/js/historyAio.js 108 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/dataTest/js/realTimeAio.js 78 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/dataTest/realTimeAio.vue 1648 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/dataTest/standardLine.vue 336 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
vue.config.js 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
package.json
@@ -27,6 +27,9 @@
    "postcss-px2rem": "^0.3.0",
    "qs": "^6.9.4",
    "script-loader": "^0.7.2",
    "video.js": "^7.14.3",
    "videojs-flash": "^2.1.0",
    "videojs-swf": "^5.4.2",
    "vue-jsonp": "^0.1.8",
    "vue-layer": "^1.2.0",
    "vue-seamless-scroll": "^1.1.23",
src/assets/js/api.js
@@ -103,17 +103,16 @@
  })
}
/**
 * 包机组下的查询站点名
 * stationName1
 * User_battgroup_baojigroup_battgroupAction!serchStationByStationName1   // 旧
 * 包机组下的查询站点名 (机房去重)
 * {stationName1}
 */
//  export const getUserStations = (params) => {
//   return axios({
//     method: 'POST',
//     url: 'baoJiGroupBattGroup/stationInfo',
//     params
//   })
// }
 export const getUserStationList = (params) => {
  return axios({
    method: 'GET',
    url: 'baoJiGroupBattGroup/stationInfo',
    params
  })
}
/**
 * 根据维护区和机房查询蓄电池组
src/assets/js/tools/getPageMenu.js
@@ -84,8 +84,8 @@
        },
        {
          label: '设备状态查询',
          name: 'btsStatusTest',
          src: '/dataMager/btsStatus',
          name: 'btsStatus',
          src: '/dataTest/btsStatus',
          closable: true,
          id: 2005,
          menuId: 2,
@@ -96,7 +96,7 @@
        {
          label: "一体机导入记录",
          name: "historyAio",
          src: "/history-aio",
          src: "/dataTest/historyAio",
          closable: true,
          id: 2006,
          menuId: 2,
src/assets/js/websocket/getWsUrl.js
New file
@@ -0,0 +1,15 @@
/**
 * 获取Websocket的连接
 * @param action
 * @returns {string}
 */
function getWsUrl(action, port) {
  let _port = port ? port : 8090;
  let hostname = window.location.hostname;
  if (process.env.NODE_ENV == 'dev') {
    hostname = "localhost";
  }
  return 'ws://' + hostname + ':' + _port + '/fg/' + action;
}
export default getWsUrl;
src/assets/js/websocket/index.js
New file
@@ -0,0 +1,54 @@
import getWsUrl from './getWsUrl';
export default function (url) {
  const wsUri = getWsUrl(url);
  return {
    data() {
      return {
        SOCKET: null
      }
    },
    computed: {
      isWSOpen () {
        return !!(this.SOCKET && this.SOCKET.readyState);
      }
    },
    methods: {
      // 打开链接
      openSocket() {
        // 初始化WebSocket
        this.WSClose();
        this.WSInit();
      },
      // 初始化
      WSInit() {
        // 未被初始化初始化
        if (!this.isOpen) {
          this.SOCKET = new WebSocket(wsUri);
          this.SOCKET.onmessage = this.onWSMessage;
          this.SOCKET.onopen = this.onWSOpen;
          this.SOCKET.onerror = this.onWSError;
          this.SOCKET.onclose = this.WSClose;
        }
      },
      onWSOpen() {
      },
      onWSMessage() {
      },
      onWSError() {
        console.log('链接失败', wsUri);
      },
      WSClose() {
        if (this.isWSOpen) {
          this.SOCKET.close();
        }
      }
    },
    mounted () {
      this.openSocket();
    },
    beforeDestroy() {
      this.WSClose();
    }
  }
}
src/components/rtmpVideo.vue
@@ -1,109 +1,114 @@
<template>
    <div class="rtmp-video-wrapper">
        <video ref="videoPlayer" class="video-js"></video>
    </div>
  <div class="rtmp-video-wrapper">
    <video ref="videoPlayer" class="video-js"></video>
  </div>
</template>
<script>
import videoJs from 'video.js';
import 'videojs-flash';
import SWF_URL from 'videojs-swf/dist/video-js.swf';
import loadImg from '@/assets/images/dw_bg.jpg';
import videoJs from "video.js";
import "videojs-flash";
import SWF_URL from "videojs-swf/dist/video-js.swf";
import loadImg from "@/assets/images/dw_bg.jpg";
export default {
    name: "rtmpVideo",
    player: "",
    props: {
        url: {
            type: String,
            default: "",
        },
  name: "rtmpVideo",
  player: "",
  props: {
    url: {
      type: String,
      default: "",
    },
    data() {
        return {
            options: {
                width: 800,
                height: 450,
                controls: true,        // 控制栏
                autoplay: false,         // 自动播放
                sources: [{             // 流配置,数组形式,会根据兼容顺序自动切换
                    type: 'rtmp/mp4',
                    src: loadImg // 亲测可用
                }],
                techOrder: ['html5', 'flash'],
                flash: {
                    swf: SWF_URL
                },
            },
            playFlag: false,
  },
  data() {
    return {
      options: {
        width: 800,
        height: 450,
        controls: true, // 控制栏
        autoplay: false, // 自动播放
        sources: [
          {
            // 流配置,数组形式,会根据兼容顺序自动切换
            type: "rtmp/mp4",
            src: loadImg, // 亲测可用
          },
        ],
        techOrder: ["html5", "flash"],
        flash: {
          swf: SWF_URL,
        },
      },
      playFlag: false,
    };
  },
  watch: {
    url() {
      this.changeUrl();
    },
  },
  methods: {
    create() {
      let self = this;
      // 初始化播放器
      this.$options.player = videoJs(
        this.$refs.videoPlayer,
        this.options,
        function onPlayerReady() {
          this.on("pause", function () {
            console.log("暂停播放");
          });
          this.on("play", function () {
            self.playFlag = true;
            console.log("开始/恢复播放");
          });
          this.on("ended", function () {
            console.log("结束播放");
          });
          this.on("loadeddata", function () {
            console.log("loadeddata数据加载完成");
          });
          this.on("error", function () {
            console.log("error");
          });
        }
      );
    },
    watch: {
        url() {
            this.changeUrl();
        },
    changeUrl() {
      let url = this.url;
      if (this.$options.player) {
        let myPlayer = this.$options.player;
        myPlayer.src(url);
        myPlayer.load(url);
      }
    },
    methods: {
        create() {
            let self = this;
            // 初始化播放器
            this.$options.player = videoJs(this.$refs.videoPlayer, this.options, function onPlayerReady() {
                this.on('pause', function() {
                    console.log('暂停播放')
                })
                this.on('play', function() {
                    self.playFlag = true;
                    console.log('开始/恢复播放')
                })
                this.on('ended', function() {
                    console.log('结束播放')
                })
                this.on('loadeddata', function() {
                    console.log('loadeddata数据加载完成')
                })
                this.on('error', function() {
                    console.log('error')
                })
            });
        },
        changeUrl() {
            let url = this.url;
            if(this.$options.player) {
                let myPlayer =  this.$options.player;
                myPlayer.src(url);
                myPlayer.load(url);
            }
        },
        play() {
            this.$nextTick(()=>{
                if(this.$options.player) {
                    this.$options.player.play();
                }
            });
        },
        dispose() {
            if(this.$options.player) {
                this.playFlag = false;
                this.$options.player.dispose();
                this.$options.player = "";
            }
        },
    play() {
      this.$nextTick(() => {
        if (this.$options.player) {
          this.$options.player.play();
        }
      });
    },
    mounted() {
        this.create();
    dispose() {
      if (this.$options.player) {
        this.playFlag = false;
        this.$options.player.dispose();
        this.$options.player = "";
      }
    },
    beforeDestroy() {
        this.dispose();
        console.log("销毁rtmp流");
    }
}
  },
  mounted() {
    this.create();
  },
  beforeDestroy() {
    this.dispose();
    console.log("销毁rtmp流");
  },
};
</script>
<style scoped>
.rtmp-video-wrapper {
    width: 100%;
    height: 100%;
  width: 100%;
  height: 100%;
}
</style>
src/router/index.js
@@ -345,6 +345,15 @@
        url: '/dataTest/realTimeStorage'
      },
      component: () => import('@/views/dataTest/realTimeStorage')
    }, {
      path: 'real-time-aio/:battGroupId',
      name: 'movingRingSystem',
      meta: {
        title: '实时监控',
        icon: '',
        url: '/dataTest/realTimeAio'
      },
      component: () => import('@/views/dataTest/realTimeAio')
    }]
  }, {
    path: 'history',
@@ -362,6 +371,30 @@
      title: '历史数据管理',
      icon: ''
    }
  }, {
    path: 'standardLine',
    name: 'standardLine',
    component: () => import('@/views/dataTest/standardLine'),
    meta: {
      title: '标准曲线',
      icon: ''
    }
  }, {
    path: 'btsStatus',
    name: 'btsStatus',
    component: () => import('@/views/dataTest/btsStatus'),
    meta: {
      title: '设备状态查询',
      icon: ''
    }
  }, {
    path: 'historyAio',
    name: 'historyAio',
    component: () => import('@/views/dataTest/historyAio'),
    meta: {
      title: '一体机导入记录',
      icon: ''
    }
  }]
},
{
src/views/dataTest/btsStatus.vue
New file
@@ -0,0 +1,237 @@
<template>
  <!-- <title>核容测试</title> -->
  <flex-layout>
    <div class="table-layout filter-box-table" slot="header">
      <div class="table-row">
        <!-- 省 -->
        <div class="table-cell text-right">机房名称:</div>
        <div class="table-cell">
          <el-select
            v-model="params.devId"
            size="small"
            @change="sendMessage"
            placeholder="请选择机房名称"
          >
            <el-option
              v-for="item in stationNameList"
              :key="item.value"
              :label="item.label"
              :value="item.value"
            >
            </el-option>
          </el-select>
        </div>
        <!-- 事件类型 -->
        <div class="table-cell text-right">设备工作状态:</div>
        <div class="table-cell">
          <el-select
            ref="selecetEvent"
            v-model="params.devWorkstate"
            @change="sendMessage"
            size="small"
            placeholder="请选择设备工作状态"
          >
            <el-option label="全部(共6种)" :value="-1"></el-option>
            <el-option label="在线浮充" :value="0"></el-option>
            <el-option label="预充电(限流充电)" :value="1"></el-option>
            <el-option label="核容测试" :value="2"></el-option>
            <el-option label="停电放电" :value="3"></el-option>
            <el-option label="内阻测试" :value="4"></el-option>
            <el-option label="K1/D1测试" :value="5"></el-option>
          </el-select>
        </div>
      </div>
    </div>
    <div class="flex-page-content">
      <!-- 表单 -->
      <el-table
        stripe
        size="small"
        :data="dataList"
        height="100%"
        class="tableCent"
      >
        <el-table-column
          prop="stationName"
          align="center"
          label="机房名称"
          min-width="360"
        ></el-table-column>
        <!--            <el-table-column prop="devId" align="center" label="设备ID"></el-table-column>-->
        <!--            <el-table-column prop="deviceName" align="center" label="设备名称"></el-table-column>-->
        <el-table-column
          prop="deviceStatus"
          align="center"
          label="设备状态"
        ></el-table-column>
        <!-- workstate[_data.devWorkstate] -->
        <el-table-column
          prop="devCaptestOnlinevol"
          align="center"
          min-width="120"
          label="在线电压(V)"
        ></el-table-column>
        <el-table-column
          prop="devCaptestGroupvol"
          align="center"
          min-width="120"
          label="组端电压(V)"
        ></el-table-column>
        <el-table-column
          prop="devCaptestCurr"
          align="center"
          min-width="120"
          label="组端电流(mA)"
        ></el-table-column>
        <el-table-column
          prop="devTemp"
          align="center"
          min-width="120"
          label="设备温度(℃)"
        ></el-table-column>
        <el-table-column
          prop="devCaptestCap"
          align="center"
          min-width="120"
          label="已测容量(AH)"
        ></el-table-column>
        <el-table-column
          prop="dev61850Alarms"
          align="center"
          label="设备告警"
        ></el-table-column>
        <el-table-column
          prop="dateLong"
          align="center"
          label="已测时间"
        ></el-table-column>
      </el-table>
    </div>
    <!-- 底部 -->
    <div class="flex-page-footer" slot="footer"></div>
  </flex-layout>
</template>
<script>
import { const_61850 } from "@/assets/js/const";
import { formatSeconds, getQueryString, Timeout } from "@/assets/js/tools";
import { UserBattgroup } from "./js/btsStatus";
import createWs from "@/assets/js/websocket";
const WSMixin = createWs("deviceWorkState");
const uId = sessionStorage.getItem("userId") * 1;
export default {
  name: 'btsStatus',
  mixins: [WSMixin],
  data() {
    let devWorkstate = getQueryString("workStauts");
    return {
      pageCurr: 1,
      pageSize: 10,
      pageAll: 0,
      devId: 0,
      stationNameList: [],
      dataList: [],
      timer: new Timeout("btsStatusTest"),
      params: {
        devId: 0,
        devWorkstate: devWorkstate ? devWorkstate * 1 : -1,
        note: uId,
      },
    };
  },
  created() {
    this.queryStationName();
    // this.startQueryList();
  },
  mounted() {},
  methods: {
    // // 展示数据数量
    // handleSizeChange(val) {
    //   this.pageSize = val;
    //   this.queryList();
    // },
    // // 翻页
    // handleCurrentChange(val) {
    //   this.pageCurr = val;
    //   this.queryList();
    // },
    // startQueryList() {
    //   this.timer.start(() => {
    //     this.$axios
    //       .all([this.queryList()])
    //       .then(() => {
    //         this.timer.open();
    //       })
    //       .catch((error) => {
    //         this.timer.open();
    //         console.log(error);
    //       });
    //   }, 4000);
    // },
    onWSOpen() {
      this.sendMessage();
    },
    onWSMessage(res) {
      res = JSON.parse(res.data);
      console.log(res, "====socket");
      let params = [];
      if (res.code) {
        params = res.data.map((item) => {
          item.deviceStatus = const_61850.workstates[item.devWorkstate];
          item.dev61850Alarms = this.getAlarmsText(item.dev61850alarms);
          item.dateLong = formatSeconds(item.battTestTLong);
          return item;
        });
      }
      this.dataList = params;
    },
    sendMessage() {
      this.SOCKET.send(JSON.stringify(this.params));
    },
    // 获取告警参数
    getAlarmsText: function (alarms) {
      var dev61850Alarms = const_61850.alarmstates;
      var _alarms = alarms.split(",");
      var str = "";
      for (var i = 0; i < _alarms.length; i++) {
        if (_alarms[i] == "true") {
          str += dev61850Alarms[i];
        }
      }
      if (str.length == 0) {
        str = "无";
      }
      return str;
    },
    // 查询机房名称
    queryStationName() {
      UserBattgroup()
        .then((res) => {
          res = res.data;
          let params = [];
          if (res.code) {
            params = res.data.map((item) => {
              return {
                label: item.stationName,
                value: item.fbsdeviceId,
              };
            });
          }
          let text =
            params.length > 0
              ? "全部 (共" + params.length + "种)"
              : "暂无可测机房站点";
          params.unshift({
            label: text,
            value: 0,
          });
          this.stationNameList = params;
        })
        .catch((err) => {});
    },
  }, //methods
};
</script>
<style lang="less" scoped>
</style>
src/views/dataTest/components/HomeListAio.vue
New file
@@ -0,0 +1,332 @@
<template>
  <content-box
    title="站点列表"
    titleLeft
    toggle
    @toggleChange="toggleChange"
    class="siteList context-box-w"
  >
    <flex-layout>
      <div slot="header">
        <el-select
          style="width: 98%; margin-left: 1%"
          size="small"
          v-model="filterText"
          filterable
          :filter-method="homeFilter"
          placeholder="请选择"
          clearable
          @change="filterChange"
        >
          <el-option
            v-for="item in homeList"
            :key="item.key"
            :label="item.label"
            :value="item.id"
          >
          </el-option>
        </el-select>
      </div>
      <my-el-tree
        :data="data"
        :default-expanded-keys="expandedKeys"
        :current-node-key="getCurrentKey"
        @node-click="nodeClick"
        @leaf-click="leafClick"
      ></my-el-tree>
    </flex-layout>
  </content-box>
</template>
<script>
import pinyinMatch from "pinyin-match";
import ContentBox from "@/components/ContentBox";
import MyElTree from "@/components/MyElTree";
import {
  getA059StationList,
} from '../js/historyAio';
import {
  getBattList
} from '@/assets/js/api';
import { getTreeDataByKey, getQueryString } from "@/assets/js/tools";
export default {
  components: {
    ContentBox,
    MyElTree,
  },
  data() {
    // 默认展开的节点
    let defaultExpandedKeys = [
      getQueryString("province"),
      getQueryString("city"),
      getQueryString("county"),
      getQueryString("home"),
    ];
    // 默认激活的电池组
    let currentNodeKey = getQueryString("batt") ? getQueryString("batt") : "";
    return {
      defaultExpandedKeys,
      currentNodeKey,
      data: [],
      expanded: [],
      currentKey: "",
      filterText: "",
      homeList: [],
      homeListCopy: [],
      batt: {},
      nibian: {
        show: false,
      },
    };
  },
  methods: {
    homeFilter(value) {
      if (value) {
        //value存在
        this.homeList = this.homeListCopy.filter((item) => {
          return pinyinMatch.match(item.label, value);
        });
      } else {
        //val为空时,还原数组
        this.homeList = this.homeListCopy;
      }
    },
    toggleChange() {
      this.$emit("toggleChange");
    },
    // 查询机房的信息
    searchStation() {
      getA059StationList()
        .then((res) => {
          res = res.data;
          // console.log(res, '8059');
          // 格式化数据
          this.formatData(res.data);
        });
    },
    formatData(data) {
      let result = [];
      let homeList = [];
      // 遍历数据构造树状
      data.forEach((item) => {
        let tmp = {};
        tmp.label =
          item.stationName1 +
          "-" +
          item.stationName2 +
          "-" +
          item.stationName5 +
          "-" +
          item.stationName3;
        tmp.key = item.deviceId + Math.random();
        tmp.id = item.deviceId;
        tmp.data = item;
        let index = this.checkValIsIn(tmp.label, homeList);
        if (index == -1) {
          homeList.push(tmp);
        }
        // 省
        let provice = this.addData(result, item.stationName1);
        // 市
        let city = this.addData(provice.children, item.stationName2, provice);
        // 区县
        let county = this.addData(city.children, item.stationName5, city);
        // 机房
        let home = this.addData(
          county.children,
          item.stationName3,
          county,
          item
        );
        // 添加空白位置占位
        home.children.push({
          id: home.id + Math.random(),
          label: "数据加载中...",
        });
      });
      // 设置树状列表
      this.data = result;
      // 设置搜索的下拉框
      this.homeList = homeList;
      this.homeListCopy = homeList.filter((item) => {
        return true;
      });
      // 设置默认展开的节点
      if (data.length > 0) {
        let item = data[0];
        this.expanded = [
          item.stationName1,
          item.stationName2,
          item.stationName5,
          item.stationName3,
        ];
      }
      let expandedNode = getTreeDataByKey(this.expandedKeys[0], result);
      if (expandedNode != -1) {
        this.nodeClick(expandedNode);
      }
    },
    addData(list, val, parent, data) {
      let item;
      let index = this.checkValIsIn(val, list);
      let parentId = parent ? parent.id + "-" : "";
      if (index == -1) {
        item = {
          id: parentId + val,
          label: val,
          children: [],
          data: data,
        };
        list.push(item);
      } else {
        item = list[index];
      }
      return item;
    },
    checkValIsIn(val, arr) {
      for (let i = 0; i < arr.length; i++) {
        if (arr[i].label == val) {
          return i;
        }
      }
      return -1;
    },
    nodeClick(data, node) {
      if (
        data.children &&
        data.children[0] &&
        data.children[0].label == "数据加载中..."
      ) {
        this.searchBattInfo(data, node);
      } else if (!node) {
        let batt = data.children[0];
        this.currentKey = batt.battGroupId;
        this.leafClick(batt);
      }
    },
    searchBattInfo(data, node) {
      // 加载等待
      if (node) {
        node.loading = true;
      }
      getBattList(data.data.stationId)
        .then((res) => {
          // 关闭等待
          if (node) {
            node.loading = false;
          }
          res = res.data;
          let result = [
            {
              id: Math.random(),
              label: "暂无电池组",
            },
          ];
          // 查询到结果
          if (res.code) {
            result = res.data.map((item) => {
              item.id = item.battGroupId;
              item.label = item.stationName4 + "-" + item.battGroupName;
              item.leaf = true;
              return item;
            });
          }
          data.children = result;
          // 根据node的值判断不是通过点击触发的
          if (!node) {
            let acIndex = 0;
            for (let i = 1; i < result.length; i++) {
              if (result[i].battGroupId == this.currentNodeKey) {
                acIndex = i;
                break;
              }
            }
            this.currentKey = result[acIndex].id;
            this.batt = result[acIndex];
            this.$emit("leaf-click", result[acIndex]);
          }
        })
        .catch((error) => {
          console.log(error);
        });
    },
    leafClick(data) {
      if (data.leaf) {
        this.batt = data;
        this.$emit("leaf-click", data);
      }
    },
    filterChange(id) {
      if (id) {
        let homeInfo = this.homeList.filter((item) => {
          return item.id == id;
        });
        // 获取到home的信息
        if (homeInfo.length > 0) {
          let item = homeInfo[0].data;
          this.defaultExpandedKeys = [
            item.stationName1,
            item.stationName2,
            item.stationName5,
            item.stationName3,
          ];
          let expandedNode = getTreeDataByKey(this.expandedKeys[0], this.data);
          if (expandedNode != -1) {
            this.nodeClick(expandedNode);
          }
        }
      }
    },
  },
  computed: {
    expandedKeys() {
      let parentKey = this.defaultExpandedKeys.join("-");
      if (parentKey.length > 0 && parentKey != "---") {
        return [parentKey];
      } else {
        let expanded = this.expanded.join("-");
        return [expanded];
      }
    },
    getCurrentKey() {
      return this.currentNodeKey ? this.currentNodeKey : this.currentKey;
    },
  },
  mounted() {
    // 查询电池组
    this.searchStation();
  },
};
</script>
<style scoped>
.context-box-w {
  width: 320px;
}
.box-tools {
  width: 200px;
  text-align: right;
  line-height: 32px;
}
.box-tools .iconfont {
  margin-left: 8px;
  font-size: 20px;
}
.box-tools .iconfont:hover {
  cursor: pointer;
  color: #cfcfcf;
}
.box-tools .iconfont:active {
  color: #ff0000;
}
</style>
src/views/dataTest/components/activateDialogContent.vue
New file
@@ -0,0 +1,1109 @@
<template>
  <div class="params-container">
    <el-form
      ref="ruleForm"
      size="mini"
      label-position="top"
      :model="params"
      :rules="rules"
      class="params-dialog"
    >
      <el-form-item label="电池组名称">
        <el-input v-model="otherParams.groupName" readonly></el-input>
      </el-form-item>
      <div class="table-layout">
        <div class="table-row">
          <div class="table-cell pr16">
            <el-form-item label="设备ID">
              <el-input v-model="otherParams.FBSDeviceId" readonly></el-input>
            </el-form-item>
          </div>
          <div class="table-cell pr16">
            <el-form-item label="电池组编号">
              <el-input
                v-model="otherParams.GroupIndexInFBSDevice"
                readonly
              ></el-input>
            </el-form-item>
          </div>
          <div class="table-cell">
            <el-form-item label="温度告警(℃)">
              <el-input v-model="params.CharHighTmp"></el-input>
            </el-form-item>
          </div>
        </div>
        <div class="table-row">
          <div class="table-cell pr16">
            <el-form-item label="单体节数" prop="MonCount">
              <el-input v-model="params.MonCount"></el-input>
            </el-form-item>
          </div>
          <div class="table-cell pr16">
            <el-form-item label="单体电压" prop="MonVol">
              <el-input v-model="params.MonVol"></el-input>
            </el-form-item>
          </div>
          <div class="table-cell">
            <el-form-item label="标称容量" prop="OffLineYH_Cycle">
              <el-input v-model="params.OffLineYH_Cycle"></el-input>
            </el-form-item>
          </div>
        </div>
      </div>
      <el-tabs
        v-model="acTabs"
        type="border-card"
        class="flex-layout noborder"
        @tab-click="tabClick"
      >
        <el-tab-pane
          label="充电"
          name="charge"
          :disabled="type !== 'charge' && type !== 'activate'"
        >
          <div class="table-layout">
            <div class="table-row">
              <div class="table-cell pr16">
                <el-form-item label="恒压电压(V)" prop="OnLineVol_Low">
                  <el-input
                    v-model="params.OnLineVol_Low"
                    @input="volInput"
                    @change="volChanged"
                  ></el-input>
                </el-form-item>
              </div>
              <div class="table-cell pr16">
                <el-form-item label="恒压电流(A)" prop="ChargeCurrSet">
                  <el-input v-model="params.ChargeCurrSet"></el-input>
                </el-form-item>
              </div>
              <div class="table-cell pr16">
                <el-form-item label="恒压时长(分钟)" prop="CharTimeLong">
                  <el-input v-model="params.CharTimeLong"></el-input>
                </el-form-item>
              </div>
              <!-- <div class="table-cell">
                                <el-form-item label="充电过温(℃)" prop="CharHighTmp">
                                    <el-input v-model="params.CharHighTmp"></el-input>
                                </el-form-item>
                            </div> -->
            </div>
            <div class="table-row">
              <div class="table-cell pr16">
                <el-form-item label="浮充电压(V)" prop="AutoTestStartVol">
                  <el-input v-model="params.AutoTestStartVol"></el-input>
                </el-form-item>
              </div>
              <div class="table-cell pr16">
                <el-form-item label="浮充电流(A)" prop="CharSotpCurr">
                  <el-input v-model="params.CharSotpCurr"></el-input>
                </el-form-item>
              </div>
              <div class="table-cell pr16">
                <el-form-item label="浮充时长(分钟)" prop="FloatCharTimeLong">
                  <el-input v-model="params.FloatCharTimeLong"></el-input>
                </el-form-item>
              </div>
              <!-- <div class="table-cell pr16">
                                <el-form-item label="充电容量(AH)" prop="CharCap">
                                    <el-input v-model.number="params.CharCap"></el-input>
                                </el-form-item>
                            </div> -->
            </div>
            <div class="table-row">
              <div class="table-cell pr16">
                <el-form-item label="单体上限(V)" prop="MonVolHightLimit">
                  <el-input v-model="params.MonVolHightLimit"></el-input>
                </el-form-item>
              </div>
              <div class="table-cell pr16">
                <el-form-item
                  label="单体上限数量(个)"
                  prop="MonVolHightLimitCount"
                >
                  <el-input v-model="params.MonVolHightLimitCount"></el-input>
                </el-form-item>
              </div>
              <div class="table-cell pr16">
                <el-form-item label="保护电压(V)" prop="DCVolHighLimit">
                  <el-input v-model="params.DCVolHighLimit"></el-input>
                </el-form-item>
              </div>
            </div>
            <div class="table-row">
              <div class="table-cell pr16">
                <el-form-item label="恒流阶段总数" prop="FlowOver_Count">
                  <el-select
                    v-model="params.FlowOver_Count"
                    placeholder="请选择"
                  >
                    <el-option
                      v-for="item in flowOverCount"
                      :key="item"
                      :label="item"
                      :value="item"
                    ></el-option>
                  </el-select>
                </el-form-item>
              </div>
              <div class="table-cell pr16">
                <el-form-item
                  label="恒流1阶段充电电流"
                  prop="FlowOver_CharCurr_1"
                >
                  <el-input v-model="params.FlowOver_CharCurr_1"></el-input>
                </el-form-item>
              </div>
              <div class="table-cell pr16">
                <el-form-item
                  label="恒流2阶段充电电流"
                  prop="FlowOver_CharCurr_2"
                >
                  <el-input
                    :disabled="params.FlowOver_Count < 2"
                    v-model="params.FlowOver_CharCurr_2"
                  ></el-input>
                </el-form-item>
              </div>
              <div class="table-cell">
                <el-form-item
                  label="恒流3阶段充电电流"
                  prop="FlowOver_CharCurr_3"
                >
                  <el-input
                    :disabled="params.FlowOver_Count < 3"
                    v-model="params.FlowOver_CharCurr_3"
                  ></el-input>
                </el-form-item>
              </div>
            </div>
            <div class="table-row">
              <div class="table-cell pr16"></div>
              <div class="table-cell pr16">
                <el-form-item
                  label="恒流1阶段充电时长"
                  prop="FlowOver_CharTime_1"
                >
                  <el-input v-model="params.FlowOver_CharTime_1"></el-input>
                </el-form-item>
              </div>
              <div class="table-cell pr16">
                <el-form-item
                  label="恒流2阶段充电时长"
                  prop="FlowOver_CharTime_2"
                >
                  <el-input
                    :disabled="params.FlowOver_Count < 2"
                    v-model="params.FlowOver_CharTime_2"
                  ></el-input>
                </el-form-item>
              </div>
              <div class="table-cell">
                <el-form-item
                  label="恒流3阶段充电时长"
                  prop="FlowOver_CharTime_3"
                >
                  <el-input
                    :disabled="params.FlowOver_Count < 3"
                    v-model="params.FlowOver_CharTime_3"
                  ></el-input>
                </el-form-item>
              </div>
            </div>
          </div>
        </el-tab-pane>
        <el-tab-pane
          label="放电"
          name="discharge"
          :disabled="type !== 'discharge' && type !== 'activate'"
        >
          <div class="table-layout">
            <div class="table-row">
              <div class="table-cell pr16">
                <el-form-item label="放电模式">
                  <!-- 恒电流 功率 电阻 -->
                  <el-select
                    v-model="params.OnlineLowAction"
                    placeholder="请选择"
                  >
                    <el-option
                      v-for="item in testType"
                      :key="item.value"
                      :label="item.label"
                      :value="item.value"
                    ></el-option>
                  </el-select>
                </el-form-item>
              </div>
              <div class="table-cell pr16">
                <el-form-item label="预放电流(A)" prop="DisCurr">
                  <el-input
                    v-model="params.DisCurr"
                    :disabled="params.OnlineLowAction != 0"
                  ></el-input>
                </el-form-item>
              </div>
              <div class="table-cell pr16">
                <el-form-item label="预放容量(AH)" prop="DisCap">
                  <el-input v-model="params.DisCap"></el-input>
                </el-form-item>
              </div>
              <div class="table-cell">
                <el-form-item label="小时率" prop="HourRate">
                  <el-select v-model="params.HourRate" placeholder="请选择">
                    <el-option
                      v-for="item in HourRate"
                      :key="item"
                      :label="item"
                      :value="item"
                    ></el-option>
                  </el-select>
                </el-form-item>
              </div>
            </div>
            <div class="table-row">
              <div class="table-cell pr16">
                <el-form-item label="预放阻值(mΩ)" prop="DisPreRes">
                  <el-input
                    v-model="params.DisPreRes"
                    :disabled="params.OnlineLowAction != 2"
                    >i</el-input
                  >
                </el-form-item>
              </div>
              <div class="table-cell pr16">
                <el-form-item label="预放功率(KW)" prop="DisPower">
                  <el-input
                    v-model="params.DisPower"
                    :disabled="params.OnlineLowAction != 1"
                  ></el-input>
                </el-form-item>
              </div>
              <div class="table-cell pr16">
                <el-form-item label="预放时间(分钟)" prop="DisTime">
                  <el-input v-model="params.DisTime"></el-input>
                </el-form-item>
              </div>
              <!-- <div class="table-cell">
                                <el-form-item label="放电过温" prop="MonomerTmp_High">
                                    <el-input v-model.number="params.MonomerTmp_High"></el-input>
                                </el-form-item>
                            </div> -->
              <div class="table-cell">
                <el-form-item label="组端下限(V)" prop="GroupVol_Low">
                  <el-input v-model="params.GroupVol_Low"></el-input>
                </el-form-item>
              </div>
            </div>
            <div class="table-row">
              <div class="table-cell pr16">
                <el-form-item label="单体下限(V)" prop="MonomerVol_Low">
                  <el-input v-model="params.MonomerVol_Low"></el-input>
                </el-form-item>
              </div>
              <div class="table-cell pr16">
                <el-form-item label="下限个数(个)" prop="MonomerLowCount">
                  <el-input v-model="params.MonomerLowCount"></el-input>
                </el-form-item>
              </div>
            </div>
          </div>
        </el-tab-pane>
        <el-tab-pane
          label="活化"
          name="activate"
          :disabled="type !== 'activate'"
        >
          <div class="table-layout">
            <div class="table-row">
              <div class="table-cell pr16">
                <el-form-item label="活化开始">
                  <!-- 放电 充电 -->
                  <el-select
                    v-model="params.OffLineYHOnceCycle"
                    placeholder="请选择"
                  >
                    <el-option
                      v-for="item in cycleStart"
                      :key="item.value"
                      :label="item.label"
                      :value="item.value"
                    ></el-option>
                  </el-select>
                </el-form-item>
              </div>
            </div>
            <div class="table-row">
              <div class="table-cell pr16">
                <el-form-item label="循环次数(次)" prop="OffLineYHTimes">
                  <el-input v-model="params.OffLineYHTimes"></el-input>
                </el-form-item>
              </div>
              <div class="table-cell pr16">
                <el-form-item label="充完静置(分钟)" prop="DisWaitTime">
                  <el-input v-model="params.DisWaitTime"></el-input>
                </el-form-item>
              </div>
              <div class="table-cell">
                <el-form-item label="放完静置(分钟)" prop="CharWaitTime">
                  <el-input v-model="params.CharWaitTime"></el-input>
                </el-form-item>
              </div>
            </div>
          </div>
        </el-tab-pane>
      </el-tabs>
      <div class="form-footer">
        <three-btn :disabled="!startTestFlag" @click="startTestCheck"
          >启动{{ typeStr }}</three-btn
        >
        <three-btn @click="getParams(true)">读取</three-btn>
        <three-btn :disabled="!setTestFlag" @click="submitFrom">设定</three-btn>
      </div>
    </el-form>
  </div>
</template>
<script>
import { testVal } from "@/assets/js/tools";
import { const_aio } from "@/assets/js/const";
import config from "@/assets/js/config";
// import checkFace from "@/components/checkFace";
let rules = const_aio.dischargeRules;
export default {
  name: "dischargeParams",
  components: {
    // checkFace
  },
  props: {
    batt: {
      type: Object,
      default() {
        return {};
      },
    },
    type: {
      type: String,
      default: "charge",
    },
  },
  data() {
    let cmd = const_aio.cmd;
    let testType = const_aio.testType;
    let cycleStart = const_aio.cycleStart;
    let HourRate = const_aio.HourRate;
    let batt = this.batt;
    // 修改组端下限的取值范围
    // rules.GroupVol_Low.min = (batt.MonCount*batt.MonVolStd*0.875).toHold(1);
    // rules.GroupVol_Low.max = (batt.MonCount*batt.MonVolStd*1.125).toHold(1);
    // rules.GroupVol_Low.msg = "取值范围"+rules.GroupVol_Low.min+"~"+rules.GroupVol_Low.max+"(保留一位小数)";
    // 修改电池单体下限的取值范围
    // rules.MonomerVol_Low.min = (batt.MonVolStd*0.9).toHold(1);
    // rules.MonomerVol_Low.max = (batt.MonVolStd*1.2).toHold(1);
    // rules.MonomerVol_Low.msg = "取值范围"+rules.MonomerVol_Low.min+"~"+rules.MonomerVol_Low.max+"(保留一位小数)";
    // 单体下限数量
    rules.MonomerLowCount.max = batt.MonCount;
    rules.MonomerLowCount.msg =
      "取值范围" + rules.MonomerLowCount.min + "~" + rules.MonomerLowCount.max;
    // 单体上限数量
    rules.MonVolHightLimitCount.max = batt.MonCount;
    rules.MonVolHightLimitCount.msg =
      "取值范围" +
      rules.MonVolHightLimitCount.min +
      "~" +
      rules.MonVolHightLimitCount.max;
    return {
      setFaceShow: false,
      startFaceShow: false,
      flowOverCount: const_aio.flowOverCount,
      cmd: cmd, // 操作命令
      startTestFlag: false, // 启动测试的状态
      setTestFlag: false, // 设置参数的状态
      testType: testType, // 测试类型
      cycleStart: cycleStart, // 活化起点
      HourRate: HourRate, // 放电小时率
      acTabs: "activate",
      params: {
        AutoTestStartVol: 0, //浮充电压(V)
        BattGroupNum: 0, //电池组编号
        CharCap: 0, //充电容量(AH)(不显示)
        CharHighTmp: 0, //充电过温
        CharSotpCurr: 0, //截止电流
        CharTimeLong: 0, //充电时长
        CharWaitTime: 0, //放完静置
        ChargeCurrSet: 0, //充电电流
        DCVolHighLimit: 0, //组端上限
        DisCap: 0, //放电容量
        DisCurr: 0, //放电电流
        DisPower: 0, //预放功率
        DisPreRes: 0, //放电阻值
        DisTime: 0, //放电时长
        DisWaitTime: 0, //充完静置
        FloatCharTimeLong: 0, //浮充时长
        GroupVol_Low: 0, //组端下限
        HourRate: 0, //放电小时率
        MonCount: 0, //单体数量
        MonVol: 0, //单体电压
        MonVolHightLimit: 0, //单体上限
        MonVolHightLimitCount: 0, //单体上限数量
        MonomerLowCount: 0, //单体下限数量
        MonomerTmp_High: 0, //放电过温
        MonomerVol_Low: 0, //单体下限
        OffLineYHOnceCycle: 1, //活化起点
        OffLineYHTimes: 1, //活化次数
        OffLineYH_Cycle: 0, //电池组标称容量
        FlowOver_Count: 1, //恒流总阶段数
        FlowOver_CharCurr_1: 0, //恒流1阶段充电电流
        FlowOver_CharCurr_2: 0, //恒流2阶段充电电流
        FlowOver_CharCurr_3: 0, //恒流3阶段充电电流
        FlowOver_CharTime_1: 0, //恒流3阶段充电时长
        FlowOver_CharTime_2: 0, //恒流3阶段充电时长
        FlowOver_CharTime_3: 0, //恒流3阶段充电时长
        OffLineYHstarttime: "2000-01-01 00:00:00", //养护开始时间
        OnLineVol_Low: 0, //充电电压
        OnlineLowAction: 0, //测试类型 0:恒电流,1:恒功率,2:恒电阻
        TestCmd: 0, //备用
        dev_id: 0, //设备id
        dev_ip: "127.0.0.0", //设备ip
        op_cmd: cmd.setParams, //指令
      },
      ranges: {
        GroupVol_Low: {
          name: "组端电压下限",
          unit: "V",
          min: rules.GroupVol_Low.min,
          max: rules.GroupVol_Low.max,
        },
        MonomerVol_Low: {
          name: "单体电压下限",
          unit: "V",
          min: rules.MonomerVol_Low.min,
          max: rules.MonomerVol_Low.max,
        },
      },
      rules: {
        AutoTestStartVol: [
          {
            validator(rule, value, callback) {
              testVal(rule, value, callback, rules.AutoTestStartVol);
            },
            trigger: "change",
          },
        ],
        // CharCap: [{
        //     validator(rule, value, callback) {
        //         testVal(rule, value, callback, rules.CharCap)
        //     },
        //     trigger: 'change'
        // }],
        CharHighTmp: [
          {
            validator(rule, value, callback) {
              testVal(rule, value, callback, rules.CharHighTmp);
            },
            trigger: "change",
          },
        ],
        CharSotpCurr: [
          {
            validator(rule, value, callback) {
              testVal(rule, value, callback, rules.CharSotpCurr);
            },
            trigger: "change",
          },
        ],
        CharWaitTime: [
          {
            validator(rule, value, callback) {
              testVal(rule, value, callback, rules.CharWaitTime);
            },
            trigger: "change",
          },
        ],
        ChargeCurrSet: [
          {
            validator(rule, value, callback) {
              testVal(rule, value, callback, rules.ChargeCurrSet);
            },
            trigger: "change",
          },
        ],
        DCVolHighLimit: [
          {
            validator(rule, value, callback) {
              testVal(rule, value, callback, rules.DCVolHighLimit);
            },
            trigger: "change",
          },
        ],
        DisCap: [
          {
            validator(rule, value, callback) {
              testVal(rule, value, callback, rules.DisCap);
            },
            trigger: "change",
          },
        ],
        DisCurr: [
          {
            validator(rule, value, callback) {
              testVal(rule, value, callback, rules.DisCurr);
            },
            trigger: "change",
          },
        ],
        DisPower: [
          {
            validator(rule, value, callback) {
              testVal(rule, value, callback, rules.DisPower);
            },
            trigger: "change",
          },
        ],
        DisPreRes: [
          {
            validator(rule, value, callback) {
              testVal(rule, value, callback, rules.DisPreRes);
            },
            trigger: "change",
          },
        ],
        DisTime: [
          {
            validator(rule, value, callback) {
              testVal(rule, value, callback, rules.DisTime);
            },
            trigger: "change",
          },
        ],
        DisWaitTime: [
          {
            validator(rule, value, callback) {
              testVal(rule, value, callback, rules.DisWaitTime);
            },
            trigger: "change",
          },
        ],
        // FloatCharTimeLong: [{
        //     validator(rule, value, callback) {
        //         testVal(rule, value, callback, rules.FloatCharTimeLong)
        //     },
        //     trigger: 'change'
        // }],
        GroupVol_Low: [
          {
            validator(rule, value, callback) {
              testVal(rule, value, callback, rules.GroupVol_Low);
            },
            trigger: "change",
          },
        ],
        MonVolHightLimit: [
          {
            validator(rule, value, callback) {
              testVal(rule, value, callback, rules.MonVolHightLimit);
            },
            trigger: "change",
          },
        ],
        MonVolHightLimitCount: [
          {
            validator(rule, value, callback) {
              testVal(rule, value, callback, rules.MonVolHightLimitCount);
            },
            trigger: "change",
          },
        ],
        MonomerLowCount: [
          {
            validator(rule, value, callback) {
              testVal(rule, value, callback, rules.MonomerLowCount);
            },
            trigger: "change",
          },
        ],
        // MonomerTmp_High: [{
        //     validator(rule, value, callback) {
        //         testVal(rule, value, callback, rules.MonomerTmp_High)
        //     },
        //     trigger: 'change'
        // }],
        MonomerVol_Low: [
          {
            validator(rule, value, callback) {
              testVal(rule, value, callback, rules.MonomerVol_Low);
            },
            trigger: "change",
          },
        ],
        OffLineYHTimes: [
          {
            validator(rule, value, callback) {
              testVal(rule, value, callback, rules.OffLineYHTimes);
            },
            trigger: "change",
          },
        ],
        OnLineVol_Low: [
          {
            validator(rule, value, callback) {
              testVal(rule, value, callback, rules.OnLineVol_Low);
            },
            trigger: "change",
          },
        ],
        MonCount: [
          {
            validator(rule, value, callback) {
              testVal(rule, value, callback, rules.MonCount);
            },
            trigger: "change",
          },
        ],
        MonVol: [
          {
            validator(rule, value, callback) {
              testVal(rule, value, callback, rules.MonVol);
            },
            trigger: "change",
          },
        ],
        OffLineYH_Cycle: [
          {
            validator(rule, value, callback) {
              testVal(rule, value, callback, rules.OffLineYH_Cycle);
            },
            trigger: "change",
          },
        ],
      },
    };
  },
  watch: {
    "params.MonCount"(n) {
      this.updateRulesGroupVol_low(n, this.params.MonVol);
    },
    "params.MonVol"(n) {
      this.updateRulesGroupVol_low(this.params.MonCount, n);
    },
  },
  methods: {
    initParams() {
      // 初始化参数
      this.params = {
        AutoTestStartVol: 0, //浮充电压(V)
        BattGroupNum: 0, //电池组编号
        CharCap: 0, //充电容量(AH)
        CharHighTmp: 0, //充电过温
        CharSotpCurr: 0, //截止电流
        CharTimeLong: 0, //充电时长
        CharWaitTime: 0, //放完静置
        ChargeCurrSet: 0, //充电电流
        DCVolHighLimit: 0, //组端上限
        DisCap: 0, //放电容量
        DisCurr: 0, //放电电流
        DisPower: 0, //预放功率
        DisPreRes: 0, //放电阻值
        DisTime: 0, //放电时长
        DisWaitTime: 0, //充完静置
        FloatCharTimeLong: 0, //浮充时长
        GroupVol_Low: 0, //组端下限
        HourRate: 0, //放电小时率
        MonCount: 0, //单体数量
        MonVol: 0, //单体电压
        MonVolHightLimit: 0, //单体上限
        MonVolHightLimitCount: 0, //单体上限数量
        MonomerLowCount: 0, //单体下限数量
        MonomerTmp_High: 0, //放电过温
        MonomerVol_Low: 0, //单体下限
        OffLineYHOnceCycle: 1, //活化起点
        OffLineYHTimes: 1, //活化次数
        OffLineYH_Cycle: 0, //电池组标称容量
        FlowOver_Count: 1, //恒流总阶段数
        FlowOver_CharCurr_1: 0, //恒流1阶段充电电流
        FlowOver_CharCurr_2: 0, //恒流2阶段充电电流
        FlowOver_CharCurr_3: 0, //恒流3阶段充电电流
        FlowOver_CharTime_1: 0, //恒流3阶段充电时长
        FlowOver_CharTime_2: 0, //恒流3阶段充电时长
        FlowOver_CharTime_3: 0, //恒流3阶段充电时长
        OffLineYHstarttime: "2000-01-01 00:00:00", //养护开始时间
        OnLineVol_Low: 0, //充电电压
        OnlineLowAction: 0, //测试类型 0:恒电流,1:恒功率,2:恒电阻
        TestCmd: 0, //备用
        dev_id: 0, //设备id
        dev_ip: "127.0.0.0", //设备ip
        op_cmd: const_aio.cmd.setParams, //指令
      };
    },
    volInput(v) {
      console.log("volchange", v);
      // 修改浮充的取值范围
      rules.AutoTestStartVol.max = v * 1;
      rules.AutoTestStartVol.msg =
        "取值范围" +
        rules.AutoTestStartVol.min +
        "~" +
        rules.AutoTestStartVol.max;
      this.rules.AutoTestStartVol = [
        {
          validator(rule, value, callback) {
            testVal(rule, value, callback, rules.AutoTestStartVol);
          },
          trigger: "change",
        },
      ];
    },
    volChanged(v) {
      // 如果保护电压比恒压电压高 就把保护电压改为恒压电压
      if (v == v * 1 && this.params.DCVolHighLimit > v) {
        this.params.DCVolHighLimit = v * 1;
      }
    },
    // 设置组端下限范围
    updateRulesGroupVol_low(moncount, monvolstd) {
      // 修改组端下限的取值范围
      rules.GroupVol_Low.min = (moncount * monvolstd * 0.875).toHold(1);
      rules.GroupVol_Low.max = (moncount * monvolstd * 1.125).toHold(1);
      rules.GroupVol_Low.msg =
        "取值范围" +
        rules.GroupVol_Low.min +
        "~" +
        rules.GroupVol_Low.max +
        "(保留一位小数)";
      this.rules.GroupVol_Low = [
        {
          validator(rule, value, callback) {
            testVal(rule, value, callback, rules.GroupVol_Low);
          },
          trigger: "change",
        },
      ];
    },
    tabClick(tab) {
      this.acTabs = tab.name;
      // // 根据tab更新电路图
      // if(this.acTabs === "eleLine") {
      //     this.diagram.update = true;
      // }else {
      //     this.diagram.update = false;
      // }
      // // 更新图表
      // this.setChart();
      // // 重置图表的大小
      // this.$nextTick(() => {
      //     this.resize();
      //     // 设置表格的数据
      //     if(this.acTabs == "tblData") {
      //         this.table.datas = tblData;
      //     }
      // });
    },
    // 获取参数
    getParams(showLoad) {
      // 定义等待框
      let loading;
      if (showLoad) {
        loading = this.$layer.loading(1);
      }
      // 启动按钮不可点击
      this.startTestFlag = false;
      // 查询后台
      this.$apis.aio.realtime
        .getParams({
          dev_id: this.batt.FBSDeviceId,
          op_cmd: const_aio.cmd.getParams,
        })
        .then((res) => {
          let rs = JSON.parse(res.data.result);
          // console.log('00000', rs, '-------=====');
          // debugger;
          if (rs.code == 1) {
            let fsparam = rs.data[0];
            // 遍历参数属性并赋值
            for (let key in this.params) {
              this.params[key] = fsparam[key];
            }
            // 设置的命令和dev_id
            this.params.op_cmd = this.cmd.setParams;
            this.$layer.msg("读取成功!");
            // 设置按钮可点击
            this.setTestFlag = true;
          } else {
            // 初始化参数
            // this.initParams();
            // 设置按钮不可点击
            // TODO
            this.setTestFlag = false;
            this.$layer.msg("读取失败!");
          }
          // 关闭等待框
          this.$layer.close(loading);
        })
        .catch((error) => {
          console.log(error);
          // 初始化参数
          this.initParams();
          // 设置按钮不可点击
          this.setTestFlag = false;
          // 关闭等待框
          this.$layer.close(loading);
          this.$layer.msg("读取失败,读取请求异常!");
        });
    },
    // 提交表单设置参数
    submitFrom() {
      this.$refs.ruleForm.validate((valid) => {
        // 校验通过
        if (valid) {
          // 设置参数
          this.setParamsCheck();
        } else {
          this.$layer.msg("存在校验未通过的数据!");
          return false;
        }
      });
    },
    setParamsCheck() {
      if (config.dischargeByFace.value) {
        this.setFaceShow = true;
      } else {
        this.setParams(true);
      }
    },
    // 设置参数
    setParams() {
      // 等待框
      let loading = this.$layer.loading(1);
      // this.params.dev_id = 618500001;
      // 请求后台
      this.$apis.aio.realtime
        .setParams(this.params)
        .then((res) => {
          let rs = JSON.parse(res.data.result);
          if (rs.code == 1) {
            // 启动按钮可点击
            this.startTestFlag = true;
            // 提示信息
            this.$layer.msg("设置成功");
          } else {
            // 启动按钮不可点击
            this.startTestFlag = false;
            // 提示信息
            this.$layer.msg("设置失败!");
          }
          // 关闭等待框
          this.$layer.close(loading);
        })
        .catch((error) => {
          console.log(error);
          // 关闭等待框
          this.$layer.close(loading);
          // 启动按钮不可点击
          this.startTestFlag = false;
          // 提示信息
          this.$layer.msg("设置失败,设置请求异常!");
        });
    },
    startTestCheck() {
      if (config.dischargeByFace.value) {
        this.startFaceShow = true;
      } else {
        this.confirmStartTest();
      }
    },
    // 确认框
    confirmStartTest() {
      this.$layer.prompt(
        {
          title: "输入启动口令,并确认",
          formType: 2,
          area: ["300px", "180px"],
        },
        (pass, index) => {
          // 请求后台校验密码
          this.$apis.login
            .checkUserPwd(pass)
            .then((res) => {
              let rs = JSON.parse(res.data.result);
              if (rs.code == 1) {
                // 关闭弹出框
                this.$layer.close(index);
                this.$layer.msg("密码检测通过,启动测试");
                // 启动测试
                this.startTest();
              } else {
                this.$layer.msg("启动口令错误!");
              }
            })
            .catch((error) => {
              console.log(error);
              this.$layer.msg("网络请求异常");
            });
        }
      );
    },
    // 启动
    startTest() {
      // 等待框
      let loading = this.$layer.loading(1);
      let num = 0;
      switch (this.type) {
        case "charge":
          num = this.cmd.startCharge;
          break;
        case "discharge":
          num = this.cmd.startDisCharge;
          break;
        case "activate":
          num = this.cmd.startActivate;
          break;
      }
      // 请求后台
      this.$apis.aio.realtime
        .sendCmd({
          op_cmd: num,
          dev_id: this.batt.FBSDeviceId,
        })
        .then((res) => {
          let rs = JSON.parse(res.data.result);
          if (rs.code == 1) {
            // 提示信息
            this.$layer.msg("启动测试成功");
            this.$emit("startok");
          } else {
            // 提示信息
            this.$layer.msg("启动测试失败!");
          }
          // 关闭等待框
          this.$layer.close(loading);
        })
        .catch((error) => {
          console.log(error);
          // 关闭等待框
          this.$layer.close(loading);
          // 提示信息
          this.$layer.msg("启动测试失败,启动测试请求异常!");
        });
    },
    checkValIsInObjects(val, objects) {
      let rs = false;
      for (let i = 0; i < objects.length; i++) {
        let obj = objects[i];
        if (obj.value === val) {
          rs = true;
          break;
        }
      }
      return false;
    },
    setFaceSuccess() {
      this.setFaceShow = false;
      this.setParams();
    },
    startFaceSuccess() {
      this.startFaceShow = false;
      this.startTest();
    },
  },
  computed: {
    otherParams() {
      let batt = this.batt;
      let groupInfo =
        "单体数量:" +
        this.batt.MonCount +
        ";电压(V):" +
        this.batt.MonVolStd +
        ";容量(AH):" +
        this.batt.MonCapStd;
      return {
        groupName: batt.StationName + "-" + batt.BattGroupName,
        FBSDeviceId: batt.FBSDeviceId,
        groupInfo: groupInfo,
        GroupIndexInFBSDevice: this.batt.GroupIndexInFBSDevice + 1,
      };
    },
    rangeLabel() {
      let ranges = this.ranges;
      let result = {};
      for (let key in ranges) {
        let item = ranges[key];
        result[key] =
          item.name + "(" + item.min + "~" + item.max + item.unit + ")";
      }
      return result;
    },
    typeStr() {
      let res = "";
      switch (this.type) {
        case "charge":
          res = "充电";
          break;
        case "discharge":
          res = "放电";
          break;
        case "activate":
          res = "活化";
          break;
      }
      return res;
    },
  },
  mounted() {
    console.log("mounted");
    this.acTabs = this.type;
    // 获取数据
    this.getParams(true);
  },
};
</script>
<style scoped>
.form-footer {
  margin-top: 16px;
  margin-bottom: 16px;
  text-align: right;
}
.form-footer .three-btn {
  margin-left: 12px;
}
.params-container {
  padding: 0.4rem;
  background-color: #ececec;
}
>>> .is-disabled {
  cursor: not-allowed;
}
>>> .el-tab-pane {
  padding-top: 0;
  padding-bottom: 16px;
}
>>> .el-tabs--border-card > .el-tabs__header {
  background: #4ba1fa;
  border-color: #4ba1fa;
}
>>> .el-tabs--border-card > .el-tabs__header .el-tabs__item {
  color: #042271;
}
>>> .el-tabs--border-card
  > .el-tabs__header
  .el-tabs__item:not(.is-disabled):hover {
  color: #042271;
}
>>> .el-tabs--border-card > .el-tabs__header .el-tabs__item.is-active {
  background-color: #042271;
  border-color: #042271;
  color: #fff;
}
>>> .el-tabs {
  margin-top: 10px;
}
</style>
src/views/dataTest/components/endoscopeVideo.vue
New file
@@ -0,0 +1,89 @@
<template>
  <div class="endoscope-video">
    <rtmp-video :url="url"></rtmp-video>
  </div>
</template>
<script>
import RtmpVideo from "@/components/rtmpVideo";
export default {
  name: "endoscopeVideo",
  components: { RtmpVideo },
  data() {
    return {
      url: "",
      mac: "",
    };
  },
  methods: {
    getList() {
      this.$axios({
        method: "get",
        url: "http://121.36.27.55:51389/A059Web/webService/getList",
        withCredentials: false,
      })
        .then((res) => {
          let rs = res.data;
          if (rs.code == 200 && rs.data.length) {
            let data = rs.data;
            let mac = data[0].mac;
            let url = data[0].rtmp;
            this.start(mac, url);
          }
        })
        .catch((error) => {
          console.log(error);
        });
    },
    start(mac, url) {
      this.$axios({
        method: "post",
        url: "http://121.36.27.55:51389/A059Web/webService/startTest",
        withCredentials: false,
        params: {
          mac: mac,
        },
      })
        .then((res) => {
          let rs = res.data;
          if (rs.code == 200) {
            this.url = url;
            this.mac = mac;
          }
        })
        .catch((error) => {
          console.log(error);
        });
    },
    stop() {
      let mac = this.mac;
      if (!mac) {
        return;
      }
      this.$axios({
        method: "post",
        url: "http://121.36.27.55:51389/A059Web/webService/stopTest",
        withCredentials: false,
        params: {
          mac: mac,
        },
      })
        .then((res) => {
          console.log("内窥镜MAC:" + mac + "停止推送视频");
        })
        .catch((error) => {
          console.log(error);
        });
    },
  },
  mounted() {
    this.getList();
  },
  beforeDestroy() {
    this.stop();
  },
};
</script>
<style scoped>
</style>
src/views/dataTest/historyAio.vue
New file
@@ -0,0 +1,2700 @@
<template>
  <flex-layout
    direction="row"
    class="page-history-aio"
    :no-bg="true"
    :loading="loading"
  >
    <home-list-aio
      slot="header"
      @toggleChange="toggleChange"
      @leaf-click="leafClick"
    ></home-list-aio>
    <content-box
      style="margin-left: 4px; margin-right: 4px"
      :title="battFullName"
    >
      <div slot="box-tools" class="box-tools">
        <el-tooltip
          class="item"
          effect="dark"
          content="实时数据"
          placement="bottom"
        >
          <i class="iconfont el-icon-jinru" @click="syncPage"></i>
        </el-tooltip>
      </div>
      <div slot="box-tools" class="box-tools" style="right: 36px">
        <el-tooltip
          class="item"
          effect="dark"
          content="数据导出"
          placement="bottom"
        >
          <i
            class="iconfont el-icon-daochu"
            @click="exportExcel"
            style="font-size: 24px"
          ></i>
        </el-tooltip>
      </div>
      <div slot="box-tools" class="box-tools" style="right: 65px">
        <el-tooltip
          class="item"
          effect="dark"
          content="数据导入"
          placement="bottom"
        >
          <i
            class="iconfont el-icon-daochu import"
            @click="importDialogShow"
            style="font-size: 24px"
          ></i>
        </el-tooltip>
      </div>
      <div slot="box-tools" class="box-tools" style="right: 95px">
        <el-tooltip
          class="item"
          v-show="removeable"
          effect="dark"
          content="数据表格"
          placement="bottom"
        >
          <i
            class="iconfont el-icon-xinxi import"
            @click="table.show = true"
            style="font-size: 24px"
          ></i>
        </el-tooltip>
      </div>
      <!-- <div slot="box-tools" class="box-tools" style="right: 125px;">
                <el-tooltip class="item" effect="dark" content="数据对比" placement="bottom">
                    <i class="iconfont el-icon-jiankong" @click="toShowComparison"></i>
                </el-tooltip>
            </div> -->
      <flex-layout :no-bg="true">
        <div class="content-header" slot="header">
          <el-form class="form-header" ref="form" label-width="80px">
            <el-row :gutter="layout.gutter">
              <el-col :span="layout.span">
                <el-form-item label="总电压">
                  <el-input
                    v-model="top.group"
                    placeholder=""
                    size="small"
                    :disabled="true"
                    style="min-width: 12rem"
                  ></el-input>
                </el-form-item>
              </el-col>
              <el-col :span="layout.span">
                <el-form-item label="电池电流">
                  <el-input
                    v-model="top.curr"
                    placeholder=""
                    size="small"
                    :disabled="true"
                  ></el-input>
                </el-form-item>
              </el-col>
              <el-col :span="layout.span">
                <el-form-item label="电池状态">
                  <el-input
                    v-model="formateBattState"
                    placeholder=""
                    size="small"
                    :disabled="true"
                  ></el-input>
                </el-form-item>
              </el-col>
              <el-col :span="layout.span">
                <el-form-item label="测试时长">
                  <el-input
                    v-model="top.test_long"
                    placeholder=""
                    size="small"
                    :disabled="true"
                  ></el-input>
                </el-form-item>
              </el-col>
              <el-col :span="layout.span">
                <el-form-item label="测试日期">
                  <el-cascader
                    v-model="test_record.value"
                    :options="test_record.list"
                    size="small"
                    placeholder="请选择测试日期"
                    style="width: 100%; min-width: 14rem"
                    @change="testRecordChange"
                  >
                    <template slot-scope="{ node, data }">
                      <span>{{ data.label }}</span>
                      <span v-if="!node.isLeaf">
                        ({{ data.children.length }})
                      </span>
                    </template>
                  </el-cascader>
                </el-form-item>
              </el-col>
              <el-col :span="layout.span">
                <el-form-item label="测试容量">
                  <el-input
                    v-model="top.test_cap"
                    placeholder=""
                    size="small"
                    :disabled="true"
                  ></el-input>
                </el-form-item>
              </el-col>
              <el-col :span="layout.span">
                <el-form-item label="剩余容量">
                  <el-input
                    v-model="top.re_cap"
                    placeholder=""
                    size="small"
                    :disabled="true"
                  ></el-input>
                </el-form-item>
              </el-col>
              <el-col :span="layout.span">
                <div class="text-right" v-if="removeable">
                  <el-button type="primary" size="small" @click="removeTestData"
                    >删除记录</el-button
                  >
                </div>
              </el-col>
            </el-row>
          </el-form>
        </div>
        <div class="page-content">
          <div class="flex-box-list">
            <div class="flex-box" style="margin-bottom: 8px">
              <chart-wrapper :title="groupVolTitle">
                <line-chart ref="groupVol" id="groupVol" unit="V"></line-chart>
              </chart-wrapper>
            </div>
            <div class="flex-box" style="margin-bottom: 8px">
              <chart-wrapper :title="monBarTitle">
                <!-- <div class="chart-tools-wrapper">
                                    <el-select v-model="chartType" size="mini" @change="changeChartType">
                                        <el-option v-for="item in chartTypes" :key="item.value" :label="item.label"
                                            :value="item.value"></el-option>
                                    </el-select>
                                </div> -->
                <bar-chart
                  ref="monBar"
                  id="monBar"
                  :show-label="false"
                ></bar-chart>
              </chart-wrapper>
            </div>
          </div>
          <div class="flex-box-list">
            <div class="flex-box" style="margin-top: 8px">
              <chart-wrapper title="电池电流折线图(A)">
                <line-chart
                  ref="groupCurr"
                  id="groupCurr"
                  unit="A"
                  start-zero
                ></line-chart>
              </chart-wrapper>
            </div>
            <div class="flex-box" style="margin-top: 8px">
              <chart-wrapper :title="monInfo.title">
                <line-chart
                  ref="monInfo"
                  id="monInfo"
                  :unit="monInfo.unit"
                ></line-chart>
              </chart-wrapper>
            </div>
          </div>
        </div>
        <div class="content-footer" slot="footer">
          <div class="slider-container">
            <el-slider
              v-model="slider"
              size="small"
              :format-tooltip="formatTooltip"
              @input="sliderInput"
            >
            </el-slider>
          </div>
        </div>
      </flex-layout>
    </content-box>
    <!-- 导入 -->
    <el-dialog
      title="一体机数据导入"
      class="dialog-import"
      :visible.sync="importData.show"
      width="800"
    >
      <div class="posR inProgress">
        <div class="title">
          <el-tag type="warning" effect="dark">当前处理中的记录</el-tag>
        </div>
        <el-row
          v-if="importData.inProgress.length"
          :gutter="layout.importGutter"
        >
          <el-col
            :span="layout.importSpan"
            v-for="(item, idx) in importData.inProgress"
            :key="'import_' + idx"
          >
            <div
              class="tag"
              :class="{ success: item.state == 2, error: item.state == -1 }"
              :style="{ '--percent': item.percent }"
            >
              {{ item.file_name }}: {{ item.stateTxt }}
              <div
                :class="[
                  'progress-bar',
                  {
                    'progress__bar--yellow': item.percent < 30,
                    'progress__bar--blue':
                      item.percent >= 30 && item.percent < 60,
                    'progress__bar--green':
                      item.percent >= 60 && item.percent < 100,
                    'progress--complete':
                      item.percent >= 100 || item.state != 1,
                  },
                ]"
                :type="item.type"
              >
                <span>{{ item.percent }}%</span>
              </div>
            </div>
          </el-col>
        </el-row>
        <div class="empty" v-else></div>
      </div>
      <div class="clearfix" v-if="importData.done">
        <div class="title files">
          <el-tag type="" effect="dark">一体机文件列表</el-tag>
          <el-pagination
            size="mini"
            :current-page="page.pageCurr"
            :page-size="page.pageSize"
            layout="total, prev, pager, next, jumper"
            :total="page.pageAll"
            @current-change="currentChange"
          ></el-pagination>
          <div class="btn-grp">
            <el-button type="primary" @click="getFileList" size="small"
              >读取</el-button
            >
            <el-button
              :disabled="importData.checked.length == 0"
              type="success"
              @click="importCmd"
              size="small"
              >导入</el-button
            >
          </div>
        </div>
        <el-table
          :data="importData.getFileList"
          @selection-change="selectChanged"
          style="width: 100%"
        >
          <el-table-column type="selection" :selectable="selectInit" width="50">
          </el-table-column>
          <el-table-column
            v-for="(item, idx) in importData.header"
            :key="'header_' + idx"
            :prop="item.prop"
            :label="item.label"
            :min-width="item.minWidth"
          >
          </el-table-column>
        </el-table>
      </div>
      <template v-else>
        <div class="info">
          请等以上任务处理结束再操作...,
          也可以点击终止按钮,手动终止当前文件列表的导入
        </div>
        <el-button type="primary" size="small" @click="stopImport"
          >终止</el-button
        >
      </template>
      <div slot="footer">
        <el-button @click="importData.show = false">关闭</el-button>
      </div>
    </el-dialog>
    <!-- 表格数据 -->
    <el-dialog
      title="一体机数据表格"
      class="dialog-table"
      :visible.sync="table.show"
      width="800"
    >
      <el-table :data="table.data" stripe height="540" style="width: 100%">
        <el-table-column
          v-for="(item, idx) in table.header"
          :key="'header_' + idx"
          :prop="item.prop"
          :label="item.label"
          :min-width="item.minWidth"
        >
        </el-table-column>
      </el-table>
    </el-dialog>
    <div id="allGraph">
      <div class="chart-contain">
        <div class="chart" ref="allGraph"></div>
      </div>
    </div>
    <form
      :action="exportInfo.action"
      method="post"
      ref="all_picture"
      enctype="multipart/form-data"
    >
      <input type="hidden" id="exPageName" name="pageName" value="exportTbal" />
      <input type="hidden" name="ltop_echart" ref="ltop_echart" value="" />
      <input type="hidden" name="rtop_echart" ref="rtop_echart" value="" />
      <input
        type="hidden"
        name="lbottom_echart"
        ref="lbottom_echart"
        value=""
      />
      <input
        type="hidden"
        name="rbottom_echart"
        ref="rbottom_echart"
        value=""
      />
      <input
        type="hidden"
        name="actucap_echart"
        ref="actucap_echart"
        value="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAACCAYAAACddGYaAAAAE0lEQVQYGWN49+7dfxhmgDFANAAmzha3DvjevgAAAABJRU5ErkJggg=="
      />
      <input
        type="hidden"
        name="restcap_echart"
        ref="restcap_echart"
        value="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAACCAYAAACddGYaAAAAE0lEQVQYGWN49+7dfxhmgDFANAAmzha3DvjevgAAAABJRU5ErkJggg=="
      />
      <input
        type="hidden"
        name="capperc_echart"
        ref="capperc_echart"
        value="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAACCAYAAACddGYaAAAAE0lEQVQYGWN49+7dfxhmgDFANAAmzha3DvjevgAAAABJRU5ErkJggg=="
      />
      <input
        type="hidden"
        name="tmp_echart"
        ref="tmp_echart"
        value="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAACCAYAAACddGYaAAAAE0lEQVQYGWN49+7dfxhmgDFANAAmzha3DvjevgAAAABJRU5ErkJggg=="
      />
      <!-- 单体温度折线图 -->
      <input
        type="hidden"
        name="mon_res"
        ref="mon_res"
        value="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAACCAYAAACddGYaAAAAE0lEQVQYGWN49+7dfxhmgDFANAAmzha3DvjevgAAAABJRU5ErkJggg=="
      />
      <!-- 单体内阻 -->
      <input
        type="hidden"
        name="JH_curr"
        ref="JH_curr"
        value="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAACCAYAAACddGYaAAAAE0lEQVQYGWN49+7dfxhmgDFANAAmzha3DvjevgAAAABJRU5ErkJggg=="
      />
      <!-- 单体均衡电流 -->
      <input
        type="hidden"
        name="last_vol"
        ref="last_vol"
        value="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAACCAYAAACddGYaAAAAE0lEQVQYGWN49+7dfxhmgDFANAAmzha3DvjevgAAAABJRU5ErkJggg=="
      />
      <!-- 终止电压柱状图 -->
      <input
        type="hidden"
        name="last_tmp"
        ref="last_tmp"
        value="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAACCAYAAACddGYaAAAAE0lEQVQYGWN49+7dfxhmgDFANAAmzha3DvjevgAAAABJRU5ErkJggg=="
      />
      <!-- 终止温度柱状图 -->
      <input
        type="hidden"
        name="restcap_line_echart"
        ref="restcap_line_echart"
        value="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAACCAYAAACddGYaAAAAE0lEQVQYGWN49+7dfxhmgDFANAAmzha3DvjevgAAAABJRU5ErkJggg=="
      />
      <!-- 剩余容量 -->
      <input type="hidden" name="group_vol_qth" ref="group_vol_qth" value="" />
      <!--驼峰锅底-->
      <input type="hidden" name="obj-bmd" ref="obj_bmd" value="" />
      <input type="hidden" name="obj-title" ref="obj_title" value="" />
      <!-- 落后单体阀值信息 -->
      <input type="hidden" name="arr-data" ref="arr_data" value="[[]]" />
      <!--存放单体的起始信息二维数组-->
      <input
        type="hidden"
        name="mon-vol-list"
        ref="mon_vol_list"
        value="[[]]"
      />
      <!-- 所有单体电压测试信息 -->
      <input
        type="hidden"
        name="mon-tmp-list"
        ref="mon_tmp_list"
        value="[[]]"
      />
      <!-- 所有单体温度测试信息 -->
      <input
        type="hidden"
        name="mon-group-list"
        ref="mon_group_list"
        value="[{}]"
      />
      <!-- 在线电压 -->
    </form>
  </flex-layout>
</template>
<script>
import HomeListAio from "./components/HomeListAio";
import echarts from "echarts";
import ContentBox from "@/components/ContentBox";
import BarChart from "@/components/chart/BarChart";
import LineChart from "@/components/chart/LineChart";
import ChartWrapper from "@/components/ChartWrapper";
import comparison from "./components/comparison.vue";
import getSpecialPointIndex from "@/assets/js/tools/getSpecialPointIndex";
import {
  searchAll_lowAction
} from "./js/history";
import {
  formatSeconds,
  GetMonomerCap,
  GetHourRate,
  getBarNum,
  Title,
  sethoubeiTime,
} from "../../assets/js/tools";
let Titleobj = new Title();
import ECharts from "echarts/lib/echarts";
//引入折线图
import "echarts/lib/chart/bar";
import "echarts/lib/chart/line";
//引入提示框
import "echarts/lib/component/tooltip";
//引入标题
import "echarts/lib/component/title";
//引入图例标志
import "echarts/lib/component/legend";
//区域缩放
import "echarts/lib/component/dataZoom";
//markeline
import "echarts/lib/component/markLine";
// 引入自定义主题
import "@/components/chart/theme/transparent";
import {
  getTestList,
  getDownloadInfo,
  getFileList,
} from './js/historyAio';
import Timeout from "@/assets/js/tools/Timeout";
import CONFIG from "@/assets/js/const/const_aio";
let stopReason = CONFIG.stopreasons;
// 端信息
let allData = {
  groupVol: [],
  onlineVol: [],
  testCurr: [],
  testTimeLong: [],
  monNumList: [],
  recordTime: [],
  testCap: [],
  dataList: [],
  endData: {},
  tableData: [],
};
// 单体折线信息
let monLineData = {
  vol: [], // 单体电压
  temp: [], // 单体温度
  realCap: [], // 单体实际容量
  resCap: [], // 单体剩余容量
  preCap: [], // 单体容量百分比
};
// 单体柱状信息
let monBarData = {
  vol: [], // 单体电压
  temp: [], // 单体温度
  realCap: [], // 单体实际容量
  resCap: [], // 单体剩余容量
  preCap: [], // 单体容量百分比
  jh_curr: [], // 单体均衡电流
  res: [], // 单体内阻
};
// 4个图表
let groupVolLineChart, currLineChart, monLineChart, monBarChart;
let allGraph;
// 导入处理的状态
const STATE = {
  0: "不下载",
  1: "正在下载",
  2: "下载完成",
  "-1": "下载失败",
};
const TYPE = {
  1: "",
  2: "success",
  "-1": "danger",
};
// 测试类型
const TESTTYPE = {
  2: "充电",
  3: "放电",
  4: "活化",
};
export default {
  name: 'historyAio',
  data() {
    let baseURL = this.$axios.defaults.baseURL;
    baseURL = baseURL ? baseURL : "";
    return {
      HistoryData: [],
      loading: false,
      isNew: true,
      batt: {},
      layout: {
        gutter: 16,
        span: 6,
        importGutter: 30,
        importSpan: 8,
      },
      groupVolTitle: "总电压折线图(V)",
      groupVolQth: {
        code: 0,
        low: 0,
        lowTime: "00:00:00",
        high: 0,
        highTime: "00:00:00",
        qt: 0,
        qg: 0,
        qh: 0,
        title: "正常",
      },
      top: {
        state: "", // 电池状态
        group: "", // 端电压
        curr: "", // 电池电流
        test_long: "", // 测试时长
        test_cap: "", // 测试容量
        re_cap: "", // 剩余容量
        xuhang: "", // 续航时长
      },
      battState: {
        test_type: -100,
        stop_reason: "",
      },
      slider: 100,
      testTimeLong: [],
      test_record: {
        value: [],
        list: [
          {
            value: "discharge",
            label: "放电",
            children: [],
          },
          {
            value: "charge",
            label: "充电",
            children: [],
          },
          {
            value: "activate",
            label: "活化",
            children: [],
          },
        ],
      },
      monBarTitle: "最大值=0V;最小值=0V;平均值=0V",
      chartType: "vol",
      chartTypes: [
        {
          label: "单体电压",
          value: "vol",
          unit: "V",
          fixed: 3,
        },
      ],
      exportInfo: {
        action: baseURL + "EchartPictureDowload.servlet",
        ltop_echart: "", // 组端电压折线图
        rtop_echart: "", // 单体电压柱状图
        lbottom_echart: "", // 测试电流
        rbottom_echart: "", // 单体电压折线图
        actucap_echart: "", // 实际容量
        restcap_echart: "", // 剩余容量
        capperc_echart: "", // 容量百分比
        tmp_echart: "", // 单体温度折线图
        mon_res: "", // 单体内阻
        JH_curr: "", // 单体均衡电流
        last_vol: "", // 终止电压柱状图
        last_tmp: "", // 终止温度柱状图
        restcap_line_echart: "", // 剩余容量
        obj_bmd: "", //
        obj_title: "", // 落后单体阀值信息
        arr_data: [], // 存放单体的起始信息二维数组
        mon_vol_list: [], // 所有单体电压测试信息
        mon_tmp_list: [], // 所有单体温度测试信息
        mon_group_list: [], // 所有单体温度测试信息
      },
      low_list: [],
      monInfo: {
        title: "单体电压(V)",
        unit: "V",
      },
      timer: new Timeout(),
      // 导入
      importData: {
        show: false,
        header: [
          {
            prop: "file_name",
            label: "文件名",
            minWidth: 200,
          },
          {
            prop: "test_type",
            label: "测试类型",
            minWidth: 200,
          },
          {
            prop: "test_timelong_str",
            label: "测试时长",
            minWidth: 100,
          },
          {
            prop: "invalid",
            label: "有效性",
            minWidth: 200,
          },
        ],
        // fileLen: 0,
        getFileList: [],
        checked: [],
        done: true,
        inProgress: [],
      },
      removeable: false,
      table: {
        show: false,
        header: [],
        headerBase: [
          {
            label: "测试时长",
            prop: "test_timelong",
            minWidth: 100,
          },
          {
            label: "总电压",
            prop: "sum_vol",
            minWidth: 100,
          },
          {
            label: "测试电流",
            prop: "test_curr",
            minWidth: 100,
          },
          {
            label: "测试容量",
            prop: "test_cap",
            minWidth: 100,
          },
        ],
        data: [],
      },
      page: {
        pageCurr: 1,
        pageSize: 8,
        pageAll: 0,
      },
      // 当前测试类型
      test_type: 0,
    };
  },
  components: {
    HomeListAio,
    ContentBox,
    BarChart,
    LineChart,
    ChartWrapper,
    comparison,
  },
  computed: {
    battFullName() {
      let batt = this.batt;
      if (batt.StationName && batt.BattGroupName) {
        return batt.StationName + "-" + batt.BattGroupName;
      }
      return "电池组全称";
    },
    formateBattState() {
      let battState = this.battState;
      let str = "(终止原因:" + battState.stop_reason + ")";
      let res = "";
      switch (battState.test_type) {
        case 2:
          res = "充电" + str;
          break;
        case 3:
          res = "放电" + str;
          break;
        case 4:
          res = "活化" + str;
          break;
      }
      return res;
    },
  },
  watch: {
    batt(n) {
      this.timer.stop();
      this.timer.restart();
    },
    "importData.inProgress"(n) {
      // console.log('done', n, o);
      this.importData.done = !n.some((v) => {
        return v.state == 1;
      });
      // console.log(n, this.importData.done, '===done');
      // 刷新测试记录列表
      this.searchBattTestData();
    },
  },
  methods: {
    changeShow() {
      // 端信息
      allData = {
        groupVol: [],
        onlineVol: [],
        testCurr: [],
        testTimeLong: [],
        monNumList: [],
        recordTime: [],
        testCap: [],
        dataList: [],
        endData: {},
        tableData: [],
      };
      // 单体折线信息
      monLineData = {
        vol: [], // 单体电压
        temp: [], // 单体温度
        realCap: [], // 单体实际容量
        resCap: [], // 单体剩余容量
        preCap: [], // 单体容量百分比
      };
      // 单体柱状信息
      monBarData = {
        vol: [], // 单体电压
        temp: [], // 单体温度
        realCap: [], // 单体实际容量
        resCap: [], // 单体剩余容量
        preCap: [], // 单体容量百分比
        jh_curr: [], // 单体均衡电流
        res: [], // 单体内阻
      };
      this.formateHisData(this.HistoryData);
    },
    toggleChange() {
      this.resize();
    },
    leafClick(data) {
      this.batt = data;
      // 重置页面内容
      this.init();
      // 获取充放电记录
      this.searchBattTestData();
      this.isNew = false;
    },
    init() {
      // 初始化充放电记录
      this.test_record.value = [];
      this.test_record.list[0].children = [];
      this.test_record.list[1].children = [];
      this.test_record.list[2].children = [];
      // 初始化顶部文本框内容
      this.top = {
        state: "", // 电池状态
        group: "", // 端电压
        curr: "", // 电池电流
        test_long: "", // 测试时长
        test_cap: "", // 测试容量
        re_cap: "", // 剩余容量
        xuhang: "---", // 续航时长
      };
      // 初始化电池状态
      this.battState.test_type = -100;
      // 初始化图表
      // TODO
      this.initChart();
    },
    // 初始化图表和图表数据
    initChart() {
      let batt = this.batt;
      // 拖动条默认值100
      this.slider = 100;
      this.testTimeLong = [];
      // 端信息
      allData = {
        groupVol: [],
        onlineVol: [],
        testCurr: [],
        testTimeLong: [],
        recordTime: [],
        testCap: [],
        monNumList: [],
        dataList: [],
        tableData: [],
      };
      for (let i = 1; i <= batt.MonCount; i++) {
        allData.monNumList[i - 1] = "#" + i;
      }
      // 单体折线信息
      monLineData = {
        vol: [], // 单体电压
        temp: [], // 单体温度
        realCap: [], // 单体实际容量
        resCap: [], // 单体剩余容量
        preCap: [], // 单体容量百分比
      };
      // 单体柱状信息
      monBarData = {
        vol: [], // 单体电压
        temp: [], // 单体温度
        realCap: [], // 单体实际容量
        resCap: [], // 单体剩余容量
        preCap: [], // 单体容量百分比
        jh_curr: [], // 单体均衡电流
        res: [], // 单体内阻
      };
      // 初始化图表的配置项
      this.initChartOptions();
      // 设置折线图
      this.setLineChart();
      // 设置柱状图
      this.setBarChart();
    },
    initChartOptions() {
      // 端电压折线图
      groupVolLineChart = {
        color: ["#0081ff", "#df9d02"],
        title: {
          show: false,
          text: "总电压折线图(V)",
          x: "left",
          textStyle: {
            fontSize: "14",
          },
        },
        legend: {
          show: false,
          data: ["在线电压", "总电压"],
          right: 0,
          orient: "vertical",
        },
        series: [
          {
            name: "在线电压",
            data: [],
          },
          {
            name: "总电压",
            data: [],
          },
        ],
      };
      // 电池电流折线图
      currLineChart = {
        title: {
          show: false,
          text: "电池电流折线图(A)",
          x: "center",
          textStyle: {
            fontSize: "14",
          },
        },
        series: [
          {
            name: "电池电流",
            areaStyle: {
              color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
                {
                  offset: 0,
                  color: "#00feff",
                },
                {
                  offset: 1,
                  color: "transparent",
                },
              ]),
            },
            data: [],
          },
        ],
      };
      // 单体信息折线图
      monLineChart = {
        title: {
          show: false,
          text: "单体电压(V)",
          x: "center",
          textStyle: {
            fontSize: "14",
          },
        },
        series: [],
      };
      // 图表类型
      let chartInfo = this.getChartInfo();
      let unit = chartInfo.unit;
      let label = chartInfo.label;
      // 单体信息柱状图
      this.monBarTitle =
        "最大值=0" + unit + ";最小值=0" + unit + ";平均值=0" + unit;
      monBarChart = {
        title: {
          show: false,
          text: "最大值=0" + unit + ";最小值=0" + unit + ";平均值=0" + unit,
          x: "center",
          textStyle: {
            fontSize: "14",
          },
        },
        series: [
          {
            name: "初始值",
            hColor: "#0B388B",
            data: [],
          },
          {
            name: label,
            barGap: "-100%",
            data: [],
          },
        ],
      };
    },
    // 设置折线图
    setLineChart() {
      // 设置端电压折线图
      this.setGroupVolLineChart();
      // 设置电池电流折线图
      this.setCurrLineChart();
      // 设置单体折线图
      this.setMonLineChart();
      // 建立联动
      this.$G.chartManage.connect(["groupVol", "groupCurr", "monInfo"]);
    },
    // 设置端电压折线图
    setGroupVolLineChart() {
      // 根据allData.groupVol数据设置groupVolLineChart的值
      groupVolLineChart.series[0].data = allData.onlineVol;
      groupVolLineChart.series[1].data = allData.groupVol;
      let specialPoint = getSpecialPointIndex(
        allData.groupVol.map((item) => {
          return item[1];
        })
      );
      let markLine = {};
      this.groupVolQth.code = specialPoint.code;
      // console.log(this.test_record.value);
      this.groupVolTitle = "总电压折线图(V)";
      groupVolLineChart.series[1].markLine = markLine;
      // 更新图表
      this.$refs.groupVol.setOption(groupVolLineChart);
    },
    // 设置电池电流折线图
    setCurrLineChart() {
      // 根据allData.testCurr数据设置currLineChart的值
      currLineChart.series[0].data = allData.testCurr;
      // 更新图表
      this.$refs.groupCurr.setOption(currLineChart);
    },
    // 设置单体折线图
    setMonLineChart() {
      let chartInfo = this.getChartInfo();
      // 根据monLineData的值设置monLineChart
      let dataList = monLineData.vol;
      let title = chartInfo.label + "(" + chartInfo.unit + ")";
      let unit = chartInfo.unit;
      let isUpdate = true;
      switch (chartInfo.value) {
        case "vol":
          dataList = monLineData.vol;
          break;
        case "temp":
          dataList = monLineData.temp;
          break;
        case "resCap":
          dataList = monLineData.resCap;
          break;
        default:
          isUpdate = false;
          break;
      }
      // 检测是否更新
      if (!isUpdate) {
        return;
      }
      this.monInfo.title = title;
      this.monInfo.unit = unit;
      monLineChart.title.show = false;
      monLineChart.series = dataList.map((item, index) => {
        let monNum = "#" + (index + 1);
        return {
          name: monNum,
          data: item,
        };
      });
      this.$nextTick(() => {
        // 更新图表
        this.$refs.monInfo.setOption(monLineChart);
      });
    },
    // 设置柱状图
    setBarChart() {
      let chartInfo = this.getChartInfo();
      let unit = chartInfo.unit;
      let fixed = chartInfo.fixed;
      // 根据monBarData的值设置monBarChart
      let dataList = this.getBarDataList();
      let index = this.getDataIndex(dataList.length, this.slider);
      if (index != -1) {
        let data = dataList[index];
        let batNum = getBarNum(data);
        monBarChart.title.show = false;
        monBarChart.title.text =
          "最大值=" +
          batNum.max +
          unit +
          ";最小值=" +
          batNum.min +
          unit +
          ";平均值=" +
          batNum.avg.toFixed(fixed) +
          unit;
        this.monBarTitle = monBarChart.title.text;
        monBarChart.series[1].name = chartInfo.label;
        monBarChart.series[1].data = data;
        monBarChart.series[0].data = dataList[0];
      } else {
        console.log("未获取到值");
      }
      // 设置柱状图
      this.$refs.monBar.setOption(monBarChart);
    },
    getBarDataList() {
      let chartInfo = this.getChartInfo();
      // 根据monBarData的值设置monBarChart
      let dataList = monBarData.vol;
      switch (chartInfo.value) {
        case "vol":
          dataList = monBarData.vol;
          break;
        case "temp":
          dataList = monBarData.temp;
          break;
        case "realCap":
          dataList = monBarData.realCap;
          break;
        case "resCap":
          dataList = monBarData.resCap;
          break;
        case "preCap":
          dataList = monBarData.preCap;
          break;
        default:
          dataList = monBarData.vol;
          break;
      }
      return dataList;
    },
    resize() {
      this.$G.chartManage.resize("groupVol");
      this.$G.chartManage.resize("monBar");
      this.$G.chartManage.resize("groupCurr");
      this.$G.chartManage.resize("monInfo");
    },
    // 查询测试信息
    searchBattTestData() {
      // console.trace('testlist');
      let batt = this.batt;
      // 开启等待框
      let loading = this.$layer.loading(1);
      getTestList({
          BattGroupId: batt.BattGroupId,
        })
        .then((res) => {
          // 关闭等待框
          this.$layer.close(loading);
          // 解析数据
          let rs = JSON.parse(res.data.result);
          let charge = []; // 充电
          let discharge = []; // 放电
          let activate = []; // 活化
          if (rs.code == 1) {
            // console.log(rs.data, 'data');
            rs.data.forEach((item) => {
              item.value = item.test_starttime;
              item.label = item.test_starttime;
              // 测试类型
              switch (item.test_type) {
                case 2:
                  //充电
                  charge.push(item);
                  break;
                case 3:
                  //放电
                  discharge.push(item);
                  break;
                case 4:
                  //活化
                  activate.push(item);
                  break;
              }
            });
          }
          // 充放电记录
          this.test_record.list[0].children = charge;
          this.test_record.list[1].children = discharge;
          this.test_record.list[2].children = activate;
        })
        .catch((error) => {
          this.$layer.close(loading);
          console.log(error);
        });
    },
    // 切换测试信息
    testRecordChange() {
      let testRecord = this.getTestRecord();
      // console.log(testRecord, '009');
      // 当前选中的数据的测试类型
      this.test_type = testRecord.test_type;
      let monCount = testRecord.mon_count || 0;
      let list = [];
      if (monCount > 0) {
        for (let i = 0; i < monCount; i++) {
          let idx = i + 1;
          list.push({
            label: "#" + idx,
            prop: "mon_vol" + idx,
            minWidth: 100,
          });
        }
        this.table.header = [...this.table.headerBase, ...list];
      }
      // 初始化图表
      this.initChart();
      // 查询历史数据
      this.searchHistory(testRecord.BattGroupId, testRecord.test_record_count);
    },
    // 查询历史信息
    searchHistory(BattGroupId, count) {
      this.loading = true;
      this.$nextTick(() => {
        getTestData({
            BattGroupId: BattGroupId,
            test_record_count: count,
          })
          .then((res) => {
            this.loading = false;
            let rs = JSON.parse(res.data.result);
            let data = [];
            // 数据
            if (rs.code == 1) {
              data = rs.data;
              // console.log(data, 'hisData');
            }
            this.HistoryData = data;
            // console.log(data, 'his==');
            // 格式化数据
            this.formateHisData(data);
          })
          .catch((error) => {
            this.loading = false;
            console.log(error);
          });
      });
    },
    // 格式化历史信息数据
    formateHisData(filterData) {
      // console.log(filterData, 'formate');
      let record_time = -1; // 记录时间
      let record_num = -100; // 记录笔数
      allData.endData = filterData[filterData.length - 1];
      // 测试类型
      if (allData.endData) {
        allData.endData.test_type = this.test_type;
      }
      filterData.forEach((item) => {
        let mon_num = item.mon_num;
        let testTimeLong = formatSeconds(item.test_timelong);
        // 获取组端电压,在线电压,组端电流的信息和开辟一个单体柱状图
        if (record_num != item.record_num) {
          // debugger;
          record_time = item.record_time;
          record_num = item.record_num;
          allData.groupVol.push([testTimeLong, item.sum_vol]);
          allData.onlineVol.push([testTimeLong, item.online_vol]);
          allData.testCurr.push([testTimeLong, item.test_curr]);
          allData.recordTime.push(testTimeLong);
          allData.testTimeLong.push(item.test_timelong);
          allData.testCap.push(item.test_cap);
          item.group_vol = item.sum_vol;
          allData.dataList.push(item);
          this.testTimeLong.push(item.test_timelong);
          // 开辟空间
          monBarData.vol.push([]);
          monBarData.temp.push([]);
          monBarData.realCap.push([]);
          monBarData.resCap.push([]);
          monBarData.preCap.push([]);
          allData.tableData.push({
            test_timelong: formatSeconds(item.test_timelong),
            sum_vol: item.sum_vol,
            test_curr: item.test_curr,
            test_cap: item.test_cap,
          });
        }
        // 单体电压柱状图设置
        let mon_num_text = "#" + mon_num;
        let monBarVol = monBarData.vol[monBarData.vol.length - 1];
        monBarVol.push([mon_num_text, item.mon_vol]);
        // 单体温度柱状图
        let monBarTemp = monBarData.temp[monBarData.temp.length - 1];
        monBarTemp.push([mon_num_text, item.mon_tmp]);
        // 设置单体折线图信息
        if (typeof monLineData.vol[mon_num - 1] != "object") {
          let index = mon_num - 1;
          // 开辟空间
          monLineData.vol[index] = [];
          monLineData.temp[index] = [];
          monLineData.resCap[index] = [];
        }
        // 获取到需要使用的空间
        let monLineVol = monLineData.vol[mon_num - 1];
        monLineVol.push([testTimeLong, item.mon_vol]);
        let monLineTemp = monLineData.temp[mon_num - 1];
        monLineTemp.push([testTimeLong, item.mon_tmp]);
        allData.tableData[allData.tableData.length - 1]["mon_vol" + mon_num] =
          item.mon_vol;
      });
      // console.log(allData, 'allData');
      this.table.data = allData.tableData;
      // 初始化图表的配置项
      this.initChartOptions();
      // 设置容量
      this.setCapList();
      // 设置折线图表
      this.setLineChart();
      // 执行滑动事件
      this.sliderInput();
    },
    setCapList() {
      let batt = this.batt;
      let batt_test_data = monBarData.vol;
      let batt_test_evary_record = allData.dataList;
      for (let i = 0; i < batt_test_data.length; i++) {
        let vol_list = batt_test_data[i].map((item) => {
          return item[1];
        });
        let max_vol = Math.max.apply(null, vol_list);
        for (let j = 0; j < vol_list.length; j++) {
          let avg_curr =
            batt_test_evary_record[i].test_timelong > 0
              ? (batt_test_evary_record[i].test_cap * 3600) /
                batt_test_evary_record[i].test_timelong
              : batt_test_evary_record[i].test_curr;
          let actionvalue = GetMonomerCap(
            batt.MonCapStd,
            GetHourRate(batt.MonCapStd, avg_curr),
            batt_test_evary_record[i].test_cap,
            max_vol,
            vol_list[j],
            batt.MonVolStd,
            1
          );
          let restvalue = GetMonomerCap(
            batt.MonCapStd,
            GetHourRate(batt.MonCapStd, avg_curr),
            batt_test_evary_record[i].test_cap,
            max_vol,
            vol_list[j],
            batt.MonVolStd,
            0
          );
          let batt_num_text = "#" + (j + 1);
          monBarData.realCap[i].push([batt_num_text, actionvalue.toFixed(0)]);
          monBarData.resCap[i].push([batt_num_text, restvalue.toFixed(0)]);
          monBarData.preCap[i].push([
            batt_num_text,
            ((actionvalue * 100) / batt.MonCapStd).toFixed(0),
          ]);
        }
      }
      // 容量
      monLineData.vol.forEach((item, key) => {
        item.forEach((volItem, volItemKey) => {
          let resCapItem = monBarData.resCap[volItemKey];
          monLineData.resCap[key].push([volItem[0], resCapItem[key][1]]);
        });
      });
    },
    // 获取测试的信息
    getTestRecord() {
      let value = this.test_record.value;
      // 没有选择充放电记录,返回-1
      if (value.length == 0) {
        return -1;
      }
      let type = value[0];
      let time = value[1];
      let list = this.test_record.list;
      let result = 0;
      // 遍历list
      for (let i in list) {
        let item = list[i];
        if (item.value == type) {
          for (let j in item.children) {
            let child = item.children[j];
            if (child.value == time) {
              result = child;
              break;
            }
          }
          break;
        }
      }
      // 设置电池状态
      this.battState.test_type = result.test_type;
      // console.log(result, 'info00');
      this.battState.stop_reason = stopReason[result.stop_type];
      this.removeable = true;
      // 返回结果集
      return result;
    },
    // 格式化滑块显示的内容
    formatTooltip(value) {
      // console.log(value, 'time_long');
      let testTimeLong = this.testTimeLong;
      let index = this.getDataIndex(testTimeLong.length, value);
      let test_long = formatSeconds(0);
      if (index != -1) {
        test_long = formatSeconds(testTimeLong[index]);
      }
      this.top.test_long = test_long;
      return test_long;
    },
    // 拖动滑块时触发
    sliderInput() {
      // 设置头部信息
      this.setTopData();
      // 设置柱状图
      this.setBarChart();
    },
    // 设置顶部文本框的数据
    setTopData() {
      let batt = this.batt;
      // 组端电压和在线电压
      let groupVol = allData.groupVol;
      let onlineVol = allData.onlineVol;
      let testCurr = allData.testCurr;
      let testCap = allData.testCap;
      let monVols = monBarData.vol;
      let dataList = allData.dataList;
      let index = this.getDataIndex(groupVol.length, this.slider);
      if (index != -1) {
        this.top.group =
          "在线:" +
          onlineVol[index][1].toFixed(2) +
          "V;总电压:" +
          groupVol[index][1].toFixed(2) +
          "V";
        this.top.curr = testCurr[index][1].toFixed(1) + "A";
        this.top.test_cap = testCap[index].toFixed(1) + "AH";
        // 剩余容量
        let monVol = monVols[index];
        let list = dataList[index];
        let avg_curr =
          list.test_timelong > 0
            ? (list.test_cap * 3600) / list.test_timelong
            : list.test_curr;
        let batNum = getBarNum(monVol);
        let over_cap = GetMonomerCap(
          batt.MonCapStd,
          GetHourRate(batt.MonCapStd, avg_curr),
          list.test_cap,
          batNum.max,
          batNum.min,
          batt.MonVolStd,
          0
        );
        this.top.re_cap = over_cap.toFixed(1) + "AH";
      }
      // 设置续航时长
      let lastIndex = this.getDataIndex(groupVol.length, 100);
      if (lastIndex != -1) {
        // 实际容量
        let monVol = monVols[lastIndex];
        let list = dataList[lastIndex];
        let avg_curr =
          list.test_timelong > 0
            ? (list.test_cap * 3600) / list.test_timelong
            : list.test_curr;
        let batNum = getBarNum(monVol);
        let real_cap = GetMonomerCap(
          batt.MonCapStd,
          GetHourRate(batt.MonCapStd, avg_curr),
          list.test_cap,
          batNum.max,
          batNum.min,
          batt.MonVolStd,
          1
        );
        let xuhang = batt.Load_curr ? real_cap / batt.Load_curr : 0;
        this.top.xuhang = xuhang ? sethoubeiTime(xuhang) : "---";
      }
    },
    // 根据百分比获取显示的数据的笔数
    getDataIndex(num, percent) {
      if (percent <= 0) {
        return 0;
      }
      return Math.floor((num * percent) / 100) - 1;
    },
    // 向父级发送同步页面的指令
    syncPage() {
      let batt = this.batt;
      let search =
        "?province=" +
        batt.StationName1 +
        "&city=" +
        batt.StationName2 +
        "&county=" +
        batt.StationName5 +
        "&home=" +
        batt.StationName3 +
        "&batt=" +
        batt.BattGroupId;
      window.parent.postMessage(
        {
          cmd: "syncPage",
          params: {
            pageInfo: {
              label: "实时监控",
              name: "movingRingSysteRrealTime",
              src: "#/moving-ring-system" + search,
              closable: true,
            },
          },
        },
        "*"
      );
    },
    toShowComparison() {
      this.showComparison = true;
    },
    getChartInfo() {
      let chartType = this.chartType;
      let chartTypes = this.chartTypes;
      let chartTypeInfo = chartTypes[0];
      for (let i = 0; i < chartTypes.length; i++) {
        if (chartType == chartTypes[i].value) {
          chartTypeInfo = chartTypes[i];
          break;
        }
      }
      return chartTypeInfo;
    },
    changeChartType() {
      if (allData.groupVol.length == 0) {
        this.initChart();
      } else {
        let loading = this.$layer.loading();
        setTimeout(() => {
          this.setBarChart();
          this.setMonLineChart();
          this.$layer.close(loading);
        }, 100);
      }
    },
    // 导出报表
    exportExcel() {
      if (allData.groupVol.length == 0) {
        this.$layer.msg("暂无数据导出,请先选择充放电数据!");
        return false;
      }
      let lastarray = [];
      lastarray.push(allData.monNumList);
      //组端电压折线图
      let groupVolLineChartOption =
        this.$refs.groupVol.getOption(groupVolLineChart);
      groupVolLineChartOption.title.show = true;
      groupVolLineChartOption.title.x = "center";
      groupVolLineChartOption.legend.show = false;
      this.createGraphByOpt(groupVolLineChartOption);
      let oltop = allGraph.getDataURL({
        pixelRatio: 1,
        backgroundColor: "#fff",
      });
      // 电池电流折线图
      let currLineChartOption = this.$refs.groupVol.getOption(currLineChart);
      currLineChartOption.title.show = true;
      currLineChartOption.title.x = "center";
      currLineChartOption.legend.show = false;
      this.createGraphByOpt(currLineChartOption);
      let ortop = allGraph.getDataURL({
        pixelRatio: 1,
        backgroundColor: "#fff",
      });
      //获取起始单体电压
      // lastarray.push(monBarData.vol[0].map(item => {
      //     return item[1];
      // }));
      lastarray.push(
        allData.monNumList.map((item) => {
          return 0;
        })
      );
      //单体电压柱状图
      let monBarVol = monBarData.vol;
      let monBarEndVol =
        monBarVol[this.getDataIndex(monBarVol.length, this.slider)];
      //获取单体截止电压
      // let monBarVolArr = monBarEndVol.map(item => {
      //     return item[1];
      // });
      // lastarray.push(monBarVolArr);
      lastarray.push(
        allData.monNumList.map((item) => {
          return 0;
        })
      );
      // monBarChart.title.show = true;
      // monBarChart.title.text = this.getTitle(monBarVolArr, 'Voltage');
      // let lowObj = Titleobj; //落后单体电压信息
      let lowObj = { min: 0, max: 0, avg: 0, alow: 0, clow: 0, lc: 0, lp: 0 };
      // monBarChart.title.x = 'center';
      // monBarChart.series[0].name = "单体电压";
      // monBarChart.series[0].data = monBarEndVol;
      // let monBarChartVolOption = this.$refs.monBar.getOption(monBarChart);
      // this.createGraphByOpt(monBarChartVolOption);
      let orbottom1 = allGraph.getDataURL({
        pixelRatio: 1,
        backgroundColor: "#fff",
      });
      //单体实际容量柱状图
      let monBarRealCap = monBarData.realCap;
      let monBarRealCapEnd =
        monBarRealCap[this.getDataIndex(monBarRealCap.length, this.slider)];
      // let monBarRealCapArr = monBarRealCapEnd.map(item => {
      //     return item[1];
      // });
      // lastarray.push(monBarRealCapArr);
      lastarray.push(
        allData.monNumList.map((item) => {
          return 0;
        })
      );
      // let monRealCapNum = getBarNum(monBarRealCapEnd);
      // monBarChart.title.show = true;
      // monBarChart.title.text = this.getTitle(monBarRealCapArr, "Actual_capacity");
      // monBarChart.title.x = 'center';
      // monBarChart.series[0].name = "单体实际容量";
      // monBarChart.series[0].data = monBarRealCapEnd;
      // let monBarChartRealCapOption = this.$refs.monBar.getOption(monBarChart);
      // this.createGraphByOpt(monBarChartRealCapOption);
      // let orbottom2 = allGraph.getDataURL({
      //     pixelRatio: 1,
      //     backgroundColor: '#fff'
      // });
      //单体剩余容量柱状图
      let monBarResCap = monBarData.resCap;
      let monBarResCapEnd =
        monBarResCap[this.getDataIndex(monBarResCap.length, this.slider)];
      // let monBarResCapArr = monBarResCapEnd.map(item => {
      //     return item[1];
      // });
      // lastarray.push(monBarResCapArr);
      lastarray.push(
        allData.monNumList.map((item) => {
          return 0;
        })
      );
      // monBarChart.title.show = true;
      // monBarChart.title.text = this.getTitle(monBarResCapArr, "Residual_capacity");
      // monBarChart.title.x = 'center';
      // monBarChart.series[0].name = "单体剩余容量";
      // monBarChart.series[0].data = monBarResCapEnd;
      // let monBarChartResCapOption = this.$refs.monBar.getOption(monBarChart);
      // this.createGraphByOpt(monBarChartResCapOption);
      // let orbottom3 = allGraph.getDataURL({
      //     pixelRatio: 1,
      //     backgroundColor: '#fff'
      // });
      //单体容量百分比柱状图
      let monBarPreCap = monBarData.preCap;
      let monBarPreCapEnd =
        monBarPreCap[this.getDataIndex(monBarPreCap.length, this.slider)];
      // let monBarPreCapArr = monBarPreCapEnd.map(item => {
      //     return item[1];
      // });
      // lastarray.push(monBarPreCapArr);
      lastarray.push(
        allData.monNumList.map((item) => {
          return 0;
        })
      );
      // monBarChart.title.show = true;
      // monBarChart.title.text = this.getTitle(monBarPreCapArr, "Percent_total_capacity");
      // monBarChart.title.x = 'center';
      // monBarChart.series[0].name = "单体容量百分比";
      // monBarChart.series[0].data = monBarPreCapEnd;
      // let monBarChartPreCapOption = this.$refs.monBar.getOption(monBarChart);
      // this.createGraphByOpt(monBarChartPreCapOption);
      // let orbottom4 = allGraph.getDataURL({
      //     pixelRatio: 1,
      //     backgroundColor: '#fff'
      // });
      // 单体电压折线图
      monLineChart.title.show = true;
      monLineChart.title.text = "单体电压(V)";
      monLineChart.title.x = "center";
      monLineChart.series = monLineData.vol.map((item, index) => {
        let monNum = "#" + (index + 1);
        return {
          name: monNum,
          data: item,
        };
      });
      let monLineChartVolOption = this.$refs.groupVol.getOption(monLineChart);
      this.createGraphByOpt(monLineChartVolOption);
      let vol_line = allGraph.getDataURL({
        pixelRatio: 1,
        backgroundColor: "#fff",
      });
      // 单体温度折线图
      monLineChart.title.show = true;
      monLineChart.title.text = "单体温度(℃)";
      monLineChart.title.x = "center";
      monLineChart.series = monLineData.temp.map((item, index) => {
        let monNum = "#" + (index + 1);
        return {
          name: monNum,
          data: item,
        };
      });
      let monLineChartTempOption = this.$refs.groupVol.getOption(monLineChart);
      this.createGraphByOpt(monLineChartTempOption);
      let tmp_line = allGraph.getDataURL({
        pixelRatio: 1,
        backgroundColor: "#fff",
      });
      // 单体剩余容量折线图
      monLineChart.title.show = true;
      monLineChart.title.text = "剩余容量(AH)";
      monLineChart.title.x = "center";
      monLineChart.series = monLineData.resCap.map((item, index) => {
        let monNum = "#" + (index + 1);
        return {
          name: monNum,
          data: item,
        };
      });
      let monLineChartResCapOption =
        this.$refs.groupVol.getOption(monLineChart);
      this.createGraphByOpt(monLineChartResCapOption);
      let resCap_line = allGraph.getDataURL({
        pixelRatio: 1,
        backgroundColor: "#fff",
      });
      // 单体内阻
      let monBarRes = monBarData.res;
      let monBarResArr = monBarRes.map((item) => {
        return item[1];
      });
      monBarChart.title.show = true;
      monBarChart.title.text = this.getTitle(monBarResArr, "Resistance");
      monBarChart.title.x = "center";
      monBarChart.series[0].name = "单体内阻";
      monBarChart.series[0].data = monBarRes;
      monBarChart.series[1].name = "";
      monBarChart.series[1].data = [];
      let monBarResOption = this.$refs.monBar.getOption(monBarChart);
      this.createGraphByOpt(monBarResOption);
      let mon_res = allGraph.getDataURL({
        pixelRatio: 1,
        backgroundColor: "#fff",
      });
      // 单体均衡电流
      let jhCurr = monBarData.jh_curr;
      let jhCurrArr = jhCurr.map((item) => {
        return item[1];
      });
      let jhCurrNum = getBarNum(jhCurr);
      monBarChart.title.show = true;
      monBarChart.title.text =
        "最大值=" +
        jhCurrNum.max +
        "A;最小值=" +
        jhCurrNum.min +
        "A;平局值=" +
        jhCurrNum.avg.toFixed(0) +
        "A";
      monBarChart.title.x = "center";
      monBarChart.series[0].name = "单体均衡电流";
      monBarChart.series[0].data = jhCurr;
      monBarChart.series[1].name = "";
      monBarChart.series[1].data = [];
      let jhCurrOption = this.$refs.monBar.getOption(monBarChart);
      this.createGraphByOpt(jhCurrOption);
      let JH_curr = allGraph.getDataURL({
        pixelRatio: 1,
        backgroundColor: "#fff",
      });
      // 终止单体电压
      let endVolData = monBarData.vol[monBarData.vol.length - 1];
      let endVolDataNum = getBarNum(endVolData);
      monBarChart.title.show = true;
      monBarChart.title.text =
        "最大值=" +
        endVolDataNum.max +
        "V;最小值=" +
        endVolDataNum.min +
        "V;平局值=" +
        endVolDataNum.avg.toFixed(2) +
        "V";
      monBarChart.title.x = "center";
      monBarChart.series[0].name = "终止单体电压";
      monBarChart.series[0].data = endVolData;
      let endVolDataOption = this.$refs.monBar.getOption(monBarChart);
      this.createGraphByOpt(endVolDataOption);
      let last_vol = allGraph.getDataURL({
        pixelRatio: 1,
        backgroundColor: "#fff",
      });
      // 终止温度电压
      let endTempData = monBarData.temp[monBarData.temp.length - 1];
      let endTempDataNum = getBarNum(endTempData);
      monBarChart.title.show = true;
      monBarChart.title.text =
        "最大值=" +
        endTempDataNum.max +
        "℃;最小值=" +
        endTempDataNum.min +
        "℃;平局值=" +
        endTempDataNum.avg.toFixed(0) +
        "℃";
      monBarChart.title.x = "center";
      monBarChart.series[0].name = "终止单体温度";
      monBarChart.series[0].data = endTempData;
      let endTempDataOption = this.$refs.monBar.getOption(monBarChart);
      this.createGraphByOpt(endTempDataOption);
      let last_tmp = allGraph.getDataURL({
        pixelRatio: 1,
        backgroundColor: "#fff",
      });
      // lastarray.push(monBarData.res.map(item => {
      //     return '';
      // }));
      // lastarray.push(monBarData.temp[0].map(item => {
      //     return -1;
      // }));
      lastarray.push(
        allData.monNumList.map((item) => {
          return 0;
        })
      );
      // lastarray.push(monBarData.temp[0].map(item => {
      //     return -1;
      // }));
      lastarray.push(
        allData.monNumList.map((item) => {
          return 0;
        })
      );
      // lastarray.push(monBarData.temp[monBarData.temp.length - 1].map(item => {
      //     return -1;
      // }));
      lastarray.push(
        allData.monNumList.map((item) => {
          return 0;
        })
      );
      let batt = this.batt;
      let testdata = allData.endData;
      this.$refs.ltop_echart.value = oltop; // 组端电压折线图
      this.$refs.rtop_echart.value = ortop; // 电池电流折线图
      this.$refs.lbottom_echart.value = vol_line; // 单体电压折线图
      this.$refs.rbottom_echart.value = orbottom1; //单体电压柱状图
      // this.$refs.actucap_echart.value = orbottom2; //单体实际容量
      // this.$refs.restcap_echart.value = orbottom3; //单体剩余容量
      // this.$refs.capperc_echart.value = orbottom4; //单体容量百分比
      // this.$refs.tmp_echart.value = tmp_line; // 单体温度
      // this.$refs.restcap_line_echart.value = resCap_line; // 剩余容量
      // this.$refs.mon_res.value = mon_res; // 单体内阻
      // this.$refs.JH_curr.value = JH_curr; // 单体均衡电流
      // this.$refs.last_vol.value = last_vol; // 终止单体电压柱状图
      // this.$refs.last_tmp.value = last_tmp; // 终止单体温度柱状图
      let top_cause = this.battState.stop_reason;
      batt.StationIp = top_cause;
      this.$refs.obj_bmd.value = JSON.stringify({
        binf: batt,
        sdata: testdata,
      });
      this.$refs.obj_title.value = JSON.stringify(lowObj);
      this.$refs.arr_data.value = JSON.stringify(lastarray);
      let batt_test_data = monBarData.vol.map((item) => {
        return item.map((item2) => {
          return 0;
        });
      });
      this.$refs.mon_vol_list.value = JSON.stringify(batt_test_data);
      let batt_test_tmpdata = monLineData.temp.map((item) => {
        return item.map((item2) => {
          return 0;
        });
      });
      this.$refs.mon_tmp_list.value = JSON.stringify(batt_test_tmpdata);
      this.$refs.mon_group_list.value = JSON.stringify(allData.dataList);
      this.$refs.group_vol_qth.value = JSON.stringify(this.groupVolQth);
      this.$refs.all_picture.submit();
    },
    createGraphByOpt(opt) {
      allGraph.clear();
      let lineStyle = {
        color: "#000",
      };
      // 设置x轴的颜色
      if (opt.xAxis[0].axisLine) {
        opt.xAxis[0].axisLine.lineStyle = lineStyle;
      } else {
        opt.xAxis[0].axisLine = {
          lineStyle,
        };
      }
      // 设置x轴刻度的值
      if (opt.xAxis[0].axisLabel) {
        opt.xAxis[0].axisLabel.color = "#000";
      } else {
        opt.xAxis[0].axisLabel = {
          color: "#000",
        };
      }
      // 设置y轴的颜色
      if (opt.yAxis[0].axisLine) {
        opt.yAxis[0].axisLine.lineStyle = lineStyle;
      } else {
        opt.yAxis[0].axisLine = {
          lineStyle,
        };
      }
      // 设置y轴刻度的值
      if (opt.yAxis[0].axisLabel) {
        opt.yAxis[0].axisLabel.color = "#000";
      } else {
        opt.yAxis[0].axisLabel = {
          color: "#000",
        };
      }
      // console.log(opt);
      opt.animation = false;
      allGraph.setOption(opt);
    },
    getTitle(array, units) {
      let getLow = this.getLow;
      var title = "";
      //a=new Title();
      //alert(Titleobj);
      Titleobj = new Title();
      var sum = 0;
      if (array != undefined && array.length > 0) {
        Titleobj.setMax(Math.max.apply(null, array));
        Titleobj.setMin(Math.min.apply(null, array));
        for (var i = 0; i < array.length; i++) {
          sum += parseFloat(array[i]);
        }
        var batt = this.batt;
        //console.info(batt);
        if ("Resistance" == units) {
          Titleobj.setAvg((sum / array.length).toFixed(3));
          var low = getLow(3, 2);
          if (low.low_method == 0) {
            //根据标称值计算
            Titleobj.setAlow(((2 - low.low_value) * batt.MonResStd).toFixed(3));
            low = getLow(3, 3);
            Titleobj.setClow(((2 - low.low_value) * batt.MonResStd).toFixed(3));
          } else {
            //根据平均值计算
            Titleobj.setAlow(
              ((2 - low.low_value) * Titleobj.getAvg()).toFixed(3)
            );
            low = getLow(3, 3);
            Titleobj.setClow(
              ((2 - low.low_value) * Titleobj.getAvg()).toFixed(3)
            );
          }
          var count = 0;
          for (var i = 0; i < array.length; i++) {
            if (parseFloat(Titleobj.getAlow()) < parseFloat(array[i])) {
              //console.info(title.getAlow()+"<"+array[i]);
              count++;
            }
          }
          Titleobj.setLc(count);
          Titleobj.setLp(((count * 100) / array.length).toFixed(1));
          //console.info(title);
        } else {
          if ("Voltage" == units) {
            Titleobj.setAvg((sum / array.length).toFixed(3));
            var low = getLow(1, 1);
            if (low.low_method == 0) {
              //根据标称值计算
              Titleobj.setAlow((low.low_value * batt.MonVolStd).toFixed(3));
              low = getLow(1, 0);
              Titleobj.setClow((low.low_value * batt.MonVolStd).toFixed(3));
            } else {
              //根据平均值计算
              Titleobj.setAlow((low.low_value * Titleobj.getAvg()).toFixed(3));
              low = getLow(1, 0);
              Titleobj.setClow((low.low_value * Titleobj.getAvg()).toFixed(3));
            }
          } else if ("Temperature" == units) {
            Titleobj.setAvg((sum / array.length).toFixed(1));
            var low = getLow(1, 1);
            if (low.low_method == 0) {
              //根据标称值计算
              Titleobj.setAlow((low.low_value * batt.MonTmpStd).toFixed(1));
              low = getLow(1, 0);
              Titleobj.setClow((low.low_value * batt.MonTmpStd).toFixed(1));
            } else {
              //根据平均值计算
              Titleobj.setAlow((low.low_value * Titleobj.getAvg()).toFixed(1));
              low = getLow(1, 0);
              Titleobj.setClow((low.low_value * Titleobj.getAvg()).toFixed(1));
            }
          } else if ("Conductance" == units) {
            Titleobj.setAvg((sum / array.length).toFixed(0));
            var low = getLow(3, 2);
            if (low.low_method == 0) {
              //根据标称值计算
              Titleobj.setAlow((low.low_value * batt.MonSerStd).toFixed(0));
              low = getLow(3, 3);
              Titleobj.setClow((low.low_value * batt.MonSerStd).toFixed(0));
            } else {
              //根据平均值计算
              Titleobj.setAlow((low.low_value * Titleobj.getAvg()).toFixed(0));
              low = getLow(3, 3);
              Titleobj.setClow((low.low_value * Titleobj.getAvg()).toFixed(0));
            }
          } else if ("Actual_capacity" == units) {
            Titleobj.setAvg((sum / array.length).toFixed(0));
            var low = getLow(2, 2);
            if (low.low_method == 0) {
              //根据标称值计算
              Titleobj.setAlow((low.low_value * batt.MonCapStd).toFixed(0));
              //console.info(batt);
              low = getLow(2, 3);
              Titleobj.setClow((low.low_value * batt.MonCapStd).toFixed(0));
            } else {
              //根据平均值计算
              Titleobj.setAlow((low.low_value * Titleobj.getAvg()).toFixed(0));
              low = getLow(2, 3);
              Titleobj.setClow((low.low_value * Titleobj.getAvg()).toFixed(0));
            }
          } else if ("Residual_capacity" == units) {
            Titleobj.setAvg((sum / array.length).toFixed(0));
            var low = getLow(1, 1);
            if (low.low_method == 0) {
              //根据标称值计算
              Titleobj.setAlow((low.low_value * Titleobj.getAvg()).toFixed(0));
              //console.info(batt);
              low = getLow(1, 0);
              Titleobj.setClow((low.low_value * Titleobj.getAvg()).toFixed(0));
            } else {
              //根据平均值计算
              Titleobj.setAlow((low.low_value * Titleobj.getAvg()).toFixed(0));
              //console.info(batt);
              low = getLow(1, 0);
              Titleobj.setClow((low.low_value * Titleobj.getAvg()).toFixed(0));
            }
          } else if ("Percent_total_capacity" == units) {
            Titleobj.setAvg((sum / array.length).toFixed(2));
            var low = getLow(2, 2);
            if (low.low_method == 0) {
              //根据标称值计算
              Titleobj.setAlow((low.low_value * batt.MonCapStd).toFixed(2));
              //console.info(batt);
              low = getLow(2, 3);
              Titleobj.setClow((low.low_value * batt.MonCapStd).toFixed(2));
            } else {
              //根据平均值计算
              Titleobj.setAlow((low.low_value * Titleobj.getAvg()).toFixed(2));
              low = getLow(2, 3);
              Titleobj.setClow((low.low_value * Titleobj.getAvg()).toFixed(2));
            }
          } else if ("MonJHCurr" == units) {
            //单体均衡
            Titleobj.setAvg((sum / array.length).toFixed(2));
          }
          var count = 0;
          for (var i = 0; i < array.length; i++) {
            if (parseFloat(Titleobj.getAlow()) > parseFloat(array[i])) {
              count++;
            }
          }
          Titleobj.setLc(count);
          Titleobj.setLp(((count * 100) / array.length).toFixed(1));
        }
        //console.info(Title);
        title = Titleobj.getAllTile(units);
      }
      return title;
    },
    searchAll_lowAction() {
      searchAll_lowAction()
        .then((res) => {
          let rs = JSON.parse(res.data.result);
          if (rs.code == 1) {
            this.low_list = rs.data;
          }
        })
        .catch((error) => {
          console.log(error);
        });
    },
    getLow(lowtype, lownametype) {
      let low_list = this.low_list;
      if (
        lowtype != undefined &&
        low_list != undefined &&
        lownametype != undefined
      ) {
        for (var i = 0; i < low_list.length; i++) {
          if (
            lowtype == low_list[i].low_type &&
            lownametype == low_list[i].low_nametype
          ) {
            return low_list[i];
          }
        }
      }
    },
    // 查询设备文件下载情况
    getDownloadInfo() {
      getDownloadInfo(this.batt.deviceId)
        .then((res) => {
          res = JSON.parse(res.data.result);
          // console.log(res, 'info');
          let list = [];
          if (res.code) {
            let data = res.data[0];
            // console.log(data, 'download_info_data');
            // 总文件数
            this.page.pageAll = data.file_total;
            for (let i = 0, j = 8; i < j; i++) {
              let idx = i + 1;
              let fileName = data["file_name" + idx];
              let flag = data["download_flag" + idx];
              let state = data["download_state" + idx];
              // 进度
              let now_block = data["now_data_block" + idx];
              let total_block = data["total_data_block" + idx];
              // 进度占比 下载占60  写数据库占40 根据当前状态来算
              let percent = 0;
              // 1;  //下载文件
              // 2;  //生成文件
              // 3;  //导出数据
              // 用户终止的状态为6(导数据库时停止), 7(下载文件时停止)
              if (state <= 1 || 7 == state) {
                // percent = now_block == 0 ? 0 : (now_block / total_block * 60).toHold(2);
                percent = now_block == 0 ? 0 : (now_block / total_block) * 60;
              } else {
                // percent = (now_block == 0 ? 0 : (now_block / total_block * 40).toHold(2)) + 60;
                percent =
                  (now_block == 0 ? 0 : (now_block / total_block) * 40) + 60;
              }
              if (fileName && flag != 0) {
                list.push({
                  file_name: fileName,
                  state: flag,
                  type: TYPE[flag],
                  stateTxt: STATE[flag],
                  percent: flag == 2 ? 100 : percent.toFixed(2),
                });
              }
            }
          }
          // console.log(list, 'list00');
          this.importData.inProgress = list;
        })
        .catch((err) => {
          console.error(err);
        });
    },
    // 一体机数据导入
    importDialogShow() {
      // console.log('import');
      this.getDownloadInfo();
      this.importData.show = true;
    },
    // 给设备发指令开始导入
    importCmd() {
      this.importData.done = false;
      let batt = this.batt;
      // console.log(batt, '99');
      let params = {
        dev_id: batt.deviceId,
        BattGroupId: batt.BattGroupId,
      };
      for (let i = 0; i < 8; i++) {
        let idx = i + 1;
        params["download_flag" + idx] =
          this.importData.checked.indexOf(idx) != -1 ? 1 : 0;
      }
      // console.log(params, 'params');
      importData(params)
        .then((res) => {
          res = JSON.parse(res.data.result);
          if (res.code) {
            this.importData.done = false;
            this.importData.checked = [];
          } else {
            this.importData.done = true;
          }
          this.importData.getFileList = [];
          // console.log(res, 'import');
        })
        .catch((err) => {
          console.error(err);
        });
    },
    selectInit(row) {
      return row.test_timelong > 0;
    },
    selectChanged(list) {
      let arr = list.map((v) => {
        return v.idx;
      });
      // console.log(arr, 'arr');
      this.importData.checked = arr;
    },
    getFileList() {
      let params = {
        dev_id: this.batt.deviceId,
        file_index: this.page.pageCurr - 1,
      };
      getFileList(params)
        .then((res) => {
          res = JSON.parse(res.data.result);
          // console.log(res, 'fileList');
          let list = [];
          if (res.code) {
            let data = res.data[0];
            let len = data.file_count;
            // 当前页文件数
            // this.importData.fileLen = len;
            for (let i = 0; i < len; i++) {
              let idx = i + 1;
              let fileName = data["file_name" + idx];
              let test_timelong = data["test_timelong" + idx];
              let type = data["data_type" + idx];
              // let state = data['download_state' + idx];
              list.push({
                file_name: fileName,
                test_type: TESTTYPE[type] || "未知",
                invalid: test_timelong == 0 ? "无效" : "有效",
                test_timelong_str: formatSeconds(test_timelong),
                test_timelong: test_timelong,
                idx,
              });
            }
          } else {
            this.$message({
              type: "warning",
              message: res.msg,
            });
          }
          this.importData.getFileList = list;
        })
        .catch((err) => {
          console.error(err);
        });
    },
    currentChange(value) {
      this.page.pageCurr = value;
      this.getFileList();
    },
    removeTestData() {
      let batt = this.batt;
      let testRecord = this.getTestRecord();
      let params = {
        BattGroupId: batt.BattGroupId,
        test_record_count: testRecord.test_record_count,
      };
      delTestData(params)
        .then((res) => {
          res = JSON.parse(res.data.result);
          if (res.code) {
            this.init();
            this.table.data = [];
            this.removeable = false;
            // 获取充放电记录
            this.searchBattTestData();
          }
          // console.log(res, 'remove');
        })
        .catch((err) => {
          console.error(err);
        });
    },
    // 停止导入
    stopImport() {
      stopImport({ dev_id: this.batt.deviceId })
        .then((res) => {
          res = JSON.parse(res.data.result);
        })
        .catch((err) => {
          console.error(err);
        });
    },
  },
  mounted() {
    this.timer.init(() => {
      this.getDownloadInfo();
      this.timer.open();
    }, 1000);
    // 初始化图表
    this.initChart();
    this.searchAll_lowAction();
    // 基于准备好的dom,初始化echarts实例
    allGraph = ECharts.init(this.$refs.allGraph, "transparent");
    // 屏幕缩放时触发
    window.addEventListener("resize", this.resize);
  },
  beforeDestroy() {
    window.removeEventListener("resize", this.resize);
  },
};
</script>
<style scoped>
.el-form-item {
  margin-bottom: 0;
}
.form-header {
  padding: 8px;
}
.page-history-aio {
  color: #fff;
}
.page-content {
  position: relative;
  padding-top: 8px;
  padding-bottom: 2px;
  box-sizing: border-box;
  height: 100%;
}
.page-content .flex-box {
  flex: 1;
  overflow-x: hidden;
}
.flex-box-list {
  display: flex;
  flex-direction: row;
  height: 50%;
  box-sizing: border-box;
}
.page-content .flex-box {
  flex: 1;
  overflow-x: hidden;
}
.slider-container {
  padding-left: 16px;
  padding-right: 16px;
  overflow: hidden;
}
.box-tools {
  line-height: 32px;
}
.box-tools .iconfont {
  font-size: 20px;
}
.box-tools .iconfont:hover {
  cursor: pointer;
  color: #cfcfcf;
}
.box-tools .iconfont:active {
  color: #ff0000;
}
.chart-wrapper {
  position: relative;
  box-sizing: border-box;
  margin: 0 16px;
  height: 100%;
  padding: 12px;
  background-image: radial-gradient(#151f4140, #3667ec40);
}
.chart-wrapper:before,
.chart-wrapper:after,
.chart-wrapper-corner {
  position: absolute;
  display: inline-block;
  content: " ";
  width: 18px;
  height: 18px;
}
.chart-wrapper:before {
  left: 0;
  top: 0;
  border-top: 2px solid #00feff;
  border-left: 2px solid #00feff;
}
.chart-wrapper:after {
  left: 0;
  bottom: 0;
  border-bottom: 2px solid #00feff;
  border-left: 2px solid #00feff;
}
.chart-wrapper-corner.top-right {
  top: 0;
  right: 0;
  border-top: 2px solid #00feff;
  border-right: 2px solid #00feff;
}
.chart-wrapper-corner.bottom-right {
  bottom: 0;
  right: 0;
  border-bottom: 2px solid #00feff;
  border-right: 2px solid #00feff;
}
.chart-tools-wrapper {
  position: absolute;
  top: 12px;
  right: 12px;
  z-index: 99;
}
#allGraph {
  position: absolute;
  top: -1000px;
  left: 0;
  width: 600px;
  height: 400px;
}
.chart-contain {
  width: 100%;
  height: 100%;
  background-color: #ffffff;
}
.chart {
  width: 100%;
  height: 100%;
}
i.import {
  -webkit-transform: scaleX(-1);
  transform: scaleX(-1);
}
.dialog-import >>> .el-dialog {
  background: #fff;
}
.dialog-import >>> .el-dialog__body {
  padding: 6px 20px 0;
}
.dialog-table >>> .el-dialog__body {
  background: #79b4f0;
}
.posR {
  position: relative;
}
/* .inProgress {
    height: 100px;
} */
.inProgress >>> .el-row .el-tag {
  width: 100%;
}
.inProgress .el-col {
  margin-bottom: 6px;
  margin-top: 20px;
}
.empty {
  height: 100%;
  color: #999;
}
.empty::before {
  content: "暂无数据";
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
}
.title {
  margin-bottom: 10px;
}
.title.files {
  margin-top: 10px;
  display: flex;
  justify-content: space-between;
}
.clearfix::before,
.clearfix:before,
.clearfix::after,
.clearfix:after {
  content: "";
  display: block;
  visibility: hidden;
  height: 0;
  font-size: 0;
  clear: both;
}
.clearfix {
  clear: both;
}
>>> .el-pager li.number {
  color: #999;
}
>>> .el-pager li.number.active {
  color: #409eff;
}
>>> .el-pagination__total,
>>> .el-pagination__jump {
  color: #333;
}
.dialog-import >>> .el-table th:first-child .cell {
  padding-left: 14px;
}
.dialog-import >>> .el-table td {
  padding: 6px 0;
}
.info {
  color: #990;
  margin-bottom: 10px;
}
>>> .el-form-item label {
  color: #ffe329;
}
.text-right {
  text-align: right;
}
.tag {
  position: relative;
  z-index: 1;
  color: #fff;
  height: 22px;
  line-height: 20px;
  border: 1px #ccc solid;
  border-radius: 4px;
  background: #999;
}
.tag.success {
  /* color: #59acff; */
  box-shadow: 0 0 10px -2px #0e0;
}
.tag.error {
  /* color: #f00; */
  box-shadow: 0 0 2px 1px #ff0000;
}
/* 进度 */
.progress-bar > span {
  position: absolute;
  bottom: 110%;
  left: 100%;
  /* display: inline-block; */
  white-space: nowrap;
  /* margin-left: -100%; */
  -webkit-transform: translate(calc(var(--percent) * -1%), 0);
  transform: translate(calc(var(--percent) * -1%), 0);
  background-color: inherit;
  /* background: var(--color); */
  border-radius: 10px;
  padding: 1px 4px;
  font-size: 12px;
}
.progress-bar {
  color: #fff;
  text-shadow: 0 1px 1px rgba(0, 0, 0, 0.6);
  position: absolute;
  top: 0;
  left: 0;
  /* width: 0%; */
  width: calc(var(--percent) * 1%);
  height: 100%;
  /* opacity: 0; */
  /* border: 1px solid; */
  border-radius: 4px;
  background-size: 50px 30px, contain, contain;
  background-position: -20% center, right center, left center;
  background-repeat: no-repeat, no-repeat, no-repeat;
  -webkit-transition: opacity 0.2s ease, width 0.8s ease-out,
    background-color 1s ease, border-color 0.3s ease, box-shadow 1s ease;
  transition: opacity 0.2s ease, width 0.8s ease-out, background-color 1s ease,
    border-color 0.3s ease, box-shadow 1s ease;
  -webkit-animation: pulse 2s linear infinite;
  animation: pulse 2s linear infinite;
  background-color: rgba(85, 182, 101, 0.95);
  background-image: -webkit-linear-gradient(0deg, 10%, 30%, 70%, 80%, 90%),
    -webkit-linear-gradient(left, rgba(251, 31, 49, 0) 0%, #1ffb56 100%),
    -webkit-linear-gradient(right, rgba(251, 31, 49, 0) 0%, #1ffb94 100%);
  background-image: linear-gradient(0deg, 10%, 30%, 70%, 80%, 90%),
    linear-gradient(left, rgba(251, 31, 49, 0) 0%, #1ffb56 100%),
    linear-gradient(right, rgba(251, 31, 49, 0) 0%, #1ffb94 100%);
  border-color: #26a100;
  box-shadow: 0 0 2px #06fa4f inset, 0 0 1px #04e217 inset;
  z-index: -1;
}
.progress--complete.progress-bar {
  background-size: 0 0, contain, contain;
  -webkit-animation: none;
  animation: none;
  border-radius: 2px;
}
.progress--complete.progress-bar:after,
.progress--complete.progress-bar:before {
  opacity: 0;
}
.progress__bar--yellow {
  background-size: 0 0, contain, contain;
  background-color: rgba(180, 123, 0, 0.95);
  background-image: -webkit-linear-gradient(90deg, transparent 60%, #fff 100%),
    -webkit-linear-gradient(0, transparent 70%, #ffbf36 100%),
    -webkit-linear-gradient(180deg, transparent 70%, #ffbf36 100%);
  background-image: linear-gradient(90deg, transparent 60%, #fff 100%),
    linear-gradient(0, transparent 70%, #ffbf36 100%),
    linear-gradient(180deg, transparent 70%, #ffbf36 100%);
  border-color: #ffc74f;
  box-shadow: 0 0 0.6em #ffb71c inset, 0 0 0.4em #ffae02 inset,
    0 0 0.5em rgba(232, 158, 0, 0.5), 0 0 0.1em rgba(255, 248, 232, 0.5);
}
.progress__bar--green {
  background-color: rgba(1, 190, 26, 0.95);
  background-image: -webkit-linear-gradient(90deg, transparent 60%, #fff 100%),
    -webkit-linear-gradient(0, transparent 70%, #00fe21 100%),
    -webkit-linear-gradient(180deg, transparent 70%, #00fe21 100%);
  background-image: linear-gradient(90deg, transparent 60%, #fff 100%),
    linear-gradient(0, transparent 70%, #00fe21 100%),
    linear-gradient(180deg, transparent 70%, #00fe21 100%);
  border-color: #19ff37;
  box-shadow: 0 0 0.6em #00e51e inset, 0 0 0.4em #00cb1a inset,
    0 0 0.5em rgba(0, 178, 23, 0.5), 0 0 0.1em rgba(178, 255, 188, 0.5);
}
.progress__bar--blue {
  background-color: rgb(0, 131, 207);
  background-image: -webkit-linear-gradient(90deg, transparent 60%, #fff 100%),
    -webkit-linear-gradient(0, transparent 70%, #3dacee 100%),
    -webkit-linear-gradient(180deg, transparent 70%, #3dacee 100%);
  background-image: linear-gradient(90deg, transparent 60%, #fff 100%),
    linear-gradient(0, transparent 70%, #3dacee 100%),
    linear-gradient(180deg, transparent 70%, #3dacee 100%);
  border-color: #6abff0;
  box-shadow: 0 0 0.6em #25a2ec inset, 0 0 0.4em #1497e3 inset,
    0 0 0.5em rgba(18, 135, 204, 0.5), 0 0 0.1em rgba(225, 242, 252, 0.5);
}
@-webkit-keyframes pulse {
  0% {
    background-position: -50% center, right center, left center;
  }
  100% {
    background-position: 150% center, right center, left center;
  }
}
@keyframes pulse {
  0% {
    background-position: -50% center, right center, left center;
  }
  100% {
    background-position: 150% center, right center, left center;
  }
}
</style>
src/views/dataTest/historyInfoMager.vue
@@ -186,7 +186,7 @@
</template>
<script>
import { searchProvince, getAllStations, batterySearch } from "@/assets/js/api";
import { searchProvince, getUserStationList, batterySearch } from "@/assets/js/api";
import { dataSeachroms, resActionDelete } from "./js/history";
import { GetMonomerCap, GetHourRate } from "@/assets/js/tools";
// 引入导出表格
@@ -368,7 +368,7 @@
        stationName1: this.UDepartment, //维护区
        battGroupName:
          this.battGroupName == "" || this.battGroupName.indexOf('全部') > -1 ? undefined : this.battGroupName,
        stationId: this.stationId == 0 ? undefined : this.stationId,
        stationId: this.station.stationId == 0 ? undefined : this.station.stationId,
        testType: this.testType,
        recordStartTime: this.startDrsj + " 00:00:00",
        recordEndTime: this.endDrsj + " 23:59:59",
@@ -487,19 +487,13 @@
    },
    // 查询机房站点
    queryStationName() {
      getAllStations({
        stationName1: this.UDepartment,
      getUserStationList({
        stationName1: this.UDepartment || 'null',
      })
        .then((res) => {
          res = res.data;
          if (res.code) {
            // console.log(res, "======res");
            let data = res.data;
            let arr = data.filter((item, idx) => {
              return (
                data.findIndex((i) => i.stationId == item.stationId) == idx
              );
            });
            let arr = res.data;
            arr.unshift({
              stationName: `全部共${arr.length}种`,
              stationId: 0,
src/views/dataTest/js/btsStatus.js
New file
@@ -0,0 +1,12 @@
import axios from "axios";
/**
  * 核容测试机房查询
  * User_battgroup_baojigroup_battgroupAction!serch61850DevidInGroup  // 旧
  */
export const UserBattgroup = () => {
  return axios({
    method: 'GET',
    url: 'BattGroupUser/stationInfoList'
  });
}
src/views/dataTest/js/draw_diagram.js
New file
@@ -0,0 +1,464 @@
import {
  Timeout
} from '@/assets/js/tools';
import screenImage from '../diagram/images/screen.png';
import loadImage from '../diagram/images/load.png';
import battImage from '../diagram/images/elegroup.png';
import chargeImage from '../diagram/images/charge.png';
let Img_screen = new Image();
let Img_load = new Image();
let Img_batt = new Image();
let Img_charge = new Image();
Img_screen.src = screenImage;
Img_load.src = loadImage;
Img_batt.src = battImage;
Img_charge.src = chargeImage;
let timer = new Timeout();
const BALLCOLOR = '#00f7f9';
let list = {
  // 二极管
  'diode_0': {
    x: 720
    , y: 50
    , method: 'drawDiode'
    , isHor: true
    , name: 'D1'
  }
  // 二极管
  , 'diode_1': {
    x: 800
    , y: 254
    , method: 'drawDiode'
  }
  , 'diode_2': {
    x: 800
    , y: 552
    , method: 'drawDiode'
  }
  // 虚线框
  , 'dashline_0': {
    points: [[106, 82], [870, 82], [870, 730], [106, 730], [106, 82]]
    , method: 'drawDashLine'
    , color: '#00f7f9'
    , lineWidth: 4
  }
  // 电阻
  , 'resistance_0': {
    // x: 800
    x: 475
    , y: 180
    , name: 'R1'
    , method: 'drawResistance'
  }
  , 'inductance_0': {
    x: 530
    , y: 420
    , method: 'drawInductance'
    , name: 'L1'
    , color: '#00f7f9'
  }
  , 'rectifier_0': {
    x: 124
    , y: 160
    , name: '充电模块'
    , method: 'drawRectifier'
    , width: 64
    , height: 104
    , img: Img_charge
  }
  , 'rectifier_1': {
    x: 950
    , y: 320
    , name: '整流器'
    , method: 'drawRectifier'
    , width: 80
    , height: 120
    , img: Img_screen
  }
  , 'load_0': {
    x: 1180
    , y: 320
    , method: 'drawLoad'
    , name: '用户负载'
    , width: 80
    , height: 140
    , img: Img_load
  }
  , 'batts_0': {
    x: 30
    , y: 480
    , method: 'drawBatts'
    , name: '电池组'
    , width: 36
    , height: 60
    , distance: 24
    , img: Img_batt
  }
  , 'line_0': {
    points: [[47, 480], [47, 60], [720, 60]]
    , method: 'drawLine'
  }
  , 'line_1': {
    points: [[730, 60], [816, 60]]
    , method: 'drawLine'
  }
  , 'line_2': {
    points: [[884, 60], [1222, 60], [1222, 323]]
    , method: 'drawLine'
  }
  , 'line_3': {
    points: [[1222, 458], [1222, 700], [47, 700], [47, 624]]
    , method: 'drawLine'
  }
  , 'line_4': {
    points: [[154, 162], [154, 120], [296, 120]]
    , method: 'drawLine'
  }
  , 'line_5': {
    points: [[364, 120], [752, 120]]
    , method: 'drawLine'
  }
  , 'line_6': {
    points: [[495, 364], [495, 420]]
    // points: [[805, 276], [805, 420], [724, 420]]
    , method: 'drawLine'
  }
  , 'line_7': {
    points: [[578, 420], [752, 420]]
    , method: 'drawLine'
  }
  , 'line_8': {
    points: [[364, 420], [530, 420]]
    , method: 'drawLine'
  }
  , 'line_9': {
    points: [[47, 420], [296, 420]]
    , method: 'drawLine'
  }
  , 'line_10': {
    points: [[154, 260], [154, 330], [296, 330]]
    , method: 'drawLine'
  }
  , 'line_11': {
    points: [[364, 330], [384, 330], [384, 420]]
    , method: 'drawLine'
  }
  , 'line_12': {
    points: [[752, 120], [752, 216]]
    , method: 'drawLine'
  }
  , 'line_13': {
    points: [[752, 284], [752, 516]]
    , method: 'drawLine'
  }
  , 'line_14': {
    points: [[752, 584], [752, 700]]
    , method: 'drawLine'
  }
  , 'line_15': {
    points: [[752, 196], [810, 196], [810, 244]]
    , method: 'drawLine'
  }
  , 'line_16': {
    points: [[810, 254], [810, 304], [752, 304]]
    , method: 'drawLine'
  }
  , 'line_17': {
    points: [[752, 496], [810, 496], [810, 542]]
    , method: 'drawLine'
  }
  , 'line_18': {
    points: [[810, 552], [810, 604], [752, 604]]
    , method: 'drawLine'
  }
  , 'line_19': {
    points: [[990, 60], [990, 322]]
    , method: 'drawLine'
  }
  , 'line_20': {
    points: [[990, 440], [990, 700]]
    , method: 'drawLine'
  }
  , 'line_21': {
    points: [[495, 120], [495, 180]]
    , method: 'drawLine'
  }
  , 'line_22': {
    points: [[495, 296], [495, 240]]
    , method: 'drawLine'
  }
};
// 画面板
// const drawPanel = (can) => {
//     can.drawRect1({
//         x: 400
//         ,y: 10
//         ,width: 260
//         ,height: 40
//         ,subName: 'title'
//         // ,color: '#f00'
//     }, true);
// }
// 面板位置信息
const panelPos = {
  // title
  title: {
    left: 400
    , top: 10
    , width: 260
    , height: 40
  }
  , batts: {
    left: 116
    , top: 500
    , width: 200
    , height: 84
  }
  , online: {
    left: 1020
    , top: 86
    , width: 200
    , height: 40
  }
  // 电感线圈
  , inductance: {
    left: 530
    , top: 400
    , width: 48
    , height: 22
  }
}
// let ballList = [];
const updateBalls = (can, ballList) => {
  let count = 0;
  return function (ballList) {
    can.updateCanvas();
    // console.log(ballList, '--------');
    for (let i = 0, j = ballList.length; i < j; i++) {
      can.moveBall({
        points: ballList[i].points
        , direction: ballList[i].direction
        , fillStyle: ballList[i].fillStyle
      }, count, ballList[i].ballNum);
    }
    count++;
    count %= can.COUNT;
  }
}
const update = function (callback, stateL, status, ballList) {
  if (!timer.callback) {
    timer.init(function () {
      callback(ballList);
      timer.open();
    }, 1000 / 30);
  }
  // console.log(status, 'status');
  let ctx = stateL.context;
  stateL.clearCanvas();
  // stateL.drawLine(ctx, {
  //     points: [[500, 100], [500, 500], [800, 500]],
  //     color: status.Q1 ? '#00f7f9' : '#ccc'
  // });
  // stateL.drawLine(ctx, {
  //     points: [[480, 200], [480, 600], [780, 600]],
  //     color: status.Q2 ? '#00f7f9' : '#ccc'
  // });
  // 放电电流
  // list1与list3公共的第一部分
  const list0 = [
    { points: [47, 480, 47, 420], direction: status.state == 2 ? 'top' : 'bottom', fillStyle: BALLCOLOR, ballNum: 1 }
  ];
  const list01 = [
    { points: [47, 480, 47, 420], direction: 'top', fillStyle: BALLCOLOR, ballNum: 1 }
  ];
  //放电
  const list1 = [
    { points: [47, 480, 47, 420], direction: 'top', fillStyle: BALLCOLOR, ballNum: 1 }
    , { points: [47, 420, 752, 420], direction: 'right', fillStyle: BALLCOLOR, ballNum: 3 }
    , { points: [752, 420, 752, 700], direction: 'bottom', fillStyle: BALLCOLOR, ballNum: 2 }
  ];
  // 充电
  const list11 = [
    { points: [47, 480, 47, 420], direction: 'bottom', fillStyle: BALLCOLOR, ballNum: 1 }
    , { points: [47, 420, 752, 420], direction: 'left', fillStyle: BALLCOLOR, ballNum: 3 }
    , { points: [752, 604, 752, 700], direction: 'top', fillStyle: BALLCOLOR, ballNum: 1 }
    , { points: [752, 420, 752, 496], direction: 'top', fillStyle: BALLCOLOR, ballNum: 1 }
    , { points: [752, 604, 810, 604], direction: 'right', fillStyle: BALLCOLOR, ballNum: 1 }
    , { points: [752, 496, 810, 496], direction: 'left', fillStyle: BALLCOLOR, ballNum: 1 }
    , { points: [810, 496, 810, 604], direction: 'top', fillStyle: BALLCOLOR, ballNum: 1 }
  ];
  const list2 = [
    { points: [495, 420, 495, 240], direction: 'bottom', fillStyle: BALLCOLOR, ballNum: 2 }
    , { points: [495, 120, 495, 180], direction: 'bottom', fillStyle: BALLCOLOR, ballNum: 1 }
    , { points: [495, 120, 752, 120], direction: 'left', fillStyle: BALLCOLOR, ballNum: 2 }
    , { points: [752, 120, 752, 196], direction: 'top', fillStyle: BALLCOLOR, ballNum: 1 }
    , { points: [810, 196, 752, 196], direction: 'left', fillStyle: BALLCOLOR, ballNum: 1 }
    , { points: [810, 304, 752, 304], direction: 'right', fillStyle: BALLCOLOR, ballNum: 1 }
    , { points: [810, 304, 810, 196], direction: 'top', fillStyle: BALLCOLOR, ballNum: 1 }
    , { points: [752, 304, 752, 420], direction: 'top', fillStyle: BALLCOLOR, ballNum: 1 }
    , { points: [495, 420, 752, 420], direction: 'right', fillStyle: BALLCOLOR, ballNum: 2 }
  ];
  const list3 = [
    { points: [47, 420, 47, 60], direction: 'top', fillStyle: BALLCOLOR, ballNum: 3 }
    , { points: [47, 60, 1222, 60], direction: 'right', fillStyle: BALLCOLOR, ballNum: 4 }
    , { points: [1222, 323, 1222, 60], direction: 'bottom', fillStyle: BALLCOLOR, ballNum: 2 }
    , { points: [1222, 458, 1222, 700], direction: 'bottom', fillStyle: BALLCOLOR, ballNum: 2 }
    , { points: [752, 700, 1222, 700], direction: 'left', fillStyle: BALLCOLOR, ballNum: 2 }
  ];
  // list1与list3公共第二部分
  const list30 = [
    { points: [47, 700, 752, 700], direction: status.state == 2 ? 'left' : 'right', fillStyle: BALLCOLOR, ballNum: 3 }
    , { points: [47, 624, 47, 700], direction: status.state == 2 ? 'top' : 'bottom', fillStyle: BALLCOLOR, ballNum: 1 }
  ];
  const list31 = [
    { points: [47, 700, 752, 700], direction: 'left', fillStyle: BALLCOLOR, ballNum: 3 }
    , { points: [47, 624, 47, 700], direction: 'top', fillStyle: BALLCOLOR, ballNum: 1 }
  ];
  const list4 = [
    { points: [154, 162, 154, 120], direction: 'top', fillStyle: BALLCOLOR, ballNum: 1 }
    , { points: [154, 120, 752, 120], direction: 'right', fillStyle: BALLCOLOR, ballNum: 3 }
    , { points: [752, 420, 752, 120], direction: 'bottom', fillStyle: BALLCOLOR, ballNum: 2 }
    , { points: [752, 420, 384, 420], direction: 'left', fillStyle: BALLCOLOR, ballNum: 2 }
    , { points: [384, 330, 384, 420], direction: 'top', fillStyle: BALLCOLOR, ballNum: 1 }
    , { points: [154, 330, 384, 330], direction: 'left', fillStyle: BALLCOLOR, ballNum: 2 }
    , { points: [154, 330, 154, 260], direction: 'top', fillStyle: BALLCOLOR, ballNum: 1 }
  ];
  // k4闭合 且在线电压高于组端电压时的电流回路
  const list5 = [
    { points: [990, 60, 990, 322], direction: 'top', fillStyle: BALLCOLOR, ballNum: 2 }
    , { points: [990, 60, 1222, 60], direction: 'right', fillStyle: BALLCOLOR, ballNum: 2 }
    , { points: [1222, 60, 1222, 323], direction: 'bottom', fillStyle: BALLCOLOR, ballNum: 2 }
    , { points: [1222, 458, 1222, 700], direction: 'bottom', fillStyle: BALLCOLOR, ballNum: 2 }
    , { points: [990, 700, 1222, 700], direction: 'left', fillStyle: BALLCOLOR, ballNum: 2 }
    , { points: [990, 700, 990, 440], direction: 'top', fillStyle: BALLCOLOR, ballNum: 2 }
  ];
  // console.log('q3, q4, q5', status.Q3, status.Q4, status.Q5);
  // 清空数组 不改变地址;
  ballList.length = 0;
  let Q1 = status.state == 2 && status.isCharge;
  let Q2 = status.state == 2 && !status.isCharge;
  let Q3 = status.main;
  let Q4 = status.state == 4 && status.isCharge;
  let Q5 = status.state == 4 && !status.isCharge;
  stateL.draw_switch({
    x: 300
    , y: 420
    , distance: 60
    , method: 'drawSwitch'
    , isOn: status.state == 2 || status.state == 4
    , name: 'K3'
    // ,description: '80A'
  });
  stateL.draw_switch({
    x: 495
    , y: 300
    , distance: 60
    , method: 'drawSwitch'
    , isOn: status.state == 2
    , name: 'K5'
    // ,description: '80A'
    , direction: 'ver'
  });
  stateL.draw_switch({
    x: 752
    , y: 220
    , distance: 60
    , method: 'drawSwitch'
    , isOn: Q4
    , direction: 'ver'
  });
  stateL.draw_switch({
    x: 752
    , y: 520
    , distance: 60
    , method: 'drawSwitch'
    , isOn: Q1
    , direction: 'ver'
  });
  stateL.draw_switch({
    x: 300
    , y: 120
    , distance: 60
    , method: 'drawSwitch'
    , isOn: status.state == 4
    , name: 'K1'
    // ,description: '80A'
  });
  stateL.draw_switch({
    x: 300
    , y: 330
    , distance: 60
    , method: 'drawSwitch'
    , isOn: status.state == 4
    , name: 'K2'
    // ,description: '80A'
  });
  stateL.draw_switch({
    x: 820
    , y: 60
    , distance: 60
    , method: 'drawSwitch'
    , isOn: Q3
    , name: 'K4'
  })
  if (Q1) {
    ballList.push(...list1, ...list0, ...list30);
    // console.log('q3', ballList);
  }
  if (Q5) {
    ballList.push(...list11, ...list0, ...list30);
  }
  if (Q2) {
    ballList.push(...list2);
  }
  if (Q3) {
    // 如果此时在线电压比组端电压高则回路为整流器到负载 否则为以前的回路
    if (status.onlineVol > status.groupVol) {
      ballList.push(...list5);
    } else {
      ballList.push(...list3, ...list01, ...list31);
    }
  }
  if (Q4) {
    ballList.push(...list4);
  }
  timer.open();
};
const stop = function () {
  timer.stop();
  timer.callback = null;
}
export {
  list
  , panelPos
  // ,resetFirstTime
  // ,drawPanel
  , update
  , updateBalls
  , stop
}
src/views/dataTest/js/history.js
@@ -122,75 +122,27 @@
    params
  })
}
/**
 * 查询历史实时数据
 * TODO
 * @param params    查询参数
 * @returns {AxiosPromise}
 * 查询标准曲线
 * Battmon_testcapAction!serchByCondition // 旧
 */
export const searchHistoryRealtimeData = (params) => {
  // 查询后台
export const searchStandardLine = (data) => {
  return axios({
    method: "post",
    url: "Batt_realdataAction!serchByCondition",
    data: "json=" + JSON.stringify(params)
    method: "POST",
    url: 'Battmon_testcapAction/testCapList',
    data
  });
}
/**
 * 查询LD9测试数据列表
 * Ld9testdata_infAction_ld9action_searchInfList
 * 参数:json={"BattGroupId":1005129}
 * 查询所有的标准曲线
 * {pageNum, pageSize}
 * Battmon_standardcurveAction!serchByCondition // 旧
 */
export const getLD9TestList = (data) => {
export const searchStandardLines = (params) => {
  return axios({
    method: "post",
    url: "Ld9testdata_infAction_ld9action_searchInfList",
    data: 'json=' + JSON.stringify(data)
    method: "GET",
    url: 'battMonStandardCure/page',
    params
  });
}
/**
 * 查询LD9 单体测试数据
 * Ld9testdataAction_ld9action_serchByCondition
 * 参数:json={"BattGroupId":1000061,"test_record_count":39,"record_num":3,"test_monnum":1}
 */
export const getLD9Testdata = (data) => {
  return axios({
    method: "post",
    url: "Ld9testdataAction_ld9action_serchByCondition",
    data: 'json=' + JSON.stringify(data)
  });
}
/**
 * 查询LD9测试组端数据
 * Ld9testdatastopAction_ld9action_serchByInfo
 * 参数:json={"BattGroupId":1000061,"test_record_count":39,"record_num":3,"test_monnum":1}
 */
export const getLD9GrpTestdata = (data) => {
  return axios({
    method: "post",
    url: "Ld9testdatastopAction_ld9action_serchByInfo",
    data: 'json=' + JSON.stringify(data)
  });
}
/**
 * 查询LD9 一次测试中所有单体的实际容量
 * Ld9testdatastopAction_ld9action_serchByCondition
 * 参数:json={"BattGroupId":1000061,"test_record_count":39}
 */
export const getLD9MonCaps = (data) => {
  return axios({
    method: "post",
    url: "Ld9testdatastopAction_ld9action_serchByCondition",
    data: 'json=' + JSON.stringify(data)
  });
}
src/views/dataTest/js/historyAio.js
New file
@@ -0,0 +1,108 @@
import axios from "axios";
/**
 * 查询A059的机房列表
 * BattInfAction!serchAllStationName_8059 // 旧
 */
export const getA059StationList = () => {
  return axios({
    method: "GET",
    url: 'battInf/stationList8059'
  });
}
/**
 * Fgcd_filedownloadAction_action_serchByCondition // 旧
 * 实时查询设备文件下载情况  传参
 * json:{"deviceId":"805900001"}
 * 0 不下载
 * 1 正在下载
 * 2 下载完成
 * -1 下载失败
 */
export const getDownloadInfo = (deviceId) => {
  return axios({
    method: "GET",
    url: 'FGCDFileDownload/listByDeviceId',
    params: {
      deviceId
    }
  });
}
/**
 * Fgcd_filedownloadAction_action_sendCmdToA059_readFile // 旧
 * A059一体机命令操作读取设备文件的cmd和ack校验 file_index页码数
 * 传参json:{"dev_id":"805900001","op_cmd":"161","file_index":"1"}
 */
export const getFileList = (data) => {
  return axios({
    method: "POST",
    url: 'Fgcd_filedownloadAction_action_sendCmdToA059_readFile',
    data: "json=" + JSON.stringify(data)
  });
}
/**
 * Fgcd_filedownloadAction_action_sendCmdToA059_downLoadFile // 旧
 * A059一体机命令操作导入设备文件的cmd和ack校验 BattGroupId 电池组id,file_index文件对应的索引号
 * 传参json:{"dev_id":"805900001","op_cmd":"163","BattGroupId":"1000048""download_flag1":"1","download_flag2":"1","download_flag3":"1", "download_flag4":"1""download_flag5":"1","download_flag6":"1","download_flag7":"1","download_flag8":"1"}
 */
export const importData = (data) => {
  return axios({
    method: "POST",
    url: 'Fgcd_filedownloadAction_action_sendCmdToA059_downLoadFile',
    data: "json=" + JSON.stringify(data)
  });
}
/**
 * Fbotestdata_infAction!serchByCondition // 旧
 * 下拉读取导入数据记录,test_type分充电:2 ,放电:3 ,活化:4
 * 传参 json:{"BattGroupId":"1000007"}
 */
export const getTestList = (data) => {
  return axios({
    method: "GET",
    url: 'FGCDFileDownload/listByDeviceId',
    data: "json=" + JSON.stringify(data)
  });
}
/**
 * FbotestdataAction!serchByCondition // 旧
 * 查询具体某一次放电的详细数据
 * 传参 json:{"test_record_count":"1","BattGroupId":"1000007"}
 */
export const getTestData = (data) => {
  return axios({
    method: "POST",
    url: 'fBOTestDataInf/list',
    data: "json=" + JSON.stringify(data)
  });
}
/**
 * Fbotestdata_infAction!del // 旧
 * 一体机界面查看到导入错误数据,删除
 * json:{"BattGroupId":"1000048","test_record_count":"1"}
 */
export const delTestData = (data) => {
  return axios({
    method: "POST",
    url: 'Fbotestdata_infAction!del',
    data: "json=" + JSON.stringify(data)
  });
}
/**
 * Fgcd_filedownloadAction_action_sendCmdToA059_stopFile // 旧
 * A059一体机命令操作停止下载文件
 * {deviceId}
 * json:{"dev_id":"805900001"}
 */
export const stopImport = (params) => {
  return axios({
    method: "POST",
    url: 'FGCDFileDownload',
    params
  });
}
src/views/dataTest/js/realTimeAio.js
New file
@@ -0,0 +1,78 @@
import axios from 'axios';
/**
 * 实时监控-A059发送指令
 * {devId, opCmd}
 * Fbs9100_setparamAction_action_updateA059Cmd // 旧
 */
export const sendCmd = (params) => {
  return axios({
    method: 'GET',
    url: 'Fbs9100_setparamAction/updateA059Cmd',
    params
  });
}
/**
 * 读取FGCD_A059放电参数
 * Fbs9100_setparamAction_action_searchA059Param  // 旧
 * {devId, opCmd}
 */
export const getParams = (params) => {
  return axios({
    method: 'GET',
    url: 'Fbs9100_setparamAction/searchA059Param',
    params
  });
}
/**
 * 设置FGCD_A059放电参数
 * Fbs9100_setparamAction_action_updateA059Param  // 旧
 */
export const setParams = (data) => {
  return axios({
    method: 'POST',
    url: 'Fbs9100_setparamAction/updateA059Param',
    data
  });
}
/**
 * Fbs9100_setparamAction_action_serchCharHighTmp  // 旧
 * 一体机拓扑图界面添加一个温度报警的设置值  json:{"dev_id":"912000001"}
 */
export const getTempLimit = (devId) => {
  return axios({
    method: 'GET',
    url: 'Fbs9100_setparamAction/serchCharHighTmp',
    params: {
      devId
    }
  });
}
/**
 * Fbs9100_stateAction_action_update_dev_res_test_state  // 旧
 * 一体机烟雾报警确认 json:{"dev_id":"805900001"}
 */
export const confirmAlarm = (devId) => {
  return axios({
    method: 'GET',
    url: 'Fbs9100_stateAction/update_dev_res_test_state',
    params: {
      devId
    }
  });
}
/**
 * Fbs9100_stateAction_action_update_dev_alarmstate  // 旧
 * {"devId":"805900001", num:1}
 * 一体机界面弹出框确认操作 json:{"devId":"805900001", num:1}1确定,0取消
 */
export const confirmStop = (params) => {
  return axios({
    method: 'GET',
    url: 'Fbs9100_stateAction/update_dev_alarmstate',
    params
  });
}
src/views/dataTest/realTimeAio.vue
New file
@@ -0,0 +1,1648 @@
<template>
  <flex-layout direction="row" class="page-real-time" :no-bg="true">
    <!-- 充放电一体机 -->
    <content-box
      style="margin-left: 4px; margin-right: 4px"
      :title="battFullName"
    >
      <div slot="box-tools" class="box-tools">
        <el-tooltip
          class="item"
          effect="dark"
          content="历史数据"
          placement="bottom"
        >
          <i class="iconfont el-icon-jinru" @click="syncPage"></i>
        </el-tooltip>
      </div>
      <flex-layout :no-bg="true">
        <div class="content-header" slot="header" :model="inputs">
          <div class="table-layout">
            <div class="table-row">
              <div class="table-cell text-right w80">电池状态:</div>
              <div class="table-cell">
                <el-input
                  :value="backInputs.batt_state"
                  size="small"
                  :disabled="true"
                ></el-input>
              </div>
              <div class="table-cell text-right w80">端电压:</div>
              <div class="table-cell">
                <el-input
                  :value="backInputs.group_online_vol"
                  size="small"
                  :disabled="true"
                ></el-input>
              </div>
              <div class="table-cell text-right w80">电池电流:</div>
              <div class="table-cell">
                <el-input
                  :value="backInputs.group_curr"
                  size="small"
                  :disabled="true"
                ></el-input>
              </div>
              <div class="table-cell text-right w80">更新日期:</div>
              <div class="table-cell">
                <el-input
                  :value="backInputs.rec_datetime"
                  size="small"
                  :disabled="true"
                ></el-input>
              </div>
            </div>
            <div class="table-row">
              <div class="table-cell text-right w80">测试时长:</div>
              <div class="table-cell">
                <el-input
                  :value="backInputs.batt_test_tlong"
                  size="small"
                  :disabled="true"
                ></el-input>
              </div>
              <div class="table-cell text-right w80">测试容量:</div>
              <div class="table-cell">
                <el-input
                  :value="backInputs.batt_test_cap"
                  size="small"
                  :disabled="true"
                ></el-input>
              </div>
              <div class="table-cell text-right w80">剩余容量:</div>
              <div class="table-cell">
                <el-input
                  :value="backInputs.batt_syrl_cap"
                  size="small"
                  :disabled="true"
                ></el-input>
              </div>
              <div class="table-cell text-right w80">续航时长:</div>
              <div class="table-cell">
                <el-input
                  :value="backInputs.sysc"
                  size="small"
                  :disabled="true"
                ></el-input>
              </div>
            </div>
          </div>
        </div>
        <div class="page-content">
          <div class="page-content-tools" v-if="control.show && isCanTest">
            <el-popover placement="bottom" trigger="hover">
              <div class="hdw-menu-list">
                <ul>
                  <li
                    class="hdw-menu-item"
                    v-if="control.data.startCharge.show"
                  >
                    <a @click="boot('charge')" href="javascript:void(0);"
                      >启动充电</a
                    >
                  </li>
                  <li class="hdw-menu-item" v-if="control.data.stopCharge.show">
                    <a @click="stopCharge" href="javascript:void(0);"
                      >停止充电</a
                    >
                  </li>
                  <li
                    class="hdw-menu-item"
                    v-if="control.data.startDischarge.show"
                  >
                    <a @click="boot('discharge')" href="javascript:void(0);"
                      >启动放电</a
                    >
                  </li>
                  <li
                    class="hdw-menu-item"
                    v-if="control.data.stopDischarge.show"
                  >
                    <a @click="stopDischarge" href="javascript:void(0);"
                      >停止放电</a
                    >
                  </li>
                  <li
                    class="hdw-menu-item"
                    v-if="control.data.startActivate.show"
                  >
                    <a @click="boot('activate')" href="javascript:void(0);"
                      >启动活化</a
                    >
                  </li>
                  <li
                    class="hdw-menu-item"
                    v-if="control.data.stopActivate.show"
                  >
                    <a @click="stopActivate" href="javascript:void(0);"
                      >停止活化</a
                    >
                  </li>
                  <li class="hdw-menu-item" v-if="control.data.clearAlerm.show">
                    <a @click="clearAlerm" href="javascript:void(0);"
                      >清除告警</a
                    >
                  </li>
                  <li class="hdw-menu-item" v-if="control.data.clearAlerm.show">
                    <a @click="showVideoDialog" href="javascript:void(0);"
                      >内窥镜</a
                    >
                  </li>
                  <!-- <li class="hdw-menu-item" v-if="control.data.pause.show">
                                        <a @click="pause(type)" href="javascript:void(0);">暂停{{typeStr}}}</a>
                                    </li> -->
                </ul>
              </div>
              <button class="hdw-btn transparentBtn" slot="reference">
                <span class="light-color">远程管理</span>
                <i class="hdw-icon el-icon-caret-bottom"></i>
              </button>
            </el-popover>
          </div>
          <el-tabs
            v-model="acTabs"
            type="border-card"
            class="flex-layout noborder"
            @tab-click="tabClick"
          >
            <el-tab-pane label="电路拓扑图" class="tab-eleLine" name="eleLine">
              <div class="left">
                <science-box :top="8" class="panel-box" :left="8" no-header>
                  <div class="hdw-state-list table-layout">
                    <div
                      v-for="state in stateList"
                      :key="state.text"
                      v-show="state.show"
                      class="table-row"
                      :class="state.type"
                    >
                      <div class="table-cell text-right">
                        <i
                          v-if="state.icon"
                          class="iconfont"
                          :class="state.icon"
                        ></i
                        >{{ state.text }}
                      </div>
                      <div class="table-cell" v-if="state.name == 'alarm'">
                        <hdw-light class="ywbj" :type="state.value"></hdw-light>
                      </div>
                      <div v-else class="table-cell">
                        {{ state.value }}{{ state.unit }}
                      </div>
                    </div>
                  </div>
                  <!-- 确认烟雾报警 -->
                  <div v-if="confirmBtnShow" class="row">
                    <el-button @click="confirmAlarm" type="primary" size="mini"
                      >确认烟雾报警</el-button
                    >
                  </div>
                </science-box>
                <!-- <science-box :top="8" :left="8" class="panel-box second" no-header>
                                    <div class="hdw-state-list table-layout">
                                    </div>
                                </science-box> -->
              </div>
              <circuit-diagram
                ref="circuitDiagram"
                :width="diagramOpt.width"
                :height="diagramOpt.height"
                wrap-class="wrap"
                :levelArr="['staticL', 'stateL', 'flushL']"
                @ratioChanged="ratioChanged"
                @debugClick="debugClick"
              >
                <div class="info-panel title" :style="getStyle('title', 1)">
                  {{ diagram.desc }}
                </div>
                <div class="info-panel strong" :style="getStyle('batts', 1)">
                  <div class="">{{ inputs.group_vol }} V</div>
                  <div class="">{{ inputs.group_curr }} A</div>
                </div>
                <div class="info-panel strong" :style="getStyle('online', 1)">
                  <div class="">{{ backInputs.devCaptestOnlinevol }} V</div>
                </div>
                <!-- 电感线圈充能动画 -->
                <div
                  :class="[
                    'ani-panel',
                    { charge: flag && isCharge, disCharge: flag && !isCharge },
                  ]"
                  :style="getStyle('inductance', 1)"
                ></div>
                <div
                  slot="mask"
                  v-if="
                    -1 == diagram.type || 1 == diagram.type || 3 == diagram.type
                  "
                  :class="[
                    'mask',
                    'iconfont',
                    {
                      'el-icon-duankailianjie': diagram.type == -1,
                      'el-icon-zanting': diagram.type == 1 || diagram.type == 3,
                    },
                  ]"
                ></div>
              </circuit-diagram>
            </el-tab-pane>
            <el-tab-pane label="电压" name="vol">
              <bar-chart ref="vol" id="vol" unit="V" right-menu></bar-chart>
            </el-tab-pane>
            <el-tab-pane
              label="数据表格"
              name="tblData"
              class="el-table-wrapper"
            >
              <el-table stripe size="small" :data="table.datas" height="100%">
                <el-table-column
                  v-for="header in table.headers"
                  :key="header.prop"
                  :prop="header.prop"
                  :label="header.label"
                  :width="header.width"
                  align="center"
                ></el-table-column>
              </el-table>
            </el-tab-pane>
          </el-tabs>
        </div>
      </flex-layout>
    </content-box>
    <!-- 活化参数设置 -->
    <el-dialog
      :title="dialogTitle"
      width="800px"
      :visible.sync="dialog.show"
      :close-on-click-modal="false"
      top="0"
      class="dialog-center"
      :modal-append-to-body="false"
    >
      <activate-dialog-content
        v-if="dialog.show"
        :type="dialog.type"
        :batt="batt"
        @startok="dialog.show = false"
      ></activate-dialog-content>
    </el-dialog>
    <el-dialog
      title="内窥镜"
      width="800px"
      :visible.sync="videoDialog.show"
      :close-on-click-modal="false"
      top="0"
      class="dialog-center"
      :modal-append-to-body="false"
    >
      <endoscope-video v-if="videoDialog.show"></endoscope-video>
    </el-dialog>
    <!-- 停电放电确认 -->
    <el-dialog
      :title="confirmDialog.title"
      width="480px"
      :visible.sync="confirmDialog.show"
      :close-on-click-modal="false"
      top="0"
      class="dialog-center dialog-confirm"
      :modal-append-to-body="false"
      :close-on-press-escape="false"
      :before-close="confirmStop"
    >
      <div class="content">
        当前设备在线电压低(&lt;51.5V),是否确认停止放电?
      </div>
      <div class="" slot="footer">
        <el-button type="primary" size="mini" @click="confirmStop(1)"
          >确认</el-button
        >
        <el-button type="warning" size="mini" @click="confirmStop(0)"
          >取消</el-button
        >
      </div>
    </el-dialog>
  </flex-layout>
</template>
<script>
import ContentBox from "@/components/ContentBox";
import BarChart from "@/components/chart/BarChart";
import ActivateDialogContent from "./components/activateDialogContent";
import {
  realTimeSearch,
  realTimeGroup,
  realTimePowerOff,
  realTimeAlarm,
  clearWarn
} from "./js/realTime";
import {
  getBattGroupInfo
} from '@/views/dataMager/js/battGroupMager';
import {
  Timeout,
  getBarNum,
  sethoubeiTime,
  formatSeconds,
  isHasPermit,
} from "@/assets/js/tools";
import {
  list,
  panelPos,
  // ,resetFirstTime
  update,
  updateBalls,
  stop,
} from "./js/draw_diagram";
import getMarkLineData from "@/components/chart/js/getMarkLineData";
import CircuitDiagram from "@/components/diagram/diagram";
import ScienceBox from "@/components/ScienceBox";
import Diagram from "@/components/diagram/js/diagram";
import common from "@/components/diagram/js/common";
let interval = common.interval;
import { const_aio } from "@/assets/js/const";
// import RtmpVideo from "@/components/rtmpVideo";
import EndoscopeVideo from "./components/endoscopeVideo";
import HdwLight from "@/components/HdwLight.vue";
import {
  sendCmd,
  confirmAlarm,
  getTempLimit,
  confirmStop,
} from './js/realTimeAio';
let vol, resChart, conduct, currChart, leakVol;
let staticL, stateL, flushL;
let tblData = [];
let ballList = [];
export default {
  name: "realTimeAio",
  components: {
    EndoscopeVideo,
    // RtmpVideo,
    ContentBox,
    BarChart,
    ScienceBox,
    ActivateDialogContent,
    CircuitDiagram,
    HdwLight,
  },
  watch: {
    "$route.params.battGroupId"(battGroupId) {
      // console.log('watch', battGroupId);
      this.$nextTick(() => {
        this.getBattGroupInfo(battGroupId);
      });
    },
    "$store.state.theme.collapse"() {
      //   console.log(123);
      this.$nextTick(() => {
        this.resize();
      });
    },
    "diagram.type"(n) {
      if (n == 2 || n == 4) {
        this.flag = true;
        this.resetState();
      } else {
        this.flag = false;
      }
    },
  },
  data() {
    let permits = this.$store.state.user.permits;
    let isCanTest = isHasPermit("batt_test_op_permit", permits);
    let stateList = const_aio.stateList;
    return {
      acTabs: "eleLine",
      isCanTest: isCanTest,
      dialogTitle: "充电参数设置",
      type: "", // 当前状态 charge discharge activate
      moveBall: null,
      stateList: stateList,
      // k4状态
      main: false,
      confirmBtnShow: 0,
      // 上次停止原因
      lastStopReason: "",
      /* 电池状态 模块 组端展示 */
      devCaptestOnlinevol: 0, // 在线模块在线电压
      inputs: {
        group_vol: 0 /* 端电压-组端电压 */,
        online_vol: 0 /* 端电压-在线电压 */,
        group_curr: 0 /* 电池电流 */,
        batt_test_tlong: "0:00:00" /* 测试时长 */,
        rec_datetime: 0 /* 更新日期 */,
        batt_test_cap: 0 /* 测试容量 */,
        batt_rest_cap: 0, // 剩余容量
        batt_state: 0 /* 电池状态 */,
      },
      control: {
        show: true,
        data: {
          startCharge: {
            // 启动充电
            show: true,
            typeShow: false,
            id: 11,
          },
          stopCharge: {
            // 停止充电
            show: true,
            typeShow: false,
            id: 12,
          },
          startDischarge: {
            // 启动放电
            show: true,
            typeShow: false,
            id: 13,
          },
          stopDischarge: {
            // 停止放电
            show: true,
            typeShow: false,
            id: 14,
          },
          startActivate: {
            // 启动活化
            show: true,
            typeShow: false,
            id: 15,
          },
          stopActivate: {
            // 停止活化
            show: true,
            typeShow: false,
            id: 16,
          },
          clearAlerm: {
            show: true,
            typeshow: false,
            id: 17,
          },
        },
      },
      dialog: {
        show: false,
        type: "",
      },
      confirmDialog: {
        show: false,
        title: "停电放电提示",
      },
      timer: new Timeout("movingRingSysteRrealTime"),
      timer2: new Timeout(),
      table: {
        headers: [
          {
            prop: "num1",
            label: "单体编号",
            width: "",
          },
          {
            prop: "vol1",
            label: "电压(V)",
            width: "",
          },
          // {
          //     prop: "temp1",
          //     label: "温度(℃)",
          //     width: ""
          // },
        ],
        datas: [],
      },
      batt: {},
      diagram: {
        update: true,
        type: -1,
        desc: "",
        powerCut: 1,
        temp: 0, // 设备温度
      },
      diagramOpt: {
        width: 1300,
        height: 760,
      },
      sta: {
        Q1: false,
        Q2: false,
        Q3: false,
        Q4: false,
        Q5: false,
      },
      videoDialog: {
        show: false,
      },
      // 储能状态
      isCharge: true,
      count: 0,
      flag: false,
    };
  },
  computed: {
    battFullName() {
      let batt = this.batt;
      if (batt.StationName && batt.battGroupName) {
        return batt.StationName + "-" + batt.battGroupName;
      }
      return "电池组全称";
    },
    backInputs() {
      const obj = {
          0: "未知",
          1: "浮充",
          2: "充电",
          3: "放电",
          4: "均充",
        },
        list = {
          batt_state: "未知",
          group_online_vol: "在线:0.00V; 组端:0.00V",
          devCaptestOnlinevol: 0, // 在线模块在线电压
          group_curr: "0.00A",
          rec_datetime: "1982-01-01 00:00:00",
          batt_test_tlong: formatSeconds(0),
          batt_test_cap: "0Ah",
          batt_syrl_cap: "---",
          sysc: "------",
        };
      if (this.diagram.type == -1) {
        return list;
      }
      let batt_state_text = this.diagram.powerCut
        ? "停电放电"
        : obj[this.inputs.batt_state];
      list.batt_state = batt_state_text + "(" + this.diagram.desc + ")";
      list.group_online_vol = `在线:${this.inputs.online_vol.toFixed(
        2
      )}V; 组端:${this.inputs.group_vol.toFixed(2)}V`;
      list.group_curr = this.inputs.group_curr.toFixed(2) + "A";
      list.rec_datetime = this.inputs.rec_datetime;
      list.batt_test_tlong = formatSeconds(this.inputs.batt_test_tlong);
      list.devCaptestOnlinevol = this.devCaptestOnlinevol;
      list.batt_test_cap = this.inputs.batt_test_cap.toFixed(1) + "AH";
      if (this.inputs.batt_state === 2) {
        list.batt_syrl_cap = "---";
      } else {
        list.batt_syrl_cap = this.inputs.batt_rest_cap.toFixed(1) + "AH";
      }
      if (this.inputs.batt_state === 3) {
        list.sysc = sethoubeiTime(
          parseFloat(this.inputs.batt_rest_cap) /
            parseFloat(this.inputs.group_curr)
        );
      } else {
        list.sysc = "------";
      }
      return list;
    },
  },
  methods: {
    resize() {
      // if(this.acTabs === "powerInfo") {
      //     this.powerInfoChartResize();
      // }else {
      //     this.$G.chartManage.resize(this.acTabs);
      // }
      this.$G.chartManage.resize(this.acTabs);
    },
    tabClick(tab) {
      // 根据tab更新电路图
      if (this.acTabs === "eleLine") {
        this.$refs.circuitDiagram.resizeHandle();
        this.timer2.restart();
      } else {
        this.timer2.stop();
      }
      // 更新图表
      this.setChart();
      // 重置图表的大小
      this.$nextTick(() => {
        this.resize();
        // 设置表格的数据
        if (this.acTabs == "tblData") {
          this.table.datas = tblData;
        }
      });
    },
    initChart() {
      // 电压
      vol = {
        title: {
          show: true,
          text: "最大值=0V;最小值=0V;平均值=0V",
          x: "center",
          textStyle: {
            fontSize: "14",
          },
        },
        series: [
          {
            name: "电压",
            type: "bar",
            data: [],
            markLine: {
              data: getMarkLineData(),
            },
          },
        ],
      };
      // 漏液电压
      leakVol = {
        title: {
          show: true,
          text: "最大值=0V;最小值=0V;平均值=0V",
          x: "center",
          textStyle: {
            fontSize: "14",
          },
        },
        series: [
          {
            name: "漏液电压",
            type: "bar",
            data: [],
          },
        ],
      };
      // 内阻
      resChart = {
        title: {
          show: true,
          text: "最大值=0mΩ;最小值=mΩ;平均值=0mΩ",
          x: "center",
          textStyle: {
            fontSize: "14",
          },
        },
        series: [
          {
            name: "内阻",
            type: "bar",
            data: [],
            markLine: {
              data: getMarkLineData(),
            },
          },
        ],
      };
      // 电导
      conduct = {
        title: {
          show: true,
          text: "最大值=0;最小值=0;平均值=0",
          x: "center",
          textStyle: {
            fontSize: "14",
          },
        },
        series: [
          {
            name: "电导",
            type: "bar",
            data: [],
            markLine: {
              data: getMarkLineData(),
            },
          },
        ],
      };
      // 均衡电流
      currChart = {
        title: {
          show: true,
          text: "最大值=0mA;最小值=0mA;平均值=0mA",
          x: "center",
          textStyle: {
            fontSize: "14",
          },
        },
        series: [
          {
            name: "均衡电流",
            type: "bar",
            data: [],
          },
        ],
      };
      // 设置配置项
      this.setChart();
    },
    setChart() {
      let acTabs = this.acTabs;
      switch (acTabs) {
        case "vol":
          this.$refs.vol.setOption(vol);
          break;
      }
    },
    getBattGroupInfo(battGroupId) {
      // console.log(battGroupId, 'battGroupId');
      getBattGroupInfo(battGroupId)
        .then((res) => {
          res = res.data;
          if (res.code) {
            this.leafClick(res.data[0]);
          } else {
            this.$layer.msg("未获取到电池组的信息");
          }
        })
        .catch((error) => {
          console.log(error);
        });
    },
    leafClick(data) {
      this.batt = data;
      this.diagram.desc = "";
      this.realTimeAlarmss();
      // 开启循环请求
      this.startTimer();
    },
    realTimeAlarmss() {
      var batt = this.batt;
      realTimeAlarm({
        devId: batt.fbsdeviceId,
      }).then((res) => {
        res = res.data;
        if (res.code) {
          let list = res.data.list;
          // 单体电压
          this.setChartMarkLine(vol, "Voltage", "Batt_Alarm_Type_MonVol", list);
        }
      });
    },
    setChartMarkLine(chartData, name, alm_name, list) {
      let batt = this.batt;
      // 遍历list
      for (let i = 0; i < list.length; i++) {
        let item = list[i];
        if (item.alm_name == alm_name) {
          let high = 0;
          let low = 0;
          switch (name) {
            case "Voltage": // 电压告警
              //单体电压
              let std_mon_vol = batt.MonVolStd;
              high = parseFloat(std_mon_vol * item.alm_high_coe).toHold(3);
              low = parseFloat(std_mon_vol * item.alm_low_coe).toHold(3);
              break;
            case "Temperature":
              //单体温度
              let std_mon_tmp = 25;
              high = parseFloat(std_mon_tmp * item.alm_high_coe).toHold(1);
              low = parseFloat(std_mon_tmp * item.alm_low_coe).toHold(1);
              break;
          }
          // 低告警
          chartData.series[0].markLine.data[0].yAxis = low;
          // 高告警
          chartData.series[0].markLine.data[1].yAxis = high;
          break;
        }
      }
    },
    /* echars图表 */
    realTimeSearch() {
      var batt = this.batt;
      realTimeSearch({
        battGroupId: batt.battGroupId,
      }).then((res) => {
        res = res.data;
        let data = [];
        if (res.code) {
          let temp0 = const_aio.getItemByName("temp0", this.stateList).value;
          data = res.data.list.map((item, i) => {
            if (i < 3) {
              // console.log('===', temp0, 'temp0', item.monTmp);
              // this.stateList[i + 2].value = item.monTmp;
              this.setStateList(
                "temp" + (i + 1),
                item.monTmp,
                item.monTmp > temp0 ? "alarm" : ""
              );
            }
            return {
              num1: "#" + item.monNum,
              vol1: item.monVol,
              res1: item.monRes,
              temp1: item.monTmp,
              conduct1: item.monRes
                ? ((1 / item.monRes) * 1000).toFixed(0)
                : 0,
              curr1: item.monJhCurr,
              leakVol1: item.monLyVol,
            };
          });
        }
        // 更新表格
        if (this.acTabs == "tblData") {
          this.table.datas = data;
        } else {
          tblData = data;
        }
        // 电压值
        let volTempVol = [];
        if (res.code) {
          volTempVol = res.data.list.map((item) => {
            return ["#" + item.monNum, item.monVol];
          });
        }
        let volBarNum = getBarNum(volTempVol);
        vol.title.text =
          "最大值=" +
          volBarNum.max.toFixed(2) +
          "V;最小值=" +
          volBarNum.min.toFixed(2) +
          "V;平均值=" +
          volBarNum.avg.toFixed(2) +
          "V";
        vol.series[0].data = volTempVol;
        // 更新电压图表
        this.setChart();
      });
    },
    // 向父级发送同步页面的指令
    syncPage() {
      let batt = this.batt;
      let search =
        "?province=" +
        batt.StationName1 +
        "&city=" +
        batt.StationName2 +
        "&county=" +
        batt.StationName5 +
        "&home=" +
        batt.StationName3 +
        "&batt=" +
        batt.battGroupId;
      window.parent.postMessage(
        {
          cmd: "syncPage",
          params: {
            pageInfo: {
              label: "历史数据",
              name: "history",
              src: "#/history" + search,
              closable: true,
            },
          },
        },
        "*"
      );
    },
    // 设置stateList的值
    setStateList(name, value, type, show) {
      show = undefined === show ? true : show;
      let stateList = this.stateList;
      for (let i = 0; i < stateList.length; i++) {
        let state = stateList[i];
        if (state.name == name) {
          state.value = value;
          state.type = type ? type : "";
          state.show = show;
        }
      }
    },
    /* 实时组端信息 */
    realTimeGroupss() {
      var batt = this.batt;
      realTimeGroup(batt.battGroupId).then((res) => {
        let rsa = JSON.parse(res.data.result);
        // console.log(rsa, '??', rsa.data[0]);
        if (rsa.code == 1) {
          this.inputs = rsa.data[0];
          // console.log(this.inputs.rec_datetime, '更新时间');
        }
      });
    },
    /* 查询电路图开关状态和信息 */
    realTimePowerOffs() {
      let batt = this.batt;
      // 查询后台数据
      realTimePowerOff({
        devId: batt.fbsdeviceId,
      }).then((res) => {
        res = res.data;
        let outTime = 2 * 60; //设备超时时间(2分钟)
        let isOutTime = true; //通讯中断        判断设备是否通讯中断    true:中断    false:正常
        if (res.code) {
          let data = res.data;
          console.log(data, '=========2');
          // 烟感报警 > 0为报警状态
          // this.stateList[4].value = data.devTemp > 0 ? 1 : 0;
          this.setStateList("alarm", data.devTemp > 0 ? 1 : 0);
          this.confirmBtnShow = data.devResTestState;
          // 当值大于0x80之后 这边需要减去0x80之后再对应下表并把上次停止原因标红
          let reason = data.devLastCaptestStopType;
          let alarm = false;
          if (reason > 0x80) {
            alarm = true;
            reason -= 0x80;
          }
          this.setStateList(
            "stopreason",
            const_aio.stopreasons[reason],
            alarm ? "alarm" : ""
          );
          // console.log(data, 'rt');
          // 如果devAlarmstate的值为1则弹窗
          if (data.devAlarmstate == 1) {
            this.confirmDialog.show = true;
          }
          // 判断是否超时
          var nowTime = new Date(data.note).getTime(); //当前时间
          var record = new Date(data.recordDatetime).getTime();
          if (Math.abs(nowTime - record) / 1000 > outTime) {
            this.disconnect();
          } else {
            // 未超时执行逻辑
            // 基础信息
            this.setEquipBase(data);
            this.diagram.powerCut = 0;
            //
            this.diagram.type = data.devWorkstate;
            // 活化状态
            let workstates =
              (data.devBattXuhangTlong > 0 ? "活化 " : "") +
              const_aio.workstates[data.devWorkstate];
            this.diagram.desc = workstates;
            this.setStateList("workState", workstates);
            // 活化阶段
            if (data.devBattXuhangTlong > 0) {
              let str =
                data.devRestestMonindex + "/" + data.devRestestMoncount;
              this.setStateList("activateCounter", str, "", true);
            } else {
              this.setStateList("activateCounter", "", "", false);
            }
            // 如果是充电 则显示充电类型
            if (data.devWorkstate == 4) {
              let chargeType = const_aio.chargeType[data.devEachgroupBattsum];
              this.setStateList("chargeType", chargeType, "", true);
            } else {
              this.setStateList("chargeType", "", "", false);
            }
            this.main = !data.battOnlineState;
            this.devCaptestOnlinevol = data.devCaptestOnlinevol;
          }
        } else {
          // 设备处于未连接
          this.disconnect();
        }
      });
    },
    disconnect() {
      // 设备未连接
      this.diagram.type = -1;
      this.setStateList("workState", "未连接");
      this.diagram.desc = "设备未连接";
      this.main = false;
    },
    // 基础信息
    setEquipBase(data) {
      // 设备的温度
      this.diagram.temp = data.devTemp;
    },
    startTimer() {
      this.timer.start(() => {
        this.$axios
          .all([
            this.realTimeSearch(),
            this.realTimeGroupss(),
            this.realTimePowerOffs(),
            this.getTempLimit(),
          ])
          .then(() => {
            this.timer.open();
          })
          .catch(() => {
            this.timer.open();
          });
      }, 3000);
    },
    // 获取温度报警阀值
    getTempLimit() {
      getTempLimit(this.batt.fbsdeviceId)
        .then((res) => {
          res = JSON.parse(res.data.result);
          // this.setStateList('temp0', 1);
          // console.log(res, '==res');
          if (res.code) {
            this.setStateList("temp0", res.data[0].CharHighTmp);
          }
        })
        .catch((err) => {
          console.error(err);
        });
    },
    monitorPage() {
      // 获取缓存的session
      let name = sessionStorage.getItem("acTabs");
      // console.log(name, 'session acTabs');
      if (name === "movingRingSystemRealTime" && this.acTabs === "eleLine") {
        this.diagram.update = true;
      } else {
        this.diagram.update = false;
      }
      // 启动监控
      requestAnimationFrame(() => {
        this.monitorPage();
      });
    },
    stopCharge() {
      // console.log('stopcharge');
      this.$layer.confirm(
        "停止充电",
        {
          icon: 3,
        },
        (index) => {
          // 关闭询问层
          this.$layer.close(index);
          sendCmd({
              devId: this.batt.fbsdeviceId,
              op_cmd: const_aio.cmd.stopCharge,
            })
            .then((res) => {
              res = JSON.parse(res.data.result);
              // console.log(res, 'res');
              if (res.code) {
                this.$layer.msg("停止充电成功!");
              } else {
                this.$layer.msg("停止充电失败!");
              }
            })
            .catch((err) => {
              console.log(err);
              this.$layer.msg("停止充电失败, 请求异常!");
            });
        }
      );
    },
    stopDischarge() {
      // console.log('stopdischarge');
      this.$layer.confirm(
        "停止放电",
        {
          icon: 3,
        },
        (index) => {
          // 关闭询问层
          this.$layer.close(index);
          sendCmd({
              devId: this.batt.fbsdeviceId,
              op_cmd: const_aio.cmd.stopDisCharge,
            })
            .then((res) => {
              res = JSON.parse(res.data.result);
              // console.log(res, 'res');
              if (res.code) {
                this.$layer.msg("停止放电成功!");
              } else {
                this.$layer.msg("停止放电失败!");
              }
            })
            .catch((err) => {
              console.log(err);
              this.$layer.msg("停止放电失败, 请求异常!");
            });
        }
      );
    },
    stopActivate() {
      // console.log('stopActivate');
      this.$layer.confirm(
        "停止活化",
        {
          icon: 3,
        },
        (index) => {
          // 关闭询问层
          this.$layer.close(index);
          sendCmd({
              devId: this.batt.fbsdeviceId,
              op_cmd: const_aio.cmd.stopActivate,
            })
            .then((res) => {
              res = JSON.parse(res.data.result);
              // console.log(res, 'res');
              if (res.code) {
                this.$layer.msg("停止活化成功!");
              } else {
                this.$layer.msg("停止活化失败!");
              }
            })
            .catch((err) => {
              console.log(err);
              this.$layer.msg("停止活化失败, 请求异常!");
            });
        }
      );
    },
    // 启动
    boot(type) {
      // console.log(type);
      switch (type) {
        case "charge":
          this.dialogTitle = "充电参数设置";
          break;
        case "discharge":
          this.dialogTitle = "放电参数设置";
          break;
        case "activate":
          this.dialogTitle = "活化参数设置";
          break;
      }
      this.dialog.type = type;
      this.dialog.show = true;
    },
    // 暂停
    // ,pause (type) {
    //     console.log('暂停', type)
    // }
    clearAlerm() {
      // console.log('clearAlerm');
      // 清除告警
      this.$layer.confirm(
        "清除设备告警",
        {
          icon: 3,
          title: "系统提示",
        },
        (index) => {
          // 关闭弹出框
          this.$layer.close(index);
          // 开启加载等待
          let load = this.$layer.loading(1);
          // 执行清除告警
          let batt = this.batt;
          clearWarn(batt.fbsdeviceId)
            .then((res) => {
              let rs = JSON.parse(res.data.result);
              // console.log('??', rs);
              if (res.code) {
                this.$layer.msg("清除设备告警成功!");
              } else {
                this.$layer.msg("清除设备告警失败!");
              }
              // 关闭等待
              this.$layer.close(load);
            })
            .catch((error) => {
              console.log(error);
              // 关闭等待
              this.$layer.close(load);
            });
        }
      );
    },
    ratioChanged(ratio) {
      // console.log(ratio);
      staticL && staticL.setRatio(ratio);
      flushL && flushL.setRatio(ratio);
      stateL && stateL.setRatio(ratio);
    },
    init() {
      // console.log(this.$refs.circuitDiagram);
      let circuitDiagram = this.$refs.circuitDiagram;
      // console.log(circuitDiagram.$refs.staticL[0]);
      // debugger;
      let opts = {
        count: 60,
      };
      staticL = new Diagram(circuitDiagram.$refs.staticL[0], opts);
      stateL = new Diagram(circuitDiagram.$refs.stateL[0], opts);
      flushL = new Diagram(circuitDiagram.$refs.flushL[0], opts);
      this.moveBall = updateBalls(flushL, ballList);
    },
    drawStatic() {
      staticL.importObjList(list);
      // drawPanel(staticL);
      staticL.drawAll();
    },
    drawFlush() {},
    // 调试时的点击
    debugClick(o) {
      let point = {
        x: o.offsetX,
        y: o.offsetY,
      };
      let inObj = staticL.mousePointInObj([point.x, point.y], undefined);
      let canvas_obj_id_arr = staticL.getObjIdArr();
      let canvas_obj = staticL.getObjList();
      if (inObj) {
        for (let i = 0, j = canvas_obj_id_arr.length; i < j; i++) {
          let id = canvas_obj_id_arr[i];
          let _inObj = staticL.mousePointInObj([point.x, point.y], id);
          if (_inObj) {
            let _obj = canvas_obj[id];
            console.log("----obj", _obj, id);
            break;
          }
        }
      }
    },
    loop() {
      this.timer2.start(() => {
        // console.log('loop');
        this.count++;
        // 两秒切换一次状态
        if (this.count == 2) {
          this.count = 0;
          this.isCharge = !this.isCharge;
        }
        update(
          this.moveBall,
          stateL,
          {
            state: this.diagram.type,
            main: this.main,
            onlineVol: this.backInputs.devCaptestOnlinevol,
            groupVol: this.inputs.group_vol,
            isCharge: this.isCharge,
          },
          ballList
        );
        this.timer2.open();
      }, 1000);
    },
    getStyle(type) {
      if (!staticL) {
        return {};
      }
      let pos = panelPos[type];
      let ratio = staticL.ratio;
      return {
        top: pos.top * ratio + "px",
        left: pos.left * ratio + "px",
        width: pos.width * ratio + "px",
        height: pos.height * ratio + "px",
      };
    },
    showVideoDialog() {
      this.videoDialog.show = true;
    },
    // 确认烟雾告警
    confirmAlarm() {
      confirmAlarm(this.batt.fbsdeviceId)
        .then((res) => {
          res = JSON.parse(res.data.result);
          // console.log(res, 'confirm');
        })
        .catch((err) => {
          console.error(err);
        });
    },
    // 停电放电确定
    confirmStop(num) {
      // console.trace('confirm');
      // console.log(num, '==');
      num = typeof num == "function" ? 0 : num;
      let loading = this.$layer.loading(1);
      confirmStop({
          devId: this.batt.fbsdeviceId,
          num: num,
        })
        .then((res) => {
          this.$layer.close(loading);
          res = JSON.parse(res.data.result);
          // console.log(num, res);
          if (res.code) {
            this.confirmDialog.show = false;
          }
          this.$layer.msg(res.msg);
        })
        .catch((err) => {
          this.$layer.close(loading);
          console.error(err);
        });
    },
    resetState() {
      this.count = 0;
      this.isCharge = true;
    },
  },
  mounted() {
    // console.log(this.$route.params, 'mounted');
    let battGroupId = this.$route.params.battGroupId;
    this.getBattGroupInfo(battGroupId);
    this.initChart();
    this.$nextTick(() => {
      this.$G.chartManage.resize(this.acTabs);
    });
    // 屏幕缩放时触发
    window.addEventListener("resize", this.resize);
    // 监控是否已经切换到当前页面
    this.monitorPage();
    this.init();
    interval(this.drawStatic, 100, 50);
    // this.drawStatic();
    this.loop();
    this.timer2.open();
  },
  beforeDestroy() {
    this.timer2.stop();
    stop();
  },
};
</script>
<style scoped>
.page-real-time {
  color: #ffffff;
}
.table-row .table-cell {
  padding-top: 12px;
  vertical-align: middle;
}
.page-content {
  position: relative;
  padding-top: 8px;
  padding-bottom: 2px;
  box-sizing: border-box;
  height: 100%;
}
.page-content-tools {
  position: absolute;
  top: 14px;
  right: 8px;
  z-index: 99;
}
.hdw-btn {
  display: inline-block;
  color: #fff;
  background-color: #409eff;
  border-color: #409eff;
  line-height: 1;
  white-space: nowrap;
  cursor: pointer;
  -webkit-appearance: none;
  text-align: center;
  box-sizing: border-box;
  outline: none;
  margin: 0;
  transition: 0.1s;
  font-weight: 500;
  -webkit-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
  user-select: none;
  padding: 6px 10px;
  font-size: 14px;
  border-radius: 4px;
}
.hdw-btn:hover {
  background-color: #3c91e6;
}
.hdw-menu-list {
  border: 1px solid #409eff;
}
.hdw-menu-list .hdw-menu-item {
  border-top: 1px solid #0e5194;
}
.hdw-menu-list .hdw-menu-item:first-child {
  border-top: none;
}
.hdw-menu-item a {
  display: block;
  text-align: center;
  padding: 8px;
  color: #ffffff;
  cursor: pointer;
  background-color: rgba(30, 125, 219, 0.767);
}
.hdw-menu-item a:hover {
  background-color: rgb(60, 135, 211);
}
.hdw-menu-item a:active {
  background-color: rgb(34, 100, 167);
}
.info-panel {
  position: absolute;
  text-align: left;
  /* background: #999; */
}
.info-panel.title {
  text-align: right;
  font-size: 18px;
}
.info-panel.strong {
  font-size: 22px;
  color: #ffe329;
  font-weight: bold;
}
>>> .wrap {
  /* background: rgba(66, 66, 66, 1); */
}
.mask {
  position: absolute;
  left: 0;
  top: 0;
  right: 0;
  bottom: 0;
  background: rgba(0, 0, 0, 0.4);
  display: flex;
  justify-content: center;
  align-items: center;
  font-size: 140px;
  color: rgba(200, 200, 200, 0.6);
}
.panel-box {
  position: relative;
  display: inline-block;
  align-self: flex-start;
}
.tab-eleLine {
  display: flex;
}
>>> .hdw-light-wrapper {
  justify-content: start;
}
.row {
  text-align: center;
  margin-top: 6px;
}
.alarm .table-cell {
  /* color: #ff5503; */
  color: transparent !important;
  -webkit-animation: ani 1s infinite;
  animation: ani 1s infinite;
  text-shadow: 0 0 0 #ff5503;
}
.left {
  display: inline-block;
}
.second .table-row .table-cell {
  padding-top: 0;
}
.ywbj {
  height: 2.5rem;
}
.ywbj >>> .hdw-light {
  transform: scale(1.6, 1.6);
}
.dialog-confirm >>> .el-dialog {
  background: #fff;
}
.dialog-confirm .content {
  padding: 10px;
}
.ani-panel {
  position: absolute;
}
.ani-panel::before {
  content: "";
  position: absolute;
  background: rgb(127, 255, 127);
  left: 0;
  top: 0;
  height: 100%;
  width: 0;
  opacity: 0.8;
}
.ani-panel.charge::before {
  -webkit-animation: charge 2s linear forwards;
  animation: charge 2s linear forwards;
}
.ani-panel.disCharge::before {
  -webkit-animation: disCharge linear 2s forwards;
  animation: disCharge 2s linear forwards;
}
.ani-panel::after {
  content: "";
  position: absolute;
  top: 140%;
  left: 0;
  width: 5em;
  text-align: left;
  color: #00f7f9;
  font-size: 16px;
}
.ani-panel.charge::after {
  content: "储能中...";
}
.ani-panel.disCharge::after {
  content: "释放中...";
  color: #ccc;
}
@-webkit-keyframes charge {
  0% {
    width: 0;
    background: rgb(127, 255, 127);
  }
  50% {
    background: rgb(49, 184, 49);
    width: 50%;
  }
  100% {
    background: rgb(0, 255, 0);
    width: 100%;
  }
}
@keyframes charge {
  0% {
    background: rgb(127, 255, 127);
    width: 0;
  }
  50% {
    background: rgb(49, 184, 49);
    width: 50%;
  }
  100% {
    background: rgb(0, 255, 0);
    width: 100%;
  }
}
@-webkit-keyframes disCharge {
  0% {
    background: rgb(0, 255, 0);
    width: 100%;
  }
  50% {
    background: rgb(49, 184, 49);
    width: 50%;
  }
  100% {
    background: rgb(127, 255, 127);
    width: 0;
  }
}
@keyframes disCharge {
  0% {
    background: rgb(0, 255, 0);
    width: 100%;
  }
  50% {
    background: rgb(49, 184, 49);
    width: 50%;
  }
  100% {
    background: rgb(127, 255, 127);
    width: 0;
  }
}
@keyframes ani {
  0%,
  20% {
    /* color: #ff5703; */
    text-shadow: 0 0 0 #ff5503;
  }
  50% {
    /* color: #ff5703b7; */
    text-shadow: 0 0 0 #ff5703b7;
    /* color: rgba(255, 87, 03, 183); */
  }
  80%,
  100% {
    text-shadow: 0 0 0 #ffe329aa;
    /* color: #ffe329aa; */
  }
}
@-webkit-keyframes ani {
  0%,
  20% {
    text-shadow: 0 0 0 #ff5503;
    /* color: #ff5703; */
  }
  50% {
    text-shadow: 0 0 0 #ff5703b7;
    /* color: #ff5703b7; */
  }
  80%,
  100% {
    text-shadow: 0 0 0 #ffe329aa;
    /* color: #ffe329aa; */
  }
}
</style>
src/views/dataTest/standardLine.vue
New file
@@ -0,0 +1,336 @@
<template>
  <flex-layout class="container" no-bg>
    <div class="chart-tools-wrapper">
      <el-button size="mini" type="primary" @click="drawer = true"
        >添加标准曲线</el-button
      >
    </div>
    <div class="flex-content-wrapper">
      <div class="flex-content-item" v-for="item in charts" :key="item">
        <line-chart :ref="item" :id="item" unit="V" no-full></line-chart>
      </div>
    </div>
    <el-drawer
      title="我是标题"
      direction="btt"
      :withHeader="false"
      size="80%"
      :visible.sync="drawer"
    >
      <flex-layout no-bg>
        <div class="el-drawer-header" slot="header">
          <el-button
            type="primary"
            size="mini"
            icon="el-icon-view"
            @click="viewLine"
            >标准曲线</el-button
          >
          <el-button
            type="primary"
            size="mini"
            icon="el-icon-refresh"
            @click="refreshPage"
            >刷新</el-button
          >
        </div>
        <div class="el-drawer-content">
          <el-table
            stripe
            size="mini"
            header-row-class-name="header-primary"
            height="100%"
            :data="list"
            @select="tblSelect"
            @select-all="tblSelect"
          >
            <el-table-column type="selection" width="55"> </el-table-column>
            <el-table-column
              prop="monvolstd"
              label="标称电压(V)"
              min-width="150"
              :resizable="false"
              align="center"
            >
            </el-table-column>
            <el-table-column
              prop="moncapstd"
              label="标称容量(AH)"
              min-width="150"
              :resizable="false"
              align="center"
            >
            </el-table-column>
            <el-table-column
              prop="battproducer"
              label="电池品牌"
              min-width="150"
              :resizable="false"
              align="center"
              sortable
            >
            </el-table-column>
            <el-table-column
              prop="battmodel"
              label="电池型号"
              min-width="150"
              :resizable="false"
              align="center"
            >
            </el-table-column>
            <el-table-column
              prop="hourRate"
              label="小时率"
              min-width="150"
              :resizable="false"
              align="center"
            >
            </el-table-column>
          </el-table>
        </div>
        <div class="flex-page-footer" slot="footer">
          <el-pagination
            size="mini"
            :current-page="page.pageCurr"
            :page-sizes="[1, 10, 20, 30, 50, 100]"
            :page-size="page.pageSize"
            layout="total, sizes, prev, pager, next, jumper"
            :total="page.pageAll"
            @current-change="currentChange"
            @size-change="sizeChange"
          ></el-pagination>
        </div>
      </flex-layout>
    </el-drawer>
  </flex-layout>
</template>
<script>
import LineChart from "@/components/chart/LineChart";
import { searchStandardLine, searchStandardLines } from "./js/history";
export default {
  name: "standardLine",
  components: { LineChart },
  chartOption() {
    return {
      title: {
        show: true,
        text: "标准曲线(V)",
        x: "center",
        textStyle: {
          fontSize: "14",
        },
      },
      tooltip: {
        trigger: "axis",
        axisPointer: {
          // 坐标轴指示器,坐标轴触发有效
          type: "line", // 默认为直线,可选为:'line' | 'shadow'
        },
        appendToBody: true,
      },
      grid: {
        left: "1%",
        right: "1%",
        bottom: "2%",
        containLabel: true,
      },
      series: [
        {
          name: "单体电压",
          data: [],
        },
      ],
    };
  },
  data() {
    return {
      drawer: false,
      list: [],
      charts: ["chart1"],
      selectList: [],
      page: {
        pageCurr: 1,
        pageSize: 10,
        pageAll: 0,
      },
    };
  },
  methods: {
    searchData() {
      let loading = this.$layer.loading();
      searchStandardLines({
        pageNum: this.page.pageCurr,
        pageSize: this.page.pageSize,
      })
        .then((res) => {
          // 关闭等待框
          this.$layer.close(loading);
          // 格式化数据
          res = res.data;
          let total = 0;
          let data = [];
          if (res.code) {
            data = res.data.list;
            total = res.data.total;
          }
          this.pageAll = total;
          this.list = data.map((item) => {
            item.hourRate = (item.note ? (1 / item.note).toHold(2) : 0) + "C";
            return item;
          });
        })
        .catch((error) => {
          // 关闭等待框
          this.$layer.close(loading);
          console.log(error);
        });
    },
    currentChange(value) {
      this.page.pageCurr = value;
      this.searchData();
    },
    sizeChange(value) {
      this.page.pageCurr = 1;
      this.page.pageSize = value;
      this.searchData();
    },
    resize() {
      let charts = this.charts;
      for (let i = 0; i < charts.length; i++) {
        let chart = this.$refs[charts[i]][0];
        if (chart) {
          chart.resize();
        }
      }
    },
    setChartOption(list) {
      this.charts = [];
      this.$nextTick(() => {
        let options = list.map((item1, key) => {
          let id = "chart" + key + "Num";
          this.charts.push(id);
          let chartOption = this.$options.chartOption();
          let title = "单体电压(V)";
          chartOption.series[0].data = item1.map((item2) => {
            let hourRate = (item2.note ? (1 / item2.note).toHold(2) : 0) + "C";
            title =
              "标称电压:" +
              item2.monvolstd +
              "V; 标称容量:" +
              item2.moncapstd +
              "AH; 电池品牌:" +
              item2.battproducer +
              "; 电池型号:" +
              item2.battmodel;
            return [item2.testCap, item2.monVol];
          });
          chartOption.title.text = title;
          return {
            id: id,
            option: chartOption,
          };
        });
        // 设置图表数据
        this.$nextTick(() => {
          options.map((item) => {
            this.$refs[item.id][0].setOption(item.option);
          });
        });
      });
      //this.$refs.standardLine.setOption(chartOption);
    },
    refreshPage() {
      // 清空图表
      // 查询数据
      this.searchData();
    },
    tblSelect(data) {
      this.selectList = data;
    },
    viewLine() {
      let searchParams = this.selectList;
      this.searchStandarLine(searchParams, 0, []);
    },
    searchStandarLine(searchParams, index, list) {
      if (searchParams.length > 4) {
        this.$layer.msg("最多选择4条进行查看");
        return;
      }
      if (searchParams.length == 0) {
        this.$layer.msg("请选择要查看的标准曲线");
        return;
      }
      // 获取到全部标准曲线后生成标准曲线
      if (searchParams.length <= index) {
        this.drawer = false;
        this.setChartOption(list);
        return;
      }
      let searchParam = searchParams[index];
      searchParam = {
        ...searchParam,
        monCapStd: searchParam.monCapStd * 1 + "",
        monVolStd: searchParam.monVolStd * 1 + "",
      };
      searchStandardLine(searchParam)
        .then((res) => {
          res = res.data;
          if (res.code) {
            list.push(res.data);
          }
          // 查询
          this.searchStandarLine(searchParams, ++index, list);
        })
        .catch((error) => {
          // 查询
          this.searchStandarLine(searchParams, ++index, list);
        });
    },
  },
  mounted() {
    // 初始化图表
    setTimeout(() => {
      this.$nextTick(() => {
        this.resize();
      });
    }, 100);
    // 查询表格数据
    this.searchData();
    window.addEventListener("resize", this.resize);
  },
  destroyed() {
    window.removeEventListener("resize", this.resize);
  },
};
</script>
<style scoped>
.container {
  position: relative;
}
.chart-tools-wrapper {
  position: absolute;
  top: 16px;
  right: 16px;
  z-index: 10;
}
.el-drawer-content {
  height: 100%;
}
.flex-content-wrapper {
  display: flex;
  flex-direction: column;
  height: 100%;
}
.flex-content-item {
  flex: 1;
}
</style>
vue.config.js
@@ -54,6 +54,13 @@
    // when there are many pages, it will cause too many meaningless requests
    config.plugins.delete('prefetch')
    // swf loader
    config.module.rule('swf')
            .test(/\.swf/)
            .use('url-loader')
            .loader('url-loader')
            .options({ limit: 10000 })
    config
      .when(process.env.NODE_ENV !== 'dev',
        config => {