he wei
2024-07-31 af9733ab928ccc696cc00675fa2b2af85797b47c
UA 电源核容一体机
5个文件已修改
14个文件已添加
5907 ■■■■■ 已修改文件
src/assets/js/tools/regEquipType.js 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/layout/index.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/router/index.js 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/dataTest/components/DischargeDialogContent.vue 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/dataTest/components/DischargeParamsDyhr.vue 623 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/dataTest/components/switchControl.vue 173 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/dataTest/movingRingSystem/index.vue 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/dataTest/realTimeDyhr.vue 3141 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/home/components/svg/svgAcin.vue 193 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/home/components/svg/svgBatts.vue 114 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/home/components/svg/svgBgText.vue 86 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/home/components/svg/svgDiode.vue 139 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/home/components/svg/svgDyhr.vue 873 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/home/components/svg/svgInfo.vue 61 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/home/components/svg/svgPanel.vue 92 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/home/components/svg/svgSwitch.vue 119 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/home/components/svg/svgSwitch3.vue 121 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/home/components/svg/svgTriangle.vue 112 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/test.vue 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/js/tools/regEquipType.js
@@ -44,6 +44,7 @@
        peiWang: /^5100/,   // 配网电源
        ups: /^116/,
        intelDev: /^2100/,  // 智能母联
        dyhr: /^6159/,  // 电源核容一体机
    };
    let effectPtns = [];
    // 数据类型为字符串
src/layout/index.vue
@@ -338,7 +338,7 @@
    },
    handleNextSpeak() {
      if (this.speakSrcList.length == 0) {
        console.log("全部播放完成");
        // console.log("全部播放完成");
        setTimeout(() => {
          this.getVoiceList();
        }, 2000);
src/router/index.js
@@ -756,6 +756,16 @@
        url: '/dataTest/realTimeForIntel'
      },
      component: () => import('@/views/dataTest/intelRealTime.vue')
    },{
      // 电源核容一体机
      path: 'real-time-dyhr/:devId/:stationId',
      name: 'movingRingSystem',
      meta: {
        title: '实时监控',
        icon: '',
        url: '/dataTest/realTimeDyhr'
      },
      component: () => import('@/views/dataTest/realTimeDyhr.vue')
    },]
  }, {
    path: 'history',
src/views/dataTest/components/DischargeDialogContent.vue
@@ -8,6 +8,7 @@
      :is-request="isRequest"
      @close="close"
    ></discharge-params61850>
    <discharge-params-dyhr v-else-if="isDyhr" :batt="batt" @close="close"></discharge-params-dyhr>
    <bts-discharge-params
      v-else-if="regBTS"
      :read-only="readOnly"
@@ -35,6 +36,7 @@
import LdNineParams from "./LdNineParams";
import LdSixParams from "@/views/dataTest/components/LdSixParams.vue";
import DischargeParams9612 from "@/views/dataTest/components/dischargeParams9612.vue";
import DischargeParamsDyhr from "./DischargeParamsDyhr";
export default {
  components: {
      DischargeParams9612,
@@ -44,6 +46,7 @@
    BtsDischargeParams,
    ResTest,
    ResTest9611,
    DischargeParamsDyhr,
  },
  props: {
    batt: {
@@ -89,7 +92,7 @@
        "lithiumPack",
        "BTS9140",
        "li9132",
        "BTS9150"
        "BTS9150",
      ]);
    },
    reg9605() {
@@ -107,6 +110,9 @@
      reg9612() {
          return regEquipType(this.batt.fbsdeviceId, ["BTS9612"]);
      },
    isDyhr() {
      return regEquipType(this.batt.fbsdeviceId, ['dyhr']);
    }
  },
};
</script>
src/views/dataTest/components/DischargeParamsDyhr.vue
New file
@@ -0,0 +1,623 @@
<template>
  <el-form
    ref="ruleForm"
    size="mini"
    label-position="top"
    :model="params"
    :rules="rules"
    class="params-dialog"
  >
    <el-row :gutter="layout.gutter">
      <el-col :span="layout.span">
        <el-form-item label="电池组号">
          <el-select
            v-model="otherParams.groupIndexInFBSDevice"
            disabled
            placeholder="请选择组号"
          >
            <el-option label="蓄电池组1" :value="1"></el-option>
            <el-option label="蓄电池组2" :value="2"></el-option>
          </el-select>
        </el-form-item>
      </el-col>
      <el-col :span="layout.span">
        <el-form-item label="测试类型">
          <el-select
            v-model="params.testCmd"
            :disabled="pReadOnly"
            placeholder="请选择"
          >
            <el-option
              v-for="item in testType"
              :key="item.value"
              :label="item.label"
              :value="item.value"
            ></el-option>
          </el-select>
        </el-form-item>
      </el-col>
      <el-col :span="24">
        <el-form-item label="电池组名称">
          <el-input v-model="otherParams.groupName" readonly></el-input>
        </el-form-item>
      </el-col>
      <el-col :span="layout.span">
        <el-form-item label="设备ID">
          <el-input v-model="otherParams.fbsdeviceId" readonly></el-input>
        </el-form-item>
      </el-col>
      <el-col :span="layout.span">
        <el-form-item label="电池组信息">
          <el-input v-model="otherParams.groupInfo" readonly></el-input>
        </el-form-item>
      </el-col>
      <el-col :span="layout.span">
        <el-form-item :label="disCurrText" prop="disCurr">
          <el-input
            v-model="params.disCurr"
            :readonly="readOnly || pReadOnly"
          ></el-input>
        </el-form-item>
      </el-col>
      <el-col :span="layout.span">
        <el-form-item label="核容时长(1~10000分钟)" prop="disTime">
          <el-input
            v-model="params.disTime"
            :readonly="readOnly || pReadOnly"
          ></el-input>
        </el-form-item>
      </el-col>
      <el-col :span="layout.span">
        <el-form-item label="核容容量(1~2000AH)" prop="disCap">
          <el-input
            v-model="params.disCap"
            :readonly="readOnly || pReadOnly"
          ></el-input>
        </el-form-item>
      </el-col>
      <el-col :span="layout.span">
        <el-form-item label="单体温度上限(10~60℃)" prop="monomertmpHigh">
          <el-input
            v-model="params.monomertmpHigh"
            :readonly="readOnly || pReadOnly"
          ></el-input>
        </el-form-item>
      </el-col>
      <el-col :span="layout.span">
        <el-form-item :label="rangeLabel.groupvolLow" prop="groupvolLow">
          <el-input
            v-model="params.groupvolLow"
            :readonly="readOnly || pReadOnly"
          ></el-input>
        </el-form-item>
      </el-col>
      <el-col :span="layout.span">
        <el-form-item :label="rangeLabel.monomervolLow" prop="monomervolLow">
          <el-input
            v-model="params.monomervolLow"
            :readonly="readOnly || pReadOnly"
          ></el-input>
        </el-form-item>
      </el-col>
      <el-col :span="layout.span">
        <el-form-item label="升压上限(V)">
          <el-input
            v-model="params.dcvolHighLimit"
            :readonly="pReadOnly"
          ></el-input>
        </el-form-item>
      </el-col>
      <el-col :span="layout.span">
        <el-form-item label="充电电流(A)">
          <el-input
            v-model="params.chargeCurrSet"
            :readonly="pReadOnly"
          ></el-input>
        </el-form-item>
      </el-col>
    </el-row>
    <div class="form-footer">
      <!-- <three-btn>清除告警</three-btn> -->
      <template v-if="!pReadOnly">
        <three-btn :disabled="!startTestFlag" @click="startTestCheck"
          >启动测试</three-btn
        >
        <three-btn @click="getParams()">读取</three-btn>
        <three-btn :disabled="!setTestFlag" @click="submitFrom">设定</three-btn>
      </template>
      <three-btn v-else @click="$emit('close')">关闭</three-btn>
      <!--      <three-btn @click="submitFrom">设定</three-btn>-->
    </div>
    <el-dialog
      title="人脸校验"
      width="480px"
      :visible.sync="setFaceShow"
      :close-on-click-modal="false"
      top="0"
      :modal="false"
      class="dialog-center"
      :modal-append-to-body="false"
      :destroy-on-close="true"
    >
      <check-face
        v-if="setFaceShow"
        @checkSuccess="setFaceSuccess"
      ></check-face>
    </el-dialog>
    <el-dialog
      title="人脸校验"
      width="480px"
      :visible.sync="startFaceShow"
      :close-on-click-modal="false"
      top="0"
      :modal="false"
      class="dialog-center"
      :modal-append-to-body="false"
      :destroy-on-close="true"
    >
      <check-face
        v-if="startFaceShow"
        @checkSuccess="startFaceSuccess"
      ></check-face>
    </el-dialog>
  </el-form>
</template>
<script>
import { const_61850 } from "@/assets/js/const";
import { testVal } from "@/assets/js/tools";
import CheckFace from "@/components/checkFace";
import config from "@/assets/js/config";
import {
  btsControl as getParams,
  btsControl as start,
  set61850Params,
} from "../js/realTime";
import { checkUserPwd } from "@/views/login/js/api";
export default {
  components: { CheckFace },
  props: {
    batt: {
      type: Object,
      default() {
        return {};
      },
    },
    // 只读模式 显示参数用
    pReadOnly: {
      type: Boolean,
      default: false,
    },
    isRequest: {
      type: Number,
      default: 0,
    },
    paramData: {
      type: Object,
      default() {
        return {};
      },
    },
  },
  data() {
    let cmd = const_61850.cmd;
    let testType = const_61850.testType;
    let rules = const_61850.dischargeRules;
    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 +
      "(保留三位小数)";
    return {
      // 组号
      groupIdx: "",
      layout: {
        gutter: 16,
        span: 12,
      },
      reason: "",
      setFaceShow: false,
      startFaceShow: false,
      cmd: cmd, // 操作命令
      testType: testType, // 测试类型
      startTestFlag: false, // 启动测试的状态
      setTestFlag: false, // 设置参数的状态
      readOnly: false,
      ranges: {
        groupvolLow: {
          name: "组端电压下限",
          unit: "V",
          min: rules.GroupVol_Low.min,
          max: rules.GroupVol_Low.max,
        },
        monomervolLow: {
          name: "单体电压下限",
          unit: "V",
          min: rules.MonomerVol_Low.min,
          max: rules.MonomerVol_Low.max,
        },
      },
      params: {
        num: 0,
        battGroupId: 0,
        devId: 0, // 设备id
        testCmd: 37, // 测试类型
        disCap: 0, // 核容容量
        disCurr: 0, // 核容电流
        disTime: 0, // 核容时长
        groupvolLow: 0, // 组端电压下限
        monomervolLow: 0, // 单体电压下限
        monomertmpHigh: 0, // 单体温度上限
        dcvolHighLimit: 0, // 升压上限
        chargeCurrSet: 0, // 充电电流
      },
      rules: {
        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",
          },
        ],
        disTime: [
          {
            validator(rule, value, callback) {
              testVal(rule, value, callback, rules.DisTime);
            },
            trigger: "change",
          },
        ],
        groupvolLow: [
          {
            validator(rule, value, callback) {
              testVal(rule, value, callback, rules.GroupVol_Low);
            },
            trigger: "change",
          },
        ],
        monomervolLow: [
          {
            validator(rule, value, callback) {
              testVal(rule, value, callback, rules.MonomerVol_Low);
            },
            trigger: "change",
          },
        ],
        monomertmpHigh: [
          {
            validator(rule, value, callback) {
              testVal(rule, value, callback, rules.MonomerTmp_High);
            },
            trigger: "change",
          },
        ],
      },
    };
  },
  watch: {
    params: {
      handler(params) {
        if (params.testCmd == 72 || params.testCmd == 50) {
          this.readOnly = true;
        } else {
          this.readOnly = false;
        }
        this.startTestFlag = false;
      },
      deep: true,
    },
  },
  methods: {
    initParams() {
      // 初始化参数
      this.params = {
        num: 0,
        battGroupId: 0,
        devId: 0, // 设备id
        testCmd: 37, // 测试类型
        disCap: 0, // 核容容量
        disCurr: 0, // 核容电流
        disTime: 0, // 核容时长
        groupvolLow: 0, // 组端电压下限
        monomervolLow: 0, // 单体电压下限
        monomertmpHigh: 0, // 单体温度上限
        dcvolHighLimit: 0, // 升压上限
        chargeCurrSet: 0, // 充电电流
      };
    },
    // 获取参数
    getParams(useParam) {
      // 定义等待框
      let loading = this.$layer.loading(1);
      // 启动按钮不可点击
      this.startTestFlag = false;
      // 查询后台
      getParams({
        num: this.cmd.get,
        devId: this.batt.fbsdeviceId,
        battGroupNum: this.groupIdx,
      })
        .then((res) => {
          res = res.data;
          if (useParam || (res.code && res.data2)) {
            let fsparam = res.data;
            // 遍历参数属性并赋值
            for (let key in this.params) {
              if (key === "testCmd") {
                this.params.testCmd = 37;
              } else {
                this.params[key] = fsparam[key];
              }
            }
            // 设置的命令和devId
            this.params.num = this.cmd.set;
            this.params.devId = this.batt.fbsdeviceId;
            if (res.data2) {
              this.$layer.msg("读取成功!");
              // 设置按钮可点击
              this.setTestFlag = true;
            }
          } else {
            // 初始化参数
            this.initParams();
            // 设置按钮不可点击
            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) {
          let batt = this.batt;
          let params = this.params;
          let disCurr = params.disCurr; // 核容电流
          let disCap = params.disCap; // 核容容量
          let disTime = params.disTime; // 核容时长
          let realTestTime = 0;
          if (disCurr > batt.loadCurr) {
            realTestTime = batt.loadCurr
              ? Math.ceil(disCap / batt.loadCurr) * 60
              : 0;
          }
          let msg = "确认修改参数";
          if (realTestTime > disTime) {
            msg =
              "核容时长可能无法满足核容" +
              disCap +
              "AH,建议核容时长:" +
              realTestTime +
              "分钟";
          }
          // 设置参数
          this.$layer.confirm(msg, { icon: 3, title: "系统提示" }, (index) => {
            // 关闭确认框
            this.$layer.close(index);
            this.setParamsCheck();
          });
        } else {
          this.$layer.msg("存在校验未通过的数据!");
          return false;
        }
      });
    },
    setParamsCheck() {
      if (config.setParamsByFace.value) {
        this.setFaceShow = true;
      } else {
        this.setParams(true);
      }
    },
    // 设置参数
    setParams() {
      // 等待框
      let loading = this.$layer.loading(1);
      // 请求后台
      set61850Params(this.params)
        .then((res) => {
          res = res.data;
          if (res.code && res.data) {
            // 启动按钮可点击
            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) => {
          // 请求后台校验密码
          checkUserPwd(pass)
            .then((res) => {
              res = res.data;
              if (res.code) {
                // 关闭弹出框
                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);
      // 请求后台
      start({
        num: this.cmd.start,
        devId: this.batt.fbsdeviceId,
        battGroupNum: this.batt.groupIndexInFBSDevice + 1,
      })
        .then((res) => {
          res = res.data;
          if (res.code && res.data2) {
            // 提示信息
            this.$layer.msg("启动测试成功");
            this.$emit("close");
          } else {
            // 提示信息
            this.$layer.msg("启动测试失败!");
          }
          // 关闭等待框
          this.$layer.close(loading);
        })
        .catch((error) => {
          console.log(error);
          // 关闭等待框
          this.$layer.close(loading);
          // 提示信息
          this.$layer.msg("启动测试失败,启动测试请求异常!");
        });
    },
    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;
    },
    disCurrText() {
      let batt = this.batt;
      return "核容电流(1~300A)" + " 实际负载电流:" + batt.loadCurr + "A";
    },
  },
  mounted() {
    // 获取数据
    if (this.pReadOnly) {
      this.initParams();
      this.params = {
        ...this.params,
        ...this.paramData,
      };
    } else {
      this.getParams();
    }
  },
};
</script>
<style scoped>
.form-footer {
  margin-top: 16px;
  margin-bottom: 16px;
  text-align: right;
}
.form-footer .three-btn {
  margin-left: 12px;
}
</style>
src/views/dataTest/components/switchControl.vue
New file
@@ -0,0 +1,173 @@
<template>
  <div class="main">
    <div class="switch-info">
      <div class="name">DK-11</div>
      <div class="state">
        <el-switch
          style="display: block"
          v-model="DK11"
          active-color="#13ce66"
          inactive-color="#ccc"
          active-text="合闸"
          inactive-text="分闸"
        >
        </el-switch>
      </div>
      <div class="name">DK-12</div>
      <div class="state">
        <el-switch
          style="display: block"
          v-model="DK12"
          active-color="#13ce66"
          inactive-color="#ccc"
          active-text="合闸"
          inactive-text="分闸"
        >
        </el-switch>
      </div>
      <div class="name">DK-13</div>
      <div class="state">
        <el-switch
          style="display: block"
          v-model="DK13"
          active-color="#13ce66"
          inactive-color="#ccc"
          active-text="合闸"
          inactive-text="分闸"
        >
        </el-switch>
      </div>
      <div class="name">DK-14</div>
      <div class="state">
        <el-switch
          style="display: block"
          v-model="DK14"
          active-color="#13ce66"
          inactive-color="#ccc"
          active-text="合闸"
          inactive-text="分闸"
        >
        </el-switch>
      </div>
      <div class="name">DK-15</div>
      <div class="state">
        <el-switch
          style="display: block"
          v-model="DK15"
          active-color="#13ce66"
          inactive-color="#ccc"
          active-text="合闸"
          inactive-text="分闸"
        >
        </el-switch>
      </div>
      <div class="name">DK-16</div>
      <div class="state">
        <el-switch
          style="display: block"
          v-model="DK16"
          active-color="#13ce66"
          inactive-color="#ccc"
          active-text="合闸"
          inactive-text="分闸"
        >
        </el-switch>
      </div>
      <div class="name">DK-17</div>
      <div class="state">
        <el-switch
          style="display: block"
          v-model="DK17"
          active-color="#13ce66"
          inactive-color="#ccc"
          active-text="合闸"
          inactive-text="分闸"
        >
        </el-switch>
      </div>
      <div class="name">DK-18</div>
      <div class="state">
        <el-switch
          v-model="DK18"
          active-color="#13ce66"
          inactive-color="#ccc"
          active-text="合闸"
          inactive-text="分闸"
        >
        </el-switch>
      </div>
    </div>
    <div class="footer">
      <three-btn @click="getParams()">读取</three-btn>
      <three-btn :disabled="!setTestFlag" @click="submitFrom">设定</three-btn>
      <three-btn  @click="$emit('close')"
          >取消</three-btn
        >
    </div>
  </div>
</template>
<script>
export default {
  name: "",
  props: {
    devId: {
      type: [String, Number],
      required: true
    },
  },
  data() {
    return {
      DK11: false,
      DK12: false,
      DK13: true,
      DK14: false,
      DK15: false,
      DK16: false,
      DK17: false,
      DK18: true,
    };
  },
  components: {},
  methods: {
    getParams(){
    }
  },
  mounted() {},
};
</script>
<style scoped lang="less">
.main {
  width: 600px;
  padding: 20px;
  background: #f0f0f0;
  .switch-info {
    display: grid;
    grid-template-columns: repeat(2, 1fr 2fr);
    gap: 6px 20px;
    place-content: center;
    place-items: center end;
    .name {
      font-size: 16px;
      font-weight: bold;
      color: #f7b33c;
      &::after {
        content: ':';
      }
    }
    .state {
      justify-self: start;
    }
  }
  .footer {
    padding-top: 20px;
    text-align: right;
    /deep/ .three-btn + .three-btn {
      margin-left: 0.8em;
    }
  }
}
</style>
src/views/dataTest/movingRingSystem/index.vue
@@ -108,12 +108,16 @@
                "/dataTest/movingRingSystem/real-time-peiWang/" +
                data.battGroupId,
            });
          }else if(regEquipType(dev_id1, "intelDev")) {
          } else if (regEquipType(dev_id1, "intelDev")) {
            this.$router.push({
              path:
                "/dataTest/movingRingSystem/real-time-intel/" +
                data.battGroupId,
            });
          } else if (regEquipType(dev_id1, "dyhr")) {
            this.$router.push({
              path: "/dataTest/movingRingSystem/real-time-dyhr/" + dev_id1 + '/' + data.stationId,
            });
          } else {
            this.$router.push({
              path: "/dataTest/movingRingSystem/real-time/" + data.battGroupId,
src/views/dataTest/realTimeDyhr.vue
New file
@@ -0,0 +1,3141 @@
<template>
  <flex-layout direction="row" class="page-real-time" :no-bg="true">
    <home-list
      v-if="homeListShow"
      slot="header"
      @toggleChange="toggleChange"
      @leaf-click="leafClick"
    ></home-list>
    <content-box
      style="margin-left: 4px; margin-right: 4px"
      :title="stationFullName"
    >
      <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: 40px">
        <el-tooltip
          class="item"
          effect="dark"
          content="历史实时数据"
          placement="bottom"
        >
          <i
            class="el-iconfont el-icon-s-marketing"
            @click="chooseBattGroup('showHisRtData')"
          ></i>
        </el-tooltip>
      </div>
      <div
        slot="box-tools"
        class="box-tools"
        style="right: 72px"
        v-if="esVideoSn"
      >
        <el-tooltip
          class="item"
          effect="dark"
          content="视频监控"
          placement="bottom"
        >
          <i
            class="el-iconfont el-icon-video-camera-solid"
            @click="showEsVideoDialog"
          ></i>
        </el-tooltip>
      </div>
      <div style="right: 72px" slot="box-tools" class="box-tools">
        <el-tooltip
          class="item"
          effect="dark"
          content="通讯状态"
          placement="bottom"
        >
          <hdw-light :type="isLink"></hdw-light>
        </el-tooltip>
      </div>
      <div slot="box-tools" class="box-tools" style="right: 140px">
        <el-tooltip
          class="item"
          effect="dark"
          content="电池告警参数设置"
          placement="bottom"
        >
          <i
            class="el-iconfont el-icon-warning"
            @click="goToBattWarnSetting"
          ></i>
        </el-tooltip>
      </div>
      <flex-layout :no-bg="true">
        <div class="content-header" slot="header">
          <div class="table-layout">
            <div class="table-row">
              <div class="table-cell text-right w80">通信电源:</div>
              <div class="table-cell">
                <el-input
                  :value="powerState"
                  size="small"
                  :disabled="true"
                ></el-input>
              </div>
              <div class="table-cell text-right w80">蓄电池组1:</div>
              <div class="table-cell">
                <el-input
                  :value="battState0"
                  size="small"
                  :disabled="true"
                ></el-input>
              </div>
              <div class="table-cell text-right w80">蓄电池组2:</div>
              <div class="table-cell">
                <el-input
                  :value="battState1"
                  size="small"
                  :disabled="true"
                ></el-input>
              </div>
              <div class="table-cell text-right w80">分路开关合闸:</div>
              <div class="table-cell">
                <el-input
                  :value="switchOnCount"
                  size="small"
                  :disabled="true"
                ></el-input>
              </div>
              <div class="table-cell text-right w80">分路开关分闸:</div>
              <div class="table-cell">
                <el-input
                  :value="switchOffCount"
                  size="small"
                  :disabled="true"
                ></el-input>
              </div>
              <div class="table-cell text-right w80">告警:</div>
              <div class="table-cell">
                <el-input
                  :value="alarmCount"
                  size="small"
                  :disabled="true"
                ></el-input>
              </div>
            </div>
          </div>
        </div>
        <div class="page-content">
          <div class="page-content-tools">
            <el-popover placement="bottom" trigger="hover">
              <div class="hdw-menu-list" v-if="control.show">
                <ul>
                  <li class="hdw-menu-item">
                    <a @click="startTest(0)" href="javascript:void(0);"
                      >启动组一测试</a
                    >
                  </li>
                  <li class="hdw-menu-item">
                    <a @click="startTest(1)" href="javascript:void(0);"
                      >启动组二测试</a
                    >
                  </li>
                  <li class="hdw-menu-item">
                    <a href="javascript:void(0);" @click="stopTest">停止测试</a>
                  </li>
                  <li class="hdw-menu-item">
                    <a
                      href="javascript:void(0);"
                      @click="switchControlVisible = true"
                      >分路开关控制
                    </a>
                  </li>
                  <li class="hdw-menu-item">
                    <a href="javascript:void(0);" @click="restartSystem"
                      >重启设备</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
              key="eleLine"
              label="电路拓扑图"
              name="eleLine"
              v-if="pageConfig.eleLine"
            >
              <svg-dyhr></svg-dyhr>
            </el-tab-pane>
            <el-tab-pane
              class="tab-power"
              key="power"
              name="power"
              label="电源"
            >
              <!-- 交流配电 -->
              <div class="ac-info">
                <card>
                  <big-screen-card title="交流配电">
                    <div class="g-content">
                      <div class="label">A相电压(V)</div>
                      <div class="value">205</div>
                      <div class="label">A相电流(A)</div>
                      <div class="value">1.98</div>
                      <div class="label">B相电压(V)</div>
                      <div class="value">205</div>
                      <div class="label">B相电流(A)</div>
                      <div class="value">1.98</div>
                      <div class="label">C相电压(V)</div>
                      <div class="value">205</div>
                      <div class="label">C相电流(A)</div>
                      <div class="value">1.98</div>
                      <div class="label">交流频率(Hz)</div>
                      <div class="value">50.00</div>
                    </div>
                  </big-screen-card>
                </card>
              </div>
              <!-- 直流配电 -->
              <div class="dc-info">
                <card>
                  <big-screen-card title="直流配电">
                    <div class="g-content">
                      <div class="label">母排电压(V)</div>
                      <div class="value">50</div>
                      <div class="label">直流输入电压(V)</div>
                      <div class="value">50</div>
                      <div class="label">电池电流1(A)</div>
                      <div class="value">1.98</div>
                      <div class="label">电池电流2(A)</div>
                      <div class="value">1.98</div>
                      <div class="label">模块总电流(A)</div>
                      <div class="value">1.98</div>
                      <div class="label">负载总电流(A)</div>
                      <div class="value">1.98</div>
                      <div class="label">电池温度(℃)</div>
                      <div class="value">25</div>
                      <div class="label">环境温度(℃)</div>
                      <div class="value">25</div>
                      <div class="label">扩展温度(℃)</div>
                      <div class="value">25</div>
                      <div class="label">环境湿度(%)</div>
                      <div class="value">2.5</div>
                      <div class="label">电池状态</div>
                      <div class="value">浮充</div>
                      <div class="label">电池容量(%)</div>
                      <div class="value">100</div>
                      <div class="label">负载1电流(A)</div>
                      <div class="value">1.98</div>
                      <div class="label">负载2电流(A)</div>
                      <div class="value">1.98</div>
                      <div class="label">负载3电流(A)</div>
                      <div class="value">1.98</div>
                      <div class="label">负载4电流(A)</div>
                      <div class="value">1.98</div>
                      <div class="label">负载一次下电</div>
                      <div class="value">--</div>
                    </div>
                  </big-screen-card>
                </card>
              </div>
              <!-- 整流模块 -->
              <div class="module-info">
                <card>
                  <big-screen-card title="整流模块">
                    <div class="g-content">
                      <div class="label">模块在线数</div>
                      <div class="value">10</div>
                      <div class="label">模块限流点(A)</div>
                      <div class="value">51.98</div>
                      <div class="label">模块过压点(V)</div>
                      <div class="value">58.00</div>
                      <div class="label">节能功能</div>
                      <div class="value">关闭</div>
                      <div class="label">休眠系数(%)</div>
                      <div class="value">30.0</div>
                      <div class="label">唤醒系数(%)</div>
                      <div class="value">800.0</div>
                      <div class="label">输换周期(H)</div>
                      <div class="value">24</div>
                      <div class="label">模块基数</div>
                      <div class="value">0</div>
                      <div class="label">节能测试</div>
                      <div class="value">关闭</div>
                      <div class="label">模块额定数量</div>
                      <div class="value">0</div>
                    </div>
                    <div class="table-module">
                      <div class="tbl-data-body">
                        <el-table
                          stripe
                          size="small"
                          :data="table_module.datas"
                          height="100%"
                        >
                          <el-table-column
                            v-for="header in table_module.headers"
                            :key="header.prop"
                            :prop="header.prop"
                            :label="header.label"
                            align="center"
                          ></el-table-column>
                          <!-- :width="header.width" -->
                        </el-table>
                      </div>
                    </div>
                  </big-screen-card>
                </card>
              </div>
            </el-tab-pane>
            <el-tab-pane
              key="vol"
              label="电压"
              name="vol"
              v-if="pageConfig.vol"
            >
              <div class="select-group">
                <el-select
                  size="mini"
                  @change="updateChart"
                  v-model="chartGroupIdx"
                >
                  <el-option label="蓄电池组1" :value="0"></el-option>
                  <el-option label="蓄电池组2" :value="1"></el-option>
                </el-select>
              </div>
              <bar-chart
                ref="vol"
                id="vol"
                unit="V"
                :show-tools="true"
                @right-click="chartRightCLick"
              ></bar-chart>
            </el-tab-pane>
            <el-tab-pane
              key="res"
              label="内阻"
              name="res"
              v-if="pageConfig.res"
            >
              <div class="select-group">
                <el-select
                  size="mini"
                  @change="updateChart"
                  v-model="chartGroupIdx"
                >
                  <el-option label="蓄电池组1" :value="0"></el-option>
                  <el-option label="蓄电池组2" :value="1"></el-option>
                </el-select>
              </div>
              <bar-chart
                ref="res"
                id="res"
                unit="mΩ"
                :show-tools="true"
                @right-click="chartRightCLick"
              ></bar-chart>
              <!-- max-color="red"
              min-color="green" -->
            </el-tab-pane>
            <el-tab-pane
              key="temp"
              label="温度"
              name="temp"
              v-if="pageConfig.temp"
            >
              <div class="select-group">
                <el-select
                  size="mini"
                  @change="updateChart"
                  v-model="chartGroupIdx"
                >
                  <el-option label="蓄电池组1" :value="0"></el-option>
                  <el-option label="蓄电池组2" :value="1"></el-option>
                </el-select>
              </div>
              <bar-chart
                ref="temp"
                id="temp"
                unit="℃"
                :show-tools="true"
                @right-click="chartRightCLick"
              ></bar-chart>
              <!-- max-color="red"
                min-color="green" -->
            </el-tab-pane>
            <el-tab-pane
              key="tblData"
              label="数据表格"
              name="tblData"
              class="el-table-wrapper"
              v-if="pageConfig.tblData"
            >
              <div class="tbl-data-container">
                <div class="tbl-data-body">
                  <el-table
                    stripe
                    size="small"
                    :data="table.datas"
                    :row-class-name="setTableRowClass"
                    :span-method="spanMethod"
                    height="100%"
                  >
                    <el-table-column
                      v-for="header in dataHeaders"
                      :key="header.prop"
                      :prop="header.prop"
                      :label="header.label"
                      :width="header.width"
                      :sortable="header.sortable"
                      align="center"
                    ></el-table-column>
                  </el-table>
                </div>
                <div class="tbl-data-footer">
                  <el-button
                    type="primary"
                    size="mini"
                    round
                    @click="exportFile"
                    >导出</el-button
                  >
                </div>
              </div>
            </el-tab-pane>
          </el-tabs>
        </div>
      </flex-layout>
    </content-box>
    <!-- 放电参数设置 -->
    <el-dialog
      :title="dischargeDialogTitle"
      width="700px"
      :visible.sync="dischargeDialog.show"
      :close-on-click-modal="false"
      top="0"
      class="dialog-center"
      :modal-append-to-body="false"
    >
      <discharge-dialog-content
        v-if="dischargeDialog.show"
        :batt="currBatt"
        @close="closeDisChargeDialog"
      >
      </discharge-dialog-content>
    </el-dialog>
    <el-dialog
      title="选择要操作的电池组"
      :visible.sync="chooseBattGroupVisible"
      :close-on-click-modal="false"
      width="400px"
      top="0"
      class="dialog-center"
      :modal-append-to-body="false"
    >
      <div class="choose-batt">
        <el-button type="primary" @click="chooseBattGroupOk(0)"
          >查看电池组1</el-button
        >
        <el-button type="primary" @click="chooseBattGroupOk(1)"
          >查看电池组2</el-button
        >
      </div>
    </el-dialog>
    <!-- 支路开关控制 -->
    <el-dialog
      title="分路开关控制"
      :visible.sync="switchControlVisible"
      width="auto"
      top="0"
      class="dialog-center"
      :close-on-click-modal="false"
      :modal-append-to-body="false"
    >
      <switch-control
        :devId="devId"
        @close="switchControlVisible = false"
        v-if="switchControlVisible"
      ></switch-control>
    </el-dialog>
    <!-- 系统参数设置 -->
    <el-dialog
      title="系统参数设置"
      width="700px"
      :visible.sync="systemDialog.show"
      :close-on-click-modal="false"
      top="0"
      class="dialog-center"
      :modal-append-to-body="false"
    >
      <system-params v-if="systemDialog.show" :batt="batt"></system-params>
    </el-dialog>
    <!-- 实时历史数据 -->
    <el-dialog
      :title="histroyDataTitle"
      width="1200px"
      :visible.sync="historyRealTimeDataDialog.show"
      :close-on-click-modal="false"
      top="0"
      class="dialog-center no-bg"
      :modal-append-to-body="false"
    >
      <history-realtime-data
        :batt="currBatt"
        v-if="historyRealTimeDataDialog.show"
      ></history-realtime-data>
    </el-dialog>
    <modal
      name="videoModal"
      :draggable="true"
      height="auto"
      :clickToClose="false"
    >
      <div class="modal-title-wrapper">
        <div class="modal-title-content">视频监控</div>
        <div class="modal-title-tools">
          <i class="el-icon-close" @click="closeEsVideoDialog"></i>
        </div>
      </div>
      <ez-video v-if="esVideoDialog" :sn="esVideoSn"></ez-video>
    </modal>
    <el-dialog
      title="历史内阻数据"
      width="1200px"
      :visible.sync="hisResDialog"
      :close-on-click-modal="false"
      top="0"
      class="dialog-center"
      :modal-append-to-body="false"
    >
      <history-res v-if="hisResDialog" :batt="batt"></history-res>
    </el-dialog>
    <!-- 均充参数设置 -->
    <el-dialog
      title="均充参数设置"
      width="auto"
      :visible.sync="jcParamsDialog"
      :close-on-click-modal="false"
      top="0"
      class="dialog-center"
      :modal-append-to-body="false"
    >
      <jc-params v-if="jcParamsDialog" :batt="batt"> </jc-params>
    </el-dialog>
    <right-menu
      :visible.sync="rightMenu.show"
      :x="rightMenu.x"
      :y="rightMenu.y"
    >
      <div class="right-menu-list">
        <ul>
          <li>
            <a href="javascript:;" @click="payAttentionMon">添加关注单体</a>
          </li>
          <li>
            <a href="javascript:;" @click="hisResDialog = true"
              >导出历史内阻数据</a
            >
          </li>
        </ul>
      </div>
    </right-menu>
    <!-- 周期启动内阻测试 -->
    <el-dialog
      title="周期启动内阻测试设置"
      :visible.sync="regularTestResInfo.visible"
      width="auto"
      top="0"
      class="dialog-center"
      :modal-append-to-body="false"
    >
      <regular-test-res-params
        v-if="regularTestResInfo.visible"
        :batt="batt"
        :visible.sync="regularTestResInfo.visible"
      ></regular-test-res-params>
    </el-dialog>
    <!--  重启设备使用人脸识别  -->
    <el-dialog
      title="人脸校验"
      width="480px"
      :visible.sync="restartFaceShow"
      :close-on-click-modal="false"
      top="0"
      :modal="false"
      class="dialog-center"
      :modal-append-to-body="false"
      :destroy-on-close="true"
    >
      <check-face
        v-if="restartFaceShow"
        @checkSuccess="restartFaceSuccess"
      ></check-face>
    </el-dialog>
    <!-- 设备告警参数设置 -->
    <el-dialog
      title="设备告警参数设置"
      :visible.sync="alarmParamsInfo.visible"
      width="auto"
      top="0"
      class="dialog-center"
      :close-on-press-escape="false"
      :modal-append-to-body="false"
    >
      <dev-alarm-params
        v-if="alarmParamsInfo.visible"
        :batt="batt"
        :visible.sync="alarmParamsInfo.visible"
      ></dev-alarm-params>
    </el-dialog>
  </flex-layout>
</template>
<script>
import SvgDyhr from "@/views/home/components/svg/svgDyhr.vue";
import ContentBox from "@/components/ContentBox";
import BarChart from "@/components/chart/BarChart";
import ScienceBox from "@/components/ScienceBox";
import HdwLight from "@/components/HdwLight.vue";
import stopOutlineCuring from "./components/stopOutlineCuring";
// import HomeList from "./components/HomeList";
import HomeList from "./movingRingSystem/HomeList";
import DischargeDialogContent from "./components/DischargeDialogContent";
import SystemParams from "./components/SystemParams";
import CuringParams from "./components/CuringParams";
import OutlineCuringParams from "./components/OutlineCuringParams";
// import RestartPlanParams from "./components/RestartPlanParams";
import HistoryRealtimeData from "./components/HistoryRealtimeData";
import NiBian from "./components/NiBian";
import StopCuring from "./components/StopCuring";
import NiBianInfoTab from "./components/NiBianInfoTab";
import dcWorkParams from "./components/dcdc/workParams";
import CircuitDiagram from "./components/CircuitDiagram";
import RightMenu from "./components/RightMenu";
import historyRes from "./components/historyRes";
import BalanceSupplyModule from "./components/balance-supply-module.vue";
import BalanceControlParams from "./components/balance-control-params.vue";
import ezVideo from "@/components/ezVideo";
import workPlan from "./components/dcdc/workPlan";
import ElePriceTpl from "./components/elePriceTpl";
import BmsInfo from "./components/bmsInfo";
import LithiumPackTab from "./components/lithiumPackTab";
import qrCode from "@/assets/js/outside/qrCode";
import sysConfig from "@/assets/js/config";
import {
  btsControl,
  clearWarn,
  dev9612Control,
  getGuidesData,
  getStationPic,
  ld9Control,
  outlineControl as restart,
  realTimeAdd,
  realTimeAlarm,
  realTimeNot,
  searchInfo,
  setGuidesData,
  startResTest,
  stopLd6,
  updateDevTimeApi,
} from "./js/realTime";
import { getBattList } from "@/assets/js/api";
import {
  getBattGroupInfo,
  getBattRecords,
  getStationBattInfo,
} from "../dataMager/js/battGroupMager";
import {
  formatSeconds,
  getBarNum,
  getConduct,
  getDevType,
  GetHourRate,
  GetMonomerCap,
  isHasPermit,
  lithium as lithiumInfo,
  regEquipType,
  sethoubeiTime,
} from "@/assets/js/tools";
import {
  const_61850,
  const_9100,
  const_ld_nine,
  const_system,
} from "@/assets/js/const";
import getMarkLineData from "@/components/chart/js/getMarkLineDataPlus";
import getTblHeader from "./js/getTblHeader";
import ThreeStation from "@/components/threeStation";
import createWs from "@/assets/js/websocket";
import HomeImageList from "@/components/homeImageList";
import JcParams from "@/views/dataTest/components/JcParams";
import { ExportFile } from "@/assets/js/tools/exportFile";
import const_digit from "@/assets/js/const/const_digit";
import FlexBox from "@/components/FlexBox.vue";
import BattAssetInfo from "@/views/dataMager/components/battAssetInfo.vue";
import { checkUserPwd } from "@/views/login/js/api";
import BattGroupAlarm from "@/views/dataTest/components/battGroupAlarm.vue";
import BattGroupAlarm9612 from "@/views/dataTest/components/battGroupAlarm9612.vue";
import { getBit } from "@/assets/js/const/const_storage";
import getItemByKey from "@/assets/js/tools/getItemByKey";
import const_9612 from "@/assets/js/const/const_9612";
import RegularTestResParams from "@/views/dataTest/components/RegularTestResParams.vue";
import CheckFace from "@/components/checkFace.vue";
import const_61852 from "@/assets/js/const/const_61852";
import DevAlarmParams from "@/views/dataTest/components/DevAlarmParams.vue";
import BigScreenCard from "@/components/bigScreenPage/big_screen_card.vue";
import card from "@/views/home/components/card-corner";
import switchControl from "./components/switchControl.vue";
const WSMixin = createWs("RealTime");
const {
  cap: CAP,
  vol: VOL,
  curr: CURR,
  res: RES,
  conduct: CONDUCT,
  temp: TEMP,
  hum: HUM,
} = const_digit;
/* import moment from "moment"; */
let vol, resChart, temp, conduct, currChart, leakVol, monConnRes;
export default {
  name: "movingRingSysteRrealTimeDyhr",
  mixins: [WSMixin],
  components: {
    SvgDyhr,
    DevAlarmParams,
    CheckFace,
    RegularTestResParams,
    BattGroupAlarm9612,
    BattGroupAlarm,
    BattAssetInfo,
    FlexBox,
    JcParams,
    HomeImageList,
    stopOutlineCuring,
    BmsInfo,
    ElePriceTpl,
    ezVideo,
    ContentBox,
    HomeList,
    BarChart,
    CircuitDiagram,
    ScienceBox,
    DischargeDialogContent,
    SystemParams,
    CuringParams,
    OutlineCuringParams,
    // RestartPlanParams,
    HistoryRealtimeData,
    RightMenu,
    NiBian,
    StopCuring,
    NiBianInfoTab,
    HdwLight,
    historyRes,
    BalanceSupplyModule,
    BalanceControlParams,
    dcWorkParams,
    workPlan,
    ThreeStation,
    LithiumPackTab,
    BigScreenCard,
    card,
    switchControl,
  },
  watch: {
    "$route.params.BattGroupId"(battGroupId) {
      this.$nextTick(() => {
        this.getBattGroupInfo(battGroupId);
      });
    },
    "$store.state.theme.collapse"() {
      this.$nextTick(() => {
        this.resize();
      });
    },
    // "diagram.type"() {
    //   let batt = this.batt;
    //   this.getLastCapacityTest(batt);
    // },
  },
  data() {
    let permits = this.$store.state.user.permits;
    let isCanTest = isHasPermit("batt_test_op_permit", permits);
    let stateList = JSON.parse(JSON.stringify(const_61850.stateList));
    let historyStateList = JSON.parse(
      JSON.stringify(const_61850.historyStateList)
    );
    let lastCapacityTest = JSON.parse(
      JSON.stringify(const_61850.lastCapacityTest)
    );
    let pageConfig = this.$store.getters["user/realTabsConfig"];
    return {
      viewGroupIdx: 0,
      chooseBattGroupVisible: false,
      switchControlVisible: false,
      // 柱状图显示的电池组号
      chartGroupIdx: 0,
      table_module: {
        datas: [
          {
            a: "模块1",
            b: "离线",
            c: 53.58,
            a0: 5.44,
            a1: 1900,
            a2: 0,
            a3: 0,
            a4: "--",
            a5: "开机",
          },
          {
            a: "模块2",
            b: "离线",
            c: 53.58,
            a0: 5.44,
            a1: 1900,
            a2: 0,
            a3: 0,
            a4: "--",
            a5: "开机",
          },
          {
            a: "模块3",
            b: "离线",
            c: 53.58,
            a0: 5.44,
            a1: 1900,
            a2: 0,
            a3: 0,
            a4: "--",
            a5: "开机",
          },
          {
            a: "模块4",
            b: "离线",
            c: 53.58,
            a0: 5.44,
            a1: 1900,
            a2: 0,
            a3: 0,
            a4: "--",
            a5: "开机",
          },
          {
            a: "模块5",
            b: "离线",
            c: 53.58,
            a0: 5.44,
            a1: 1900,
            a2: 0,
            a3: 0,
            a4: "--",
            a5: "开机",
          },
          {
            a: "模块6",
            b: "离线",
            c: 53.58,
            a0: 5.44,
            a1: 1900,
            a2: 0,
            a3: 0,
            a4: "--",
            a5: "开机",
          },
          {
            a: "模块7",
            b: "离线",
            c: 53.58,
            a0: 5.44,
            a1: 1900,
            a2: 0,
            a3: 0,
            a4: "--",
            a5: "开机",
          },
          {
            a: "模块8",
            b: "离线",
            c: 53.58,
            a0: 5.44,
            a1: 1900,
            a2: 0,
            a3: 0,
            a4: "--",
            a5: "开机",
          },
          {
            a: "模块9",
            b: "离线",
            c: 53.58,
            a0: 5.44,
            a1: 1900,
            a2: 0,
            a3: 0,
            a4: "--",
            a5: "开机",
          },
          {
            a: "模块10",
            b: "离线",
            c: 53.58,
            a0: 5.44,
            a1: 1900,
            a2: 0,
            a3: 0,
            a4: "--",
            a5: "开机",
          },
        ],
        headers: [
          {
            prop: "a",
            label: "模块名称",
          },
          {
            prop: "b",
            label: "在线状态",
            width: 100,
          },
          {
            prop: "c",
            label: "输出电压(V)",
            width: 100,
          },
          {
            prop: "a0",
            label: "输出电流(A)",
            width: 100,
          },
          {
            prop: "a1",
            label: "风扇1转速",
            width: 100,
          },
          {
            prop: "a2",
            label: "风扇2转速",
            width: 100,
          },
          {
            prop: "a3",
            label: "模块温度(℃)",
            width: 100,
          },
          {
            prop: "a4",
            label: "整流器告警",
            width: 100,
          },
          {
            prop: "a5",
            label: "开关机状态",
            width: 100,
          },
        ],
      },
      battList: [],
      currBatt: {},
      devId: "",
      stationInf: null,
      battState0: "未知",
      battState1: "未知",
      switchOnCount: 0,
      switchOffCount: 0,
      alarmCount: 0,
      powerState: "未知",
      restartFaceShow: false,
      regularTestResInfo: {
        visible: false,
      },
      updateDevTimeInfo: {
        visible: false,
        date: "2020-10-01 00:00:00",
      },
      alarmParamsInfo: {
        visible: false,
      },
      testNumber: 0,
      flowInfo: null,
      battRecords: [],
      lastTimeTestInfo: {
        realCap: 0,
        xuHang: 0,
      },
      workState: "",
      guidesDialog: false,
      guidesVal: "",
      guidesData: {},
      // autoCheck: false,
      homeImageDialog: false,
      workPlanDialog: false,
      dcdcWorkDialog: false,
      balanceControlDialog: false,
      jcParamsDialog: false,
      hisResDialog: false,
      esVideoDialog: false,
      esVideoSn: "",
      maskShow: false,
      isCanTest: isCanTest,
      homeListShow: true,
      // homeListShow: false,
      devVersion: "",
      username: sessionStorage.getItem("username"),
      pageConfig: pageConfig,
      stopTime: 0,
      stationImages: [],
      rightMenu: {
        show: false,
        x: 0,
        y: 0,
        xIndex: 0,
      },
      chargeMon: "",
      acTabs: "eleLine",
      table: {
        headers: [
          {
            prop: "groupIdx",
            label: "组号",
            width: "",
            key1: "",
            sortable: false,
          },
          {
            prop: "num1",
            label: "单体编号",
            width: "",
            key1: "",
            sortable: false,
          },
          {
            prop: "vol1",
            label: "电压(V)",
            width: "",
            sortable: false,
            key1: "vol",
          },
          {
            prop: "res1",
            label: "内阻(mΩ)",
            width: "",
            sortable: false,
            key1: "res",
          },
          {
            prop: "temp1",
            label: "温度(℃)",
            sortable: false,
            width: "",
            key1: "temp",
          },
          // {
          //   prop: "conduct1",
          //   label: "电导",
          //   width: "",
          //   key1: "conduct",
          //   sortable: false,
          // },
          // {
          //   prop: "monConnRes",
          //   label: "链接条阻值",
          //   width: "",
          //   key1: "monConnRes",
          //   sortable: false,
          // },
          // {
          //   prop: "curr1",
          //   label: "均衡电流(A)",
          //   width: "",
          //   key1: "curr",
          //   sortable: false,
          // },
          // {
          //   prop: "leakVol1",
          //   label: "漏液电压(V)",
          //   width: "",
          //   key1: "leakVol",
          //   sortable: false,
          // },
        ],
        datas: [],
      },
      batt: {},
      stateListShow: false,
      stateList: stateList,
      historyStateList: historyStateList,
      lastCapacityTest: lastCapacityTest,
      diagram: {
        update: true,
        type: -1,
        desc: "",
        powerCut: 1,
        temp: 0, // 设备温度
        contactRes: 0, // 接触器阻抗
        dropVol: 0, // 导通压降
        devType: 0, // 设备类型
        bypass: {
          drynodeCommst: 0xaaaa, // 干接点通信状态(0xAAAA-正常  0xBBBB-异常)
          k1CheckSt: 0xaaaa, // 接触器k1检测状态(0xAAAA-正常  0xBBBB-异常)
          k1St: 0xaaaa, // 接触器k1状态(0-断开  1-闭合)
          urgentswitchSt: 0xaaaa, // 急停状态(0xAAAA-未触发  0xBBBB-触发)
          bypassswitchSt: 0xaaaa, // 旁路状态(0xAAAA-未接入  0xBBBB-接入旁路)
        },
        devHumidity: 0, // 湿度
        devTemperature: 0, // 温度
      },
      dischargeDialog: {
        show: false,
      },
      systemDialog: {
        show: false,
      },
      curingDialog: {
        show: false,
      },
      outlineCuringDialog: {
        show: false,
      },
      // restartPlanDialog: {
      //   show: false,
      // },
      historyRealTimeDataDialog: {
        show: false,
      },
      control: {
        show: false,
        data: {
          startTest: {
            // 启动核容测试
            show: true,
            typeShow: false,
            id: 11,
          },
          stopTest: {
            // 停止测试
            show: true,
            typeShow: false,
            id: 12,
          },
          setSystemParams: {
            // 系统参数设置
            show: true,
            typeShow: false,
            id: 13,
          },
          clearWarn: {
            // 清理告警
            show: true,
            typeShow: false,
            id: 14,
          },
          startYH: {
            // 启动养护/除硫
            show: true,
            typeShow: false,
            id: 15,
          },
          stopYH: {
            // 停止养护/除硫
            show: true,
            typeShow: false,
            id: 16,
          },
          startOutlineYH: {
            // 启动离线养护/除硫
            show: true,
            typeShow: false,
            id: 17,
          },
          stopOutlineYH: {
            // 停止离线养护/除硫
            show: true,
            typeShow: false,
            id: 18,
          },
          circleRestart: {
            // 定期重启
            show: true,
            typeShow: false,
            id: 19,
          },
          restart: {
            // 重启
            show: true,
            typeShow: false,
            id: 20,
          },
          juheng: {
            // 均衡控制参数设置
            show: true,
            typeShow: false,
            id: 21,
          },
        },
      },
      // 空开状态 0-断开 1-闭合
      buscoupleSwitch: 0,
      // 数据更新标识
      dataChangeFlag: 0,
      // 单体电压信息
      monVols: [],
      // 单体温度信息
      monTemps: [],
      station: {
        show: false,
        data: {
          stationId: 0,
          info: null,
        },
      },
    };
  },
  methods: {
    spanMethod({ row, column, rowIndex, columnIndex }) {
      let data = this.table.datas;
      if (columnIndex === 0) {
        // 如果有上一行 具上行一行与当前行的值相同 则rowspan为0
        if (rowIndex > 0 && data[rowIndex - 1].groupIdx == row.groupIdx) {
          return {
            rowspan: 0,
            colspan: 0,
          };
        }
        let spanCount = 1;
        for (let i = rowIndex + 1, len = data.length; i < len; i++) {
          if (data[i].groupIdx == row.groupIdx) {
            spanCount++;
          } else {
            break;
          }
        }
        return {
          rowspan: spanCount,
          colspan: 1,
        };
      } else {
        return {
          rowspan: 1,
          colspan: 1,
        };
      }
    },
    // 获取电池组列表
    getBattList(stationId) {
      getBattList(stationId)
        .then((res) => {
          let { code, data } = res.data;
          // console.log(data, "0-0-0-0");
          if (code && data) {
            this.battList = data;
          }
        })
        .catch((err) => {
          console.log(err);
        });
    },
    showEsVideoDialog() {
      this.esVideoDialog = true;
      this.$nextTick(() => {
        this.$modal.show("videoModal");
      });
    },
    closeEsVideoDialog() {
      this.$modal.hide("videoModal");
      this.$nextTick(() => {
        this.esVideoDialog = false;
      });
    },
    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();
      });
    },
    toggleChange() {
      this.resize();
    },
    resize() {
      this.$G.chartManage.resize(this.acTabs);
      // if (isToggleChange) {
      const acTabs = this.acTabs;
      this.acTabs = "";
      this.$nextTick(() => {
        this.acTabs = acTabs;
      });
      // }
    },
    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: [],
            markLine: {
              data: getMarkLineData(),
            },
          },
        ],
      };
      // 内阻
      resChart = {
        title: {
          show: true,
          text: "最大值=0mΩ;最小值=mΩ;平均值=0mΩ",
          x: "center",
          textStyle: {
            fontSize: "14",
          },
        },
        series: [
          {
            name: "内阻",
            type: "bar",
            data: [],
            // markLine: {
            //   data: getMarkLineData(),
            // },
          },
        ],
      };
      // 温度
      temp = {
        title: {
          show: true,
          text: "最大值=0℃;最小值=0℃;平均值=0℃",
          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: "最大值=0A;最小值=0A;平均值=0A",
          x: "center",
          textStyle: {
            fontSize: "14",
          },
        },
        series: [
          {
            name: "均衡电流",
            type: "bar",
            data: [],
          },
        ],
      };
      // 链接条阻值
      monConnRes = {
        title: {
          show: true,
          text: "最大值=0mΩ;最小值=0mΩ;平均值=0mΩ",
          x: "center",
          textStyle: {
            fontSize: "14",
          },
        },
        series: [
          {
            name: "链接条阻值",
            type: "bar",
            data: [],
          },
        ],
      };
      // 设置配置项
      this.setChart();
    },
    setChart() {
      let acTabs = this.acTabs;
      if (!this.$refs[acTabs]) {
        return;
      }
      switch (acTabs) {
        case "vol":
          this.$refs.vol.setOption(vol);
          break;
        case "res":
          this.$refs.res.setOption(resChart);
          break;
        case "temp":
          this.$refs.temp.setOption(temp);
          break;
        case "conduct":
          this.$refs.conduct.setOption(conduct);
          break;
        case "curr":
          this.$refs.curr.setOption(currChart);
          break;
        case "leakVol":
          this.$refs.leakVol.setOption(leakVol);
          break;
        case "monConnRes":
          this.$refs.monConnRes.setOption(monConnRes);
          break;
      }
    },
    onWSOpen() {
      this.$nextTick(() => {
        this.sendMessage();
      });
    },
    sendMessage() {
      let devId = this.devId;
      let pageType = "powerHr6159";
      if (!devId || !this.isWSOpen) {
        return false;
      }
      let params = {
        devId,
        pageType, // standard-标准,dbs-多宝山
      };
      // console.log("=====9=", params, JSON.stringify(params));
      this.SOCKET.send(JSON.stringify(params));
    },
    onWSMessage(res) {
      res = JSON.parse(res.data);
      let data = res.data.data;
      // console.log(data, "=====111data");
      let { binf, f9100state, rtdata, rtstate, ycdata, yxdata } = data;
      if (!this.stationInf) {
        this.getStation(binf);
      }
      this.realTimePowerOffs(f9100state);
      this.updateGroup(rtstate);
      // 单体信息
      this.realTimeSearch(rtdata);
      // this.realTimeLd9Data(data.ld9);
      // this.realTimeStateList(data.fod);
      // this.getLithiumAnalog(data.li9130); // 锂电池模拟量
      // this.inversionData(data.fbs9100sBuscoupleState);
      // this.setBts9150Dev(data.fbs9150Res);
      // // 最后一次核容数据
      // this.getLastCapacityTest(data.tinfdata);
      this.dataChangeFlag = Math.random(); // 数据更新
    },
    //
    getStation(obj) {
      let { code, data, data2 } = obj;
      if (code && data) {
        this.stationInf = {
          stationName3: data2.stationName3,
          stationName4: data2.stationName4,
          fbsdeviceId: data2.fBSDeviceId,
          stationId: data2.stationId,
          stationName: data2.stationName,
        };
      }
    },
    // 组端数据
    updateGroup(obj) {
      const { code, data, data2 } = obj;
      // 电池组状态
      const workState = ["未知", "浮充", "充电", "放电", "均充", "内阻测试"];
      // battState
      if (code && data) {
        this.battState0 = workState[data2[0].battState];
        this.battState1 = workState[data2[1].battState];
      }
    },
    // 查询控制按钮的内容
    searchControl() {
      searchInfo({ categoryId: 2 })
        .then((res) => {
          res = res.data;
          let control = false; // 控制整体的显示
          if (res.code) {
            let data = res.data.list;
            Object.keys(this.control.data).forEach((key) => {
              let item = this.control.data[key];
              item.show = this.getStateById(item.id, data); // 根据id设置按钮的状态
              // 存在控制
              if (item.show) {
                control = item.show;
              }
            });
          }
          this.control.show = control; // 设置整体显示的状态
        })
        .catch((error) => {
          console.log(error);
        });
    },
    leafClick(data) {
      this.batt = data;
      this.diagram.desc = "";
      // 查询机房电池组信息(3D用)
      this.getStationBattInfo(data.stationId);
      this.realTimeAlarmss();
      this.getBattRecords(data.battGroupId);
      // this.realTimeXuHang();    // 预估续航时长
      this.diagram.devType = getDevType(data.chargeType, data.buscoupleState);
      this.esVideoSn = data.videoUrl;
      this.table.headers = getTblHeader(data.fbsdeviceId);
      this.$nextTick(() => {
        this.changeTabsName();
        // 开启循环请求
        this.sendMessage();
        // 获取机房的图片
        this.getStationPic();
      });
    },
    getStationBattInfo(id) {
      getStationBattInfo(id).then((res) => {
        res = res.data;
        // console.log(res, '======res?a');
        if (res.code && res.data.length) {
          this.station.data.stationId = res.data[0].stationId;
          this.station.data.info = res.data;
        }
      });
    },
    /**
     * 根据设备类型修改Tabs选中状态
     */
    changeTabsName() {
      // if (this.isLd9) {
      //   this.acTabs = "vol";
      // }
      this.$nextTick(() => {
        this.resize();
      });
    },
    /* 查询电池告警参数 */
    realTimeAlarmss() {
      var batt = this.batt;
      realTimeAlarm({
        devId: batt.fbsdeviceId,
      }).then((res) => {
        res = res.data;
        // 初始化查询参考线
        if (this.cdshStatus == "cdsh") {
          this.getGuides(res);
        } else {
          this.setLin(res);
        }
      });
    },
    // 设置高低线参考线
    setLin: function (res) {
      if (res.code) {
        let list = res.data.list;
        // 单体电压
        this.setChartMarkLine(vol, "Voltage", "Batt_Alarm_Type_MonVol", list);
        // 单体温度
        this.setChartMarkLine(
          temp,
          "Temperature",
          "Batt_Alarm_Type_MonTmp",
          list
        );
        // 单体内阻
        this.setChartMarkLine(
          resChart,
          "Resistance",
          "Batt_Alarm_Type_MonRes",
          list
        );
        // 单体电导
        this.setChartMarkLine(
          conduct,
          "Conductance",
          "Batt_Alarm_Type_MonRes",
          list
        );
        // 漏液电压
        this.setChartMarkLine(
          leakVol,
          "leakVol",
          "Batt_Alarm_Type_MonLYVol",
          list
        );
      }
    },
    setChartMarkLine(chartData, name, almName, list) {
      let batt = this.batt;
      // 遍历list
      for (let i = 0; i < list.length; i++) {
        let item = list[i];
        if (item.almName == almName) {
          let high = 0;
          let highHigh = 0;
          let low = 0;
          let lowLow = 0;
          let guides = 0;
          switch (name) {
            case "Voltage": // 电压告警
              //单体电压
              let std_mon_vol = batt.monVolStd;
              high = parseFloat(std_mon_vol * item.almHighCoe).toHold(VOL);
              highHigh = parseFloat(std_mon_vol * item.almHighCoeUpper).toHold(
                VOL
              );
              low = parseFloat(std_mon_vol * item.almLowCoe).toHold(VOL);
              lowLow = parseFloat(std_mon_vol * item.almLowCoeLower).toHold(
                VOL
              );
              if (this.cdshStatus == "cdsh") {
                guides = this.guidesData.monVol;
              }
              break;
            case "Temperature":
              //单体温度
              let std_mon_tmp = 25;
              high = parseFloat(std_mon_tmp * item.almHighCoe).toHold(TEMP);
              highHigh = parseFloat(std_mon_tmp * item.almHighCoeUpper).toHold(
                TEMP
              );
              low = parseFloat(std_mon_tmp * item.almLowCoe).toHold(TEMP);
              lowLow = parseFloat(std_mon_tmp * item.almLowCoeLower).toHold(
                TEMP
              );
              if (this.cdshStatus == "cdsh") {
                guides = this.guidesData.monTemp;
              }
              break;
            case "Resistance":
              // 单体电阻
              // 单位内阻告警基准值从电池信息中取标称内阻值来计算  20240428
              // let std_mon_res =
              //   (1 * (batt.monVolStd / 2)) / (batt.monCapStd / 100);
              let std_mon_res = batt.monResStd;
              high = parseFloat(std_mon_res * item.almHighCoe).toHold(RES);
              highHigh = parseFloat(std_mon_res * item.almHighCoeUpper).toHold(
                RES
              );
              low = parseFloat(std_mon_res * item.almLowCoe).toHold(RES);
              lowLow = parseFloat(std_mon_res * item.almLowCoeLower).toHold(
                RES
              );
              if (this.cdshStatus == "cdsh") {
                guides = this.guidesData.monRes;
              }
              break;
            case "Conductance":
              // 单体电导
              let std_mon_ser = batt.monSerStd;
              high = parseFloat(std_mon_ser * item.almHighCoe).toHold(CONDUCT);
              highHigh = parseFloat(std_mon_ser * item.almHighCoeUpper).toHold(
                CONDUCT
              );
              low = parseFloat(std_mon_ser * item.almLowCoe).toHold(CONDUCT);
              lowLow = parseFloat(std_mon_ser * item.almLowCoeLower).toHold(
                CONDUCT
              );
              if (this.cdshStatus == "cdsh") {
                guides = this.guidesData.monConduct;
              }
              break;
            case "leakVol":
              // 漏液电压
              high = parseFloat(item.almHighCoe);
              highHigh = parseFloat(item.almHighCoeUpper);
              low = parseFloat(item.almLowCoe);
              lowLow = parseFloat(item.almLowCoeLower);
              if (this.cdshStatus == "cdsh") {
                guides = this.guidesData.leakVol;
              }
              break;
          }
          // debugger
          // 下限预告警
          chartData.series[0].markLine.data[0].yAxis = low;
          // 下限告警
          chartData.series[0].markLine.data[1].yAxis = lowLow;
          // 上限预告警
          chartData.series[0].markLine.data[2].yAxis = high;
          // 上限告警
          chartData.series[0].markLine.data[3].yAxis = highHigh;
          if (this.cdshStatus == "cdsh") {
            //参考线
            chartData.series[0].markLine.data[4].yAxis = guides;
          }
          // 单体电压柱状图添加标称电压横线
          if (name === "Voltage") {
            chartData.series[0].markLine.data.push({
              name: "浮充电压",
              yAxis: (batt.monVolStd / 2) * 2.25,
              lineStyle: {
                width: 2,
                color: "#073ff6",
              },
              label: {
                color: "#ffffff",
                fontSize: 16,
                formatter: "{b}:{c}V",
                position: "insideEndTop",
                padding: [6, 4, 2, 4],
                backgroundColor: "#073ff680",
                borderWidth: 2,
                borderColor: "#ffffff80",
              },
              emphasis: {
                type: "dashed",
              },
            });
          }
          break;
        }
      }
    },
    // 获取电池组参考线
    getGuides: function (resdata) {
      let vm = this;
      let batt = this.batt;
      let obj = {
        battGroupId: batt.battGroupId,
      };
      getGuidesData(obj).then((res) => {
        let rs = res.data;
        if (rs.code == 1) {
          vm.guidesData = rs.data;
          //console.log(vm.guidesData);
          vm.setLin(resdata);
        }
        //console.log(vm.guidesData);
      });
    },
    // 设置参考线弹窗
    setGuidesAlert: function () {
      let vm = this;
      let params = (function () {
        let obj = {};
        for (const key in vm.guidesData) {
          if (key == "id") {
            if (vm.guidesData[key] != null) {
              obj[key] = vm.guidesData[key];
            }
          } else {
            obj[key] = vm.guidesData[key];
          }
        }
        return obj;
      })();
      if (params.battGroupId == null) {
        params.battGroupId = vm.batt.battGroupId;
      }
      if (vm.guidesVal != "") {
        switch (vm.acTabs) {
          case "vol": //电压
            params.monVol = vm.guidesVal;
            break;
          case "res": //内阻
            params.monRes = vm.guidesVal;
            break;
          case "temp": //温度
            params.monTemp = vm.guidesVal;
            break;
          case "conduct": //电导
            params.monConduct = vm.guidesVal;
            break;
          case "leakVol": //漏液电压
            params.leakVol = vm.guidesVal;
            break;
        }
        setGuidesData(params).then((rs) => {
          let res = rs.data;
          if (res.code == 1) {
            if (res.data) {
              vm.$message({
                message: res.msg,
                type: "success",
              });
              vm.guidesVal = "";
              vm.guidesDialog = false;
              vm.realTimeAlarmss();
            } else {
              vm.$message.error(res.msg);
            }
          } else {
            vm.$message.error(res.msg);
          }
        });
      } else {
        vm.$message({
          message: "请先填写参考线值!",
          type: "warning",
        });
      }
    },
    /* 查询电路图开关状态和信息 */
    realTimePowerOffs(res) {
      // 查询后台数据
      if (res) {
        // res = res.data;
        let outTime = 2 * 60; //设备超时时间(2分钟)
        if (res.code && res.data) {
          let data = res.data2;
          // 设置版本号
          this.devVersion = data.devVersion;
          // 基础信息
          this.setEquipBase(data);
          // 判断是否超时
          let nowTime = new Date(data.note).getTime(); //当前时间
          let record = new Date(data.recordDatetime).getTime();
          // 开启模拟
          if (sysConfig.analogData.value) {
            nowTime = new Date(data.recordDatetime).getTime();
          }
          if (Math.abs(nowTime - record) / 1000 > outTime) {
            this.disconnect();
          } else {
            // 未超时执行逻辑
            let devId = this.devId;
            this.diagram.powerCut = 0;
            // 设备为61850
            if (regEquipType(devId, "dyhr")) {
              this.setEquip61850(data);
            } else {
              this.disconnect();
            }
          }
        } else {
          // 设置版本号
          this.devVersion = "";
          // 设备处于未连接
          this.disconnect();
        }
      }
    },
    setBts9150Dev(res) {
      // 非9150设备直接返回不进行处理
      if (!res) {
        return;
      }
      let index = Number(this.batt.groupIndexInFBSDevice);
      if (res.code === 1 && res.data) {
        this.diagram.bypass = res.data2;
        if (index === 1) {
          this.diagram.bypass.k1St = res.data2.k2St;
          this.diagram.bypass.k1CheckSt = res.data2.k2CheckSt;
        }
      } else {
        this.diagram.bypass = {
          drynodeCommst: 0xaaaa, // 干接点通信状态(0xAAAA-正常  0xBBBB-异常)
          k1CheckSt: 0xaaaa, // 接触器k1检测状态(0xAAAA-正常  0xBBBB-异常)
          k1St: 0, // 接触器k1状态(0-断开  1-闭合)
          urgentswitchSt: 0xaaaa, // 急停状态(0xAAAA-未触发  0xBBBB-触发)
          bypassswitchSt: 0xaaaa, // 旁路状态(0xAAAA-未接入  0xBBBB-接入旁路)
        };
      }
    },
    disconnect() {
      console.log("disconnect", "=============");
      // 设备未连接
      this.diagram.type = -1;
      this.setStateList("workState", "未连接");
      if (this.isBTS9140) {
        this.workState = "未连接";
      }
      this.diagram.temp = 0;
      // 通讯状态
      this.setStateList("connect", "异常", "table-row-error");
      // 温度
      this.setStateList("devTemp", "未知", "table-row-warn");
      // 干接点
      this.setStateList("contact", "未知", "table-row-warn");
      // 核容终止原因
      this.setStateList("stopReasonIm", "未知");
      // 操作失败原因
      this.setStateList("failReason", "未知");
      // 预估续航时长
      //this.setStateList("xuHang", "???");
      // 显示遮罩层
      this.maskShow = true;
    },
    // 基础信息
    setEquipBase(data) {
      let groupIndex = this.batt.groupIndexInFBSDevice;
      // 设备的温度
      this.diagram.temp = data.devTemp;
      let contactRes = (
        groupIndex != 0 ? data.devConresist1 : data.devConresist
      ).toHold(RES);
      let dropVol = (
        groupIndex != 0 ? data.devCondvoldp1 : data.devCondvoldp
      ).toHold(VOL);
      let alarms = data.dev61850alarms.split(",");
      if (alarms.length) {
        this.diagram.contactRes = alarms[0] == "true" ? "k1异常" : contactRes;
        this.diagram.dropVol = alarms[3] == "true" ? "D1异常" : dropVol;
      } else {
        this.diagram.contactRes = contactRes;
        this.diagram.dropVol = dropVol;
      }
    },
    // 61850设备信息
    setEquip61850(data) {
      //  电路图类型
      let workstatus = parseInt(data.devWorkstate); //[0:'在线监测',1:'充电测试',2:'放电测试',3:'内阻测试',4:'未知'];
      this.diagram.desc = "";
      // 关闭遮罩层
      this.maskShow = false;
      // 设置停电放电状态
      if (data.devOnlinevollow) {
        this.diagram.type = 5;
        this.diagram.desc = "(开关闭合)";
        this.diagram.powerCut = 1;
        // 当前设备是BTS设备
        if (workstatus === 0 && data.devResTestState !== 0) {
          this.diagram.desc += "(内阻测试)";
        }
        return;
      }
      switch (workstatus) {
        case 0: //浮充状态拓扑图
          this.diagram.type = 0;
          this.diagram.desc = "(开关闭合)";
          break;
        case 4: //浮充状态(内阻测试)拓扑图
          this.diagram.type = 0;
          // 当前设备是否是内阻测试
          this.diagram.desc = "(开关闭合)";
          this.diagram.desc += "(内阻测试)";
          break;
        case 1: //充电状态拓扑图
          this.diagram.type = 2;
          this.diagram.desc = "(开关断开)";
          break;
        case 2: //放电状态拓扑图
          this.diagram.type = 1;
          this.diagram.desc = "(开关断开)";
          break;
        case 3: //放电状态拓扑图
          this.diagram.type = 5;
          break;
        case 5: //放电状态(KD测试)拓扑图
          this.diagram.type = 3;
          this.diagram.desc = "(开关断开)";
          this.diagram.desc += "(KD测试)";
          break;
        case 6: // 离线养护测试
          this.diagram.type = 4;
          this.diagram.desc = "离线养护测试";
          break;
        default:
          //未知
          this.diagram.type = -1;
          this.diagram.desc = "(未知)";
          this.maskShow = true;
          break;
      }
      // 设备工作状态
      let workStates = const_61850.workstates;
      this.setStateList("workState", workStates[data.devWorkstate]);
      // 核容终止原因
      let stopReasons = const_61850.stopreasons;
      if (data.devWorkstate == 2) {
        this.setStateList("stopReasonIm", "未知");
      } else {
        this.setStateList(
          "stopReasonIm",
          stopReasons[data.devLastCaptestStopType]
        );
      }
      // 操作失败原因
      let failReasons = const_61850.failreasons;
      // 校验61852设备
      let pattern = /^61852/;
      if (pattern.test(data.devId)) {
        failReasons = const_61852.failreasons;
      }
      this.setStateList("failReason", failReasons[data.devAlarmstate]);
      // 告警信息
      let alarms = data.dev61850alarms.split(",");
      // alarms = ['false', 'false', 'true', 'false', 'true'];
      // 通讯状态
      if (alarms[1] == "true") {
        this.setStateList("connect", "异常", "table-row-error");
      } else {
        this.setStateList("connect", "正常", "");
      }
      // 温度
      if (alarms[2] == "true") {
        this.setStateList("devTemp", "异常", "table-row-error");
      } else {
        this.setStateList("devTemp", "正常", "");
      }
      // 干接点
      if (alarms[4] == "true") {
        this.setStateList("contact", "异常", "table-row-error");
      } else {
        this.setStateList("contact", "正常", "");
      }
    },
    // 设置stateList的值
    setStateList(name, value, type) {
      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 : "";
        }
      }
      let historyStateList = this.historyStateList;
      for (let i = 0; i < historyStateList.length; i++) {
        let state = historyStateList[i];
        if (state.name == name) {
          state.value = value;
          state.type = type ? type : "";
        }
      }
      for (
        let i = 0, list = this.lastCapacityTest, j = list.length;
        i < j;
        i++
      ) {
        let state = list[i];
        if (state.name == name) {
          state.value = value;
          state.type = type || "";
        }
      }
    },
    setTableRowClass({ row, rowIndex }) {
      let data = this.table.datas;
      if (rowIndex > 0 && data[rowIndex - 1].groupIdx != row.groupIdx) {
        return "main-row";
      }
      // if (row.monState == 1) {
      //   return "red-row";
      // } else if (row.monState == 2) {
      //   return "green-row";
      // }
      return "";
    },
    /* echars图表 */
    realTimeSearch(res) {
      //console.log(res);
      if (res) {
        let diagramType = this.diagram.type;
        // TODO
        diagramType = 0;
        let data = [];
        let list = [];
        if (res.code && res.data && res.data2 && diagramType != -1) {
          Object.keys(res.data2).forEach((v) => {
            let arr = res.data2[v];
            arr.forEach((vv) => {
              vv.groupIdx = v == 0 ? "组一" : "组二";
              vv.groupIndex = v * 1;
              list.push(vv);
            });
          });
          data = list.map((item) => {
            return {
              groupIdx: item.groupIdx,
              groupIndex: item.groupIndex,
              num1: "#" + item.monNum,
              vol1: item.monVol.toHold(VOL),
              res1: item.monRes.toHold(RES),
              temp1: item.monTmp.toHold(TEMP),
              conduct1: item.monRes
                ? ((1 / item.monRes) * 1000).toHold(CONDUCT)
                : 0,
              curr1: item.monJhCurr.toHold(CURR),
              leakVol1: item.monLyVol.toHold(VOL),
              monConnRes: item.monConnRes.toHold(RES),
              monCap: item.monCap.toHold(CAP),
              monTestCap:
                diagramType == 1 || diagramType == 2 || diagramType == 6
                  ? item.monTestCap
                  : "---",
              monResCap:
                diagramType == 1 || diagramType == 2 || diagramType == 6
                  ? item.monRestCap
                  : "---",
              monDisTimeLong:
                diagramType == 1 || diagramType == 2 || diagramType == 6
                  ? Math.floor(item.monDisTimelong / 60) +
                    "时" +
                    (item.monDisTimelong % 60) +
                    "分"
                  : "---",
              monState: item.monState,
            };
          });
        }
        this.table.datas = data;
        // 更新图表
        this.updateChart();
      }
    },
    updateChart() {
      let data = this.table.datas;
      let idx = this.chartGroupIdx;
      let diagramType = 2 || this.diagram.type;
      let list = data.filter((v) => v.groupIndex == idx);
      // 电压值
      let volTempVol = [];
      volTempVol = list.map((item) => {
        let value = diagramType == -1 ? 0 : item.vol1;
        return [item.num1, value];
      });
      // 设置电压值
      this.monVols = volTempVol.map((item) => {
        return item[1];
      });
      let volBarNum = getBarNum(volTempVol);
      vol.title.text =
        "最大值=" +
        volBarNum.max.toHold(VOL) +
        "V  最小值=" +
        volBarNum.min.toHold(VOL) +
        "V  平均值=" +
        volBarNum.avg.toHold(VOL) +
        "V";
      vol.series[0].data = volTempVol;
      // 内阻
      let volTempres = [];
      volTempres = list.map((item) => {
        let value = diagramType == -1 ? 0 : item.res1;
        return [item.num1, value];
      });
      let resBarNum = getBarNum(volTempres);
      resChart.title.text =
        "最大值=" +
        resBarNum.max.toHold(RES) +
        "mΩ  最小值=" +
        resBarNum.min.toHold(RES) +
        "mΩ  平均值=" +
        resBarNum.avg.toHold(RES) +
        "mΩ";
      resChart.series[0].data = volTempres;
      // 温度
      let volTempte = [];
      volTempte = list.map((item) => {
        let value = diagramType == -1 ? 0 : item.temp1;
        return [item.num1, value];
      });
      this.monTemps = volTempte.map((item) => {
        return item[1];
      });
      let tempBarNum = getBarNum(volTempte);
      temp.title.text =
        "最大值=" +
        tempBarNum.max.toHold(TEMP) +
        "℃  最小值=" +
        tempBarNum.min.toHold(TEMP) +
        "℃  平均值=" +
        tempBarNum.avg.toHold(TEMP) +
        "℃";
      temp.series[0].data = volTempte;
      // 更新电压图表
      this.setChart();
    },
    getMonStates(battGroupId, monNum, monState) {
      return {
        battGroupId,
        monNum,
        commFail: getBit(monState, 0), // 通信故障
        volHigh: getBit(monState, 1), // 过压
        volLow: getBit(monState, 2), // 欠压
        tempHigh: getBit(monState, 3), // 超温
        resHigh: getBit(monState, 4), // 内阻高
        posLeak: getBit(monState, 5), // 正极漏液
        negLeak: getBit(monState, 6), // 负极漏液
        tempError: getBit(monState, 7), // 温度故障
        resError: getBit(monState, 8), // 内阻故障
        battBulging: getBit(monState, 9), // 电池鼓胀
        junHengError: getBit(monState, 10), // 均衡维护故障
        monTempLow: getBit(monState, 11), // 单体温度超下限
        battMainting: getBit(monState, 12), // 电池处于维护中
      };
    },
    // 向父级发送同步页面的指令
    syncPage() {
      let batt = this.batt;
      let search =
        "?province=" +
        batt.stationName1 +
        "&city=" +
        batt.stationName2 +
        "&county=" +
        batt.stationName5 +
        "&home=" +
        batt.stationName3 +
        "&batt=" +
        batt.battGroupId +
        "&pageFlag=" +
        Math.random();
      let url = "/dataTest/history";
      if (regEquipType(batt.fbsdeviceId, "LD9")) {
        url = "/dataTest/historyLD9";
      }
      this.$router.push(url + search);
    },
    // 停止测试
    stopTest() {
      this.$layer.confirm(
        "停止测试",
        {
          icon: 3,
        },
        (index) => {
          // 关闭询问层
          this.$layer.close(index);
          this.stop61850Test();
        }
      );
    },
    // 停止61850测试
    stop61850Test() {
      // 开启等待框
      let loading = this.$layer.loading(1);
      // 请求后台
      btsControl({
        num: const_61850.cmd.stop,
        devId: this.devId,
        battGroupNum: 1,
      })
        .then((res) => {
          res = res.data;
          if (res.code) {
            // 提示信息
            this.$layer.msg("停止测试成功");
          } else {
            // 提示信息
            this.$layer.msg("停止测试失败!");
          }
          // 关闭等待框
          this.$layer.close(loading);
        })
        .catch((error) => {
          console.log(error);
          // 关闭等待框
          this.$layer.close(loading);
          // 提示信息
          this.$layer.msg("停止测试失败,停止测试请求异常!");
        });
    },
    getStateById(id, list) {
      let result = true;
      for (let i = 0; i < list.length; i++) {
        let item = list[i];
        if (id == item.id) {
          result = item.status ? true : false;
          break;
        }
      }
      return result;
    },
    /**
     * 读取锂电池信息 暂定读取组一的
     */
    getLithiumAnalog(res) {
      if (res) {
        // res = res.data;
        if (res.code && res.data) {
          // 剩余容量进行累加
          let restCap = 0;
          let packVols = [];
          let packCurrs = [];
          res.data2.map((item) => {
            restCap += item.restCap;
            packVols.push(item.sumVol);
            packCurrs.push(item.current);
          });
          this.packVols = packVols;
          this.packCurrs = packCurrs;
          let data = res.data2[0];
          data.restCap = restCap;
          this.lithiumParams.analog = data;
        } else {
          this.lithiumParams.analog = lithiumInfo.analog().params;
        }
      }
    },
    realTimeStateList(res) {
      // 获取剩余天数,工作模式,组端电压,峰值电压
      // let batt = this.batt;
      // 仅有编号不做任何操作
      if (this.fodHeaders.length == 1) {
        return;
      }
      if (res) {
        // res = res.data;
        let data = [];
        if (res.code && res.data) {
          let rsData = res.data2;
          let workModels = ["停止", "养护", "除硫"];
          let list = ["One", "Two", "Three", "Four", "Five"];
          let fodHeaders = this.fodHeaders;
          data = list.map((item, index) => {
            let workModel = rsData["workstate" + item];
            return fodHeaders.map((fod) => {
              if (fod.prop == "num") {
                return index + 1;
              } else if (fod.prop == "workstate") {
                return workModels[workModel];
              } else {
                return rsData[fod.prop + item];
              }
            });
            //return [index+1, rsData['RestTime_'+item], workModels[workModel], rsData['vgroupvol'+item], rsData['vpeakvol'+item]]
          });
          this.fodData = data;
        }
      }
    },
    // 初始化时lifeFlag传true 页面销毁时传false
    monitorPage(lifeFlag) {
      if (!lifeFlag) {
        return;
      }
      let url = this.$route.meta.url || "";
      if (url == "/dataTest/realTime" && this.acTabs === "eleLine") {
        this.diagram.update = true;
      } else {
        this.diagram.update = false;
      }
      // 启动监控
      requestAnimationFrame(() => {
        this.monitorPage(true);
      });
    },
    setRightMenuPos(x, y) {
      this.rightMenu.show = true;
      this.rightMenu.x = x;
      this.rightMenu.y = y;
    },
    chartRightCLick(params) {
      this.rightMenu.show = true;
      this.rightMenu.x = params.x;
      this.rightMenu.y = params.y;
      this.rightMenu.xIndex = params.xIndex;
    },
    payAttentionMon() {
      let searchParams = {
        battGroupId: this.batt.battGroupId,
        monNum: this.rightMenu.xIndex + 1,
      };
      // 查询
      realTimeNot(searchParams)
        .then((res) => {
          res = res.data;
          if (res.code && res.data) {
            this.$layer.msg("单体#" + searchParams.monNum + "已被关注");
          } else {
            this.addAttentionMon(searchParams);
          }
        })
        .catch((error) => {
          console.log(error);
        });
    },
    addAttentionMon(params) {
      let loading = this.$layer.loading(1);
      // 请求后台添加
      realTimeAdd(params)
        .then((res) => {
          res = res.data;
          if (res.code && res.data) {
            this.$layer.msg("成功关注单体#" + params.monNum);
          } else {
            this.$layer.msg("添加失败");
          }
          this.$layer.close(loading);
        })
        .catch((error) => {
          this.$layer.close(loading);
          console.log(error);
        });
    },
    closeDisChargeDialog() {
      this.dischargeDialog.show = false;
    },
    restartSystem() {
      if (sysConfig.restartDevByFace.value) {
        this.restartFaceShow = true;
      } else {
        let resetPwd = "restart123456";
        this.$prompt("请输入重启密码", "提示", {
          confirmButtonText: "确定",
          cancelButtonText: "取消",
          inputType: "password",
        })
          .then(({ value }) => {
            if (value == resetPwd) {
              this.restartSystemReq();
            } else {
              this.$layer.msg("密码不正确");
            }
          })
          .catch(() => {});
      }
    },
    restartFaceSuccess() {
      this.restartFaceShow = false;
      this.restartSystemReq();
    },
    restartSystemReq() {
      let loading = this.$layer.loading();
      restart({
        devId: this.devId,
        opCmd: 16,
      })
        .then((res) => {
          res = res.data;
          if (res.code && res.data) {
            this.$alert("发送重启命令成功", "系统提示");
          } else {
            this.$alert("发送重启命令失败!", "系统提示");
          }
          this.$layer.close(loading);
        })
        .catch((error) => {});
    },
    stopOutLineCuring() {
      this.stopTime = new Date().getTime();
      console.log(this.stopTime);
    },
    updateDevTime() {
      this.updateDevTimeInfo.date = new Date().format("yyyy-MM-dd hh:mm:ss");
      this.updateDevTimeInfo.visible = true;
    },
    regularTestRes() {
      this.regularTestResInfo.visible = true;
    },
    alarmParamsShow() {
      this.alarmParamsInfo.visible = true;
    },
    confirmUpdateDevTime() {
      this.$confirm("确定更新设备时间?", "提示", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning",
      })
        .then(async () => {
          let loading = this.$layer.loading();
          try {
            const devId = this.batt.fbsdeviceId;
            const date = new Date(this.updateDevTimeInfo.date).format(
              "yyyy-MM-dd hh:mm:ss"
            );
            const res = await updateDevTimeApi(devId, date);
            this.$layer.close(loading);
            const rs = res.data;
            if (rs.code === 1 && rs.data) {
              this.updateDevTimeInfo.visible = false;
              this.$message.success("更新成功!!!");
            } else {
              this.$message.error("更新失败,请检查网络。");
            }
          } catch (e) {
            this.$layer.close(loading);
            console.log(e);
            this.$message.error("更新失败, 请检查网络。");
          }
        })
        .catch(() => {
          this.$message({
            type: "info",
            message: "更新失败",
          });
        });
    },
    getStationPic() {
      let batt = this.batt;
      if (sysConfig.clientName.name == "sxty") {
        this.getQRStationPic();
      } else {
        getStationPic(batt.stationId)
          .then((res) => {
            let rs = res.data;
            let data = [];
            if (rs.code == 1) {
              data = rs.data ? rs.data : [];
            }
            this.stationImages = data;
          })
          .catch((error) => {
            console.log(error);
          });
      }
    },
    getQRStationPic() {
      let mId = this.batt.mid;
      qrCode
        .battery(mId)
        .then((res) => {
          let rs = res.data;
          let pics = "";
          if (rs.code == 200) {
            pics = rs.data.pics;
          }
          this.stationImages = pics ? pics.split(",") : [];
        })
        .catch((error) => {
          this.stationImages = [];
        });
    },
    // 导出表格
    exportFile() {
      let batt = this.stationInf;
      let time = new Date().getTime();
      if (this.table.datas.length === 0) {
        this.$message.warning("暂无数据,无需导出");
        return false;
      }
      ExportFile(
        this.dataHeaders,
        this.table.datas,
        batt.stationName + "-电池实时数据(" + time + ")"
      );
    },
    chooseBattGroup(fn) {
      this.chooseBattGroupVisible = true;
      this.chooseBattGroupFn = fn;
    },
    chooseBattGroupOk(idx) {
      this.chooseBattGroupVisible = false;
      this.currBatt = this.battList[idx];
      this[this.chooseBattGroupFn]();
    },
    showHisRtData() {
      this.historyRealTimeDataDialog.show = true;
    },
    goToBattWarnSetting() {
      // let batt = this.batt;
      let fbsdeviceId = this.devId;
      const search =
        "?fbsdeviceId=" + fbsdeviceId + "&pageFlag=" + Math.random();
      // 电源参数设置界面
      this.$router.push(
        "/alarmMager/devicepaSetting" + search + "&fromType=fromIndex"
      );
    },
    getBattRecords(battGroupId) {
      // 查询
      getBattRecords(battGroupId)
        .then((res) => {
          let { code, data, data2 } = res.data;
          let list = [];
          if (code && data) {
            list = data2;
          }
          //console.log(list);
          this.battRecords = list;
        })
        .catch((err) => {
          console.log(err);
        });
    },
    showSend() {
      this.dischargeDialog.show = true;
    },
    startTest(idx) {
      this.currBatt = this.battList[idx];
      this.dischargeDialog.show = true;
    },
    confirmStartResTest() {
      this.$layer.prompt(
        {
          title: "输入启动口令,并确认",
          formType: 2,
          area: ["300px", "180px"],
        },
        (pass, index) => {
          // 请求后台校验密码
          checkUserPwd(pass)
            .then((res) => {
              res = res.data;
              if (res.code) {
                // 关闭弹出框
                this.$layer.close(index);
                // 启动内阻测试
                this.startResTest();
              } else {
                this.$layer.msg("启动口令错误!");
              }
            })
            .catch((error) => {
              console.log(error);
              this.$layer.msg("网络请求异常");
            });
        }
      );
    },
    async startResTest() {
      let loading = this.$layer.loading(1);
      let batt = this.batt;
      try {
        const res = await startResTest(
          batt.fbsdeviceId,
          batt.groupIndexInFBSDevice + 1
        );
        this.$layer.close(loading);
        const rs = res.data;
        if (rs.code && rs.data) {
          // 提示信息
          this.$layer.msg("启动测试成功");
        } else {
          // 提示信息
          this.$layer.msg("启动测试失败!");
        }
      } catch (e) {
        console.log(e);
        this.$layer.close(loading);
        // 提示信息
        this.$layer.msg("启动测试失败, 请检查网络!");
      }
    },
    refreshFN() {
      // 如果是跳过来放电  则要验证条件 1 通讯正常   2 状态为停止
      let disCharge = this.$route.query.disCharge;
      if (disCharge) {
        this.checkLink();
      }
    },
    checkLink() {
      setTimeout(() => {
        if (this.dataChangeFlag) {
          if (this.isLink) {
            this.$message.error("当前设置未连接, 无法放电");
          } else {
            this.dischargeDialog.show = true;
          }
          return false;
        }
        this.checkLink();
      }, 500);
    },
  },
  computed: {
    stationFullName() {
      let station = this.stationInf;
      if (station && station.stationName3 && station.stationName4) {
        return station.stationName3 + "-" + station.stationName4;
      }
      return "设备全称";
    },
    dischargeDialogTitle() {
      let batt = this.stationInf || {};
      if (regEquipType(batt.fbsdeviceId, ["dyhr"])) {
        return "放电参数设置";
      } else {
        return "未知设备(待开发)";
      }
    },
    histroyDataTitle() {
      return this.stationInf?.stationName + "-历史实时数据";
    },
    // 设备连接状态1为未连接 0正常
    isLink() {
      return this.diagram.type == -1 ? 1 : 0;
    },
    dataHeaders() {
      let headers = this.table.headers;
      let tabConfig = this.pageConfig;
      let batt = this.batt;
      return headers.filter((item) => {
        let isShow = item.key1 ? tabConfig[item.key1] : true;
        if (item.type) {
          isShow = regEquipType(batt.fbsdeviceId, item.type);
        }
        return isShow;
      });
    },
  },
  mounted() {
    let devId = this.$route.params.devId;
    let stationId = this.$route.params.stationId;
    // console.log("mounted======", devId);
    if (devId) {
      this.devId = devId;
      this.homeListShow = false;
    }
    this.getBattList(stationId);
    // 查询控制按钮的配置
    this.searchControl();
    // 初始化图表
    this.initChart();
    this.$nextTick(() => {
      this.$G.chartManage.resize(this.acTabs);
    });
    // 屏幕缩放时触发
    window.addEventListener("resize", this.resize);
    // 监控是否已经切换到当前页面
    this.monitorPage(true);
  },
  destroyed() {
    window.removeEventListener("resize", this.resize);
    this.monitorPage(false);
  },
};
</script>
<style scoped>
.page-real-time {
  color: #ffffff;
}
.table-cell.text-right {
  font-size: 14px;
}
.table-cell.text-right .iconfont {
  margin-right: 4px;
}
.table-row.table-row-error {
  color: #ff0000;
}
.table-row.table-row-warn {
  color: #e6a23c;
}
.table-row .table-cell {
  padding-top: 8px;
}
.page-content {
  position: relative;
  padding-top: 8px;
  padding-bottom: 2px;
  box-sizing: border-box;
  height: 100%;
}
.box-tools {
  position: static;
  line-height: 32px;
  margin-left: 6px;
}
.box-tools .iconfont,
.box-tools .el-iconfont {
  font-size: 24px;
}
.box-tools .iconfont:hover,
.box-tools .el-iconfont:hover {
  cursor: pointer;
  color: #cfcfcf;
}
.box-tools .iconfont:active,
.box-tools .el-iconfont:active {
  color: #ff0000;
}
.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);
}
.hdw-state-list {
  box-sizing: border-box;
  font-size: 14px;
  padding-bottom: 8px;
}
.table-info-list {
  width: 100%;
  font-size: 14px;
}
.table-info-list td {
  padding: 4px;
  text-align: center;
}
.noborder {
  border: none;
}
.el-table-wrapper {
  background-color: #052272;
}
.flex-box-list,
.flex-box-list-full {
  display: flex;
  flex-direction: row;
  height: 50%;
  box-sizing: border-box;
}
.flex-box-list-full {
  height: 100%;
}
.flex-box-mgr {
  margin: 16px;
}
.page-content .flex-box {
  flex: 1;
  overflow: hidden;
}
.dianchigaojing {
  padding: 5px;
  height: 100%;
}
.dianchigaojing .borderBox {
  border: 1px solid #00fefe;
  padding: 5px;
}
.dianchigaojing .borderBox.box1 {
  margin-bottom: 5px;
  height: 110px;
}
.dianchigaojing .borderBox.box2 {
  height: calc(100% - 140px);
}
.lampImg {
  height: 28px;
}
.box-header {
  font-size: 14px;
  padding: 0;
}
.threeD-dialog >>> .el-dialog {
  width: 960px;
}
.station-contain {
  height: 600px;
}
.wx_guides {
  height: 150px;
  text-align: center;
  background-color: #ffffff;
  padding-top: 15%;
}
.wx_guides p {
  display: inline-block;
  margin-right: 10px;
}
.wx_guides p /deep/.el-input__inner {
  color: #000;
}
.tbl-data-container {
  display: flex;
  flex-direction: column;
  height: 100%;
}
.tbl-data-body {
  flex: 1;
  overflow: hidden;
}
.tbl-data-footer {
  text-align: center;
}
.center-box {
  display: flex;
  height: 100%;
  align-items: center;
  justify-content: center;
}
.row-info {
  font-size: 14px;
  color: #00fefe;
}
</style>
<style scoped lang="less">
.update-dev-form-container {
  background-color: #ffffff;
  padding: 8px;
  text-align: center;
  .update-dev-form-footer {
    padding-top: 8px;
    text-align: right;
  }
}
.modal-title-wrapper {
  background-color: #00fefe;
  color: #003d64;
  font-weight: bold;
  display: flex;
  padding: 8px 0;
  .modal-title-content {
    flex: 1;
    padding: 0 8px;
    cursor: move;
  }
  .modal-title-tools {
    padding: 0 8px;
    cursor: pointer;
  }
}
.tab-power {
  height: 100%;
  padding: 4px;
  display: grid;
  gap: 2px;
  grid-template-columns: 1fr 1.8fr;
  grid-template-rows: 1fr 1.8fr;
  grid-auto-flow: column;
  /deep/ .big-screen-card {
    padding: 0;
  }
  .g-content {
    box-sizing: border-box;
    height: 100%;
    padding: 0 10px 4px;
    display: grid;
    gap: 2px 10px;
    align-content: start;
    grid-template-columns: repeat(2, 1.3fr 1fr);
    grid-template-rows: repeat(4, 30px);
    .label {
      place-self: center end;
      padding-right: 0.4em;
      &::after {
        content: ":";
      }
    }
    .value {
      background: #000;
      line-height: 30px;
      padding-left: 0.6em;
      color: #ffea70;
      border-radius: 4px;
      // height: 30px;
    }
  }
  .module-info {
    grid-row-start: span 2;
    /deep/ .big-screen-card-body {
      display: flex;
      flex-direction: column;
    }
    .g-content {
      height: auto;
      grid-template-columns: repeat(4, 1.5fr 1fr);
      grid-template-rows: repeat(3, 30px);
    }
    .table-module {
      flex: 1;
      position: relative;
      .tbl-data-body {
        position: absolute;
        left: 0;
        top: 0;
        right: 0;
        bottom: 0;
      }
    }
  }
}
.select-group {
  position: absolute;
  top: 6px;
  left: 5em;
  z-index: 1;
}
/deep/ .main-row {
  box-shadow: inset 0 1px 0 #00fefe;
}
.choose-batt {
  background: #f0f0f0;
  padding: 20px;
  text-align: center;
}
</style>
src/views/home/components/svg/svgAcin.vue
New file
@@ -0,0 +1,193 @@
<template>
  <g ref="g" :transform="'translate(' + offset.join(',') + ')'">
    <!-- <defs>
      <circle id="ball" :r="ballR" />
    </defs> -->
    <polyline
      :points="pointsStr"
      :stroke="color"
      :stroke-width="lineWidth"
      style="fill: none"
    />
    <path :d="path" ref="path" style="fill: none; stroke: none"></path>
  </g>
</template>
<script>
export default {
  name: "",
  props: {
    offset: {
      type: Array,
      default() {
        return [0, 0];
      },
    },
    points: {
      type: Array,
      default() {
        return [
          [0, 0],
          [10, 10],
        ];
      },
    },
    color: {
      type: String,
      default: "#f59a23",
    },
    status: {
      type: Number,
      default: 0,
    },
    currColor: {
      type: String,
      default: "#0f0",
    },
    lineWidth: {
      type: [Number, String],
      default: 2,
    },
  },
  computed: {
    path() {
      let points = this.points;
      let path = `M ${points[0].join(",")} `;
      for (let i = 1, len = points.length; i < len; i++) {
        path += ` L ${points[i].join(",")} `;
      }
      return path;
    },
    pointsStr() {
      return this.points.join(' ');
    },
    // pathLength() {
    //   return this.$refs.path.getTotalLength();
    // },
  },
  data() {
    return {
      tailCount: 3,
      ballR: 6,
      // ballSpeed: 2,
      ballSpeed: 1,
      currentPosition: 0,
    };
  },
  watch: {
    // status: {
    //   handler(n) {
    //     this.$nextTick(() => {
    //       this.move();
    //     });
    //   },
    //   immediate: true,
    // },
  },
  components: {},
  methods: {
    // move() {
    //   if (!this.status) {
    //     return false;
    //   }
    //   let {
    //     currentPosition,
    //     pathLength,
    //     ballCount,
    //     $refs: { path },
    //   } = this;
    //   if (currentPosition >= pathLength) {
    //     // 循环回到起点
    //     this.currentPosition = currentPosition % pathLength;
    //   }
    //   let _pathLen = pathLength / ballCount;
    //   for (let i = 0, len = ballCount; i < len; i++) {
    //     let _currentPosition = (currentPosition + _pathLen * i) % pathLength;
    //     let pos = path.getPointAtLength(_currentPosition);
    //     let $ball = this.$refs["ball_" + i][0];
    //     // console.log($ball, 'ball');
    //     $ball.setAttribute("x", pos.x);
    //     $ball.setAttribute("y", pos.y);
    //     for (let m = 0, tlen = this.tailCount; m < tlen; m++) {
    //       let tailPos = _currentPosition - 3.4 * (m + 1);
    //       tailPos = tailPos >= 0 ? tailPos : pathLength + tailPos;
    //       let pos2 = path.getPointAtLength(tailPos);
    //       let $tail = this.$refs["tail_" + i + "_" + m][0];
    //       $tail.setAttribute("x", pos2.x);
    //       $tail.setAttribute("y", pos2.y);
    //     }
    //   }
    //   // 更新当前位置
    //   this.currentPosition += this.ballSpeed * this.status;
    //   requestAnimationFrame(this.move);
    // },
    // getPathLength() {
    //   this.pathLength = this.$refs.path.getTotalLength();
    // },
  },
  mounted() {
  },
};
</script>
<style scoped lang="less">
// .g-rect-fill {
//   fill: none;
//   // stroke-width: 5;
//   stroke-linejoin: round;
//   stroke-linecap: round;
//   stroke-dashoffset: -100;
//   // stroke-dasharray: 3, 900;
// }
// .move {
//   stroke-width: 7;
//   // stroke-dasharray: 43, 87;
//   stroke-dasharray: 23, 107;
//   animation: lineMove 1.8s cubic-bezier(0.05, 0.1, 0.8, 1) infinite;
// }
// .move1 {
//   stroke-width: 5;
//   stroke-dasharray: 23, 107;
//   animation: lineMove 1.8s cubic-bezier(0, 0, 1, 1) infinite;
// }
// .move-dis {
//   stroke-width: 7;
//   stroke-dasharray: 23, 107;
//   animation: lineMoveDis 1.8s cubic-bezier(0.05, 0.1, 0.8, 1) infinite;
// }
// .move-dis1 {
//   stroke-width: 5;
//   stroke-dasharray: 23, 107;
//   animation: lineMoveDis 1.8s cubic-bezier(0, 0, 1, 1) infinite;
//   // &.line1 {
//   //   animation: lineMoveDis1 1.8s cubic-bezier(0, 0, 1, 1) infinite;
//   // }
// }
// @keyframes lineMove {
//   0% {
//     // stroke-dashoffset: -850;
//     stroke-dashoffset: -260;
//   }
//   100% {
//     stroke-dashoffset: 0;
//   }
// }
// @keyframes lineMoveDis {
//   0% {
//     // stroke-dashoffset: -850;
//     stroke-dashoffset: 260;
//   }
//   100% {
//     stroke-dashoffset: 0;
//   }
// }
</style>
src/views/home/components/svg/svgBatts.vue
New file
@@ -0,0 +1,114 @@
<template>
  <g :transform="transform">
    <image
      :x="width / -2"
      :width="width"
      :height="battHeight"
      :xlink:href="imgBatt"
    />
    <line
      :y1="battHeight"
      :y2="battHeight + distance"
      stroke-width="4"
      stroke="#fff"
      stroke-dasharray="4,2"
    ></line>
    <image
      :x="width / -2"
      :y="battHeight + distance"
      :width="width"
      :height="battHeight"
      :xlink:href="imgBatt"
    />
  </g>
</template>
<script>
import imgBatt from "./images/elegroup.png";
export default {
  name: "",
  props: {
    offset: {
      type: Array,
      default() {
        return [0, 0];
      },
    },
    width: {
      type: Number,
      default: 40,
    },
    height: {
      type: Number,
      default: 160,
    },
    distance: {
      type: Number,
      default: 20,
    },
    points: {
      type: Array,
      default() {
        return [
          [0, 0],
          [10, 10],
        ];
      },
    },
    // 方向为电池正极指向
    direct: {
      type: String,
      default: "top",
      validator: (v) => ["left", "right", "top", "bottom"].includes(v),
    },
    color: {
      type: String,
      default: "#f59a23",
    },
    status: {
      type: Number,
      default: 0,
    },
    currColor: {
      type: String,
      default: "#0f0",
    },
    lineWidth: {
      type: [Number, String],
      default: 2,
    },
  },
  computed: {
    battHeight() {
      const { width, height, distance } = this;
      return (height - distance) / 2;
    },
    transform() {
      let { offset, direct, height } = this;
      let rotate = "";
      switch (direct) {
        case "right":
          rotate = `rotate(90 0 0) translate(0 -${height})`;
          break;
        case "left":
          rotate = `rotate(-90 0 0)`;
          break;
        case "top":
          rotate = "";
          break;
        case "bottom":
          rotate = `rotate(180 0 0) translate(0 -${height})`;
          break;
      }
      return `translate(${offset.join(",")}) ${rotate}`;
    },
  },
  data() {
    return {
      imgBatt,
    };
  },
};
</script>
<style scoped lang="less"></style>
src/views/home/components/svg/svgBgText.vue
New file
@@ -0,0 +1,86 @@
<template>
  <g
    ref="g"
    :transform="
      'translate(' +
      offset.join(',') +
      ')' +
      (isVertical ? ' rotate(90 0 0)' : '')
    "
  >
    <rect
      :y="y"
      :rx="rx"
      :width="width"
      :height="height"
      stroke="none"
      :fill="color"
    ></rect>
    <text
      :x="tx"
      :font-size="fontSize"
      :fill="fontColor"
      dominant-baseline="middle"
      text-anchor="middle"
      >{{text}}</text
    >
  </g>
</template>
<script>
export default {
  name: "",
  props: {
    width: {
      type: Number,
      default: 80,
    },
    height: {
      type: Number,
      default: 30,
    },
    rx: {
      type: Number,
      default: 6,
    },
    fontSize: {
      type: Number,
      default: 60,
    },
    offset: {
      type: Array,
      default() {
        return [0, 0];
      },
    },
    isVertical: {
      type: Boolean,
      default: false,
    },
    text: {
      type: String,
      default: "~",
    },
    color: {
      type: String,
      default: "#0ff",
    },
    fontColor: {
      type: String,
      default: "#000",
    },
  },
  computed: {
    tx() {
      let { width, height, fontSize } = this;
      return width / 2;
    },
    y() {
      let { width, height, fontSize } = this;
      return height / -2;
    },
  },
};
</script>
<style scoped lang="less"></style>
src/views/home/components/svg/svgDiode.vue
New file
@@ -0,0 +1,139 @@
<template>
  <g :transform="transform">
    <polygon :points="points" stroke="none" :fill="color" />
    <line :y1="y1" :y2="y2" :stroke-width="lineWidth" :stroke="color"></line>
  </g>
</template>
<script>
export default {
  name: "",
  props: {
    len: {
      type: Number,
      default: 20,
    },
    offset: {
      type: Array,
      default() {
        return [0, 0];
      },
    },
    color: {
      type: String,
      default: "#f59a23",
    },
    lineWidth: {
      type: [Number, String],
      default: 2,
    },
    // 方向为二极管导通方向 三角形指向
    direct: {
      type: String,
      default: "left",
      validator: (v) => ["left", "right", "top", "bottom"].includes(v),
    },
  },
  computed: {
    y1() {
      let len = this.len;
      return len / -2;
    },
    y2() {
      let len = this.len;
      return len / 2;
    },
    points() {
      let lineWidth = this.lineWidth;
      let len = this.len;
      let len2 = len / 2;
      return [
        [lineWidth, 0],
        [lineWidth + Math.cos((30 * Math.PI) / 180) * len, len2],
        [lineWidth + Math.cos((30 * Math.PI) / 180) * len, -len2],
      ].join(",");
    },
    transform() {
      let { offset, direct, lineWidth, len } = this;
      let rotate = "";
      switch (direct) {
        case "left":
          rotate = "";
          break;
        case "right":
          rotate = `rotate(180 0 0) translate(-${lineWidth + Math.cos((30 * Math.PI) / 180) * len} 0)`;
          break;
        case "top":
          rotate = "rotate(90 0 0)";
          break;
        case "bottom":
          rotate = `rotate(270 0 0) translate(-${lineWidth + Math.cos((30 * Math.PI) / 180) * len} 0)`;
          break;
      }
      return `translate(${offset.join(",")}) ${rotate}`;
    },
  },
  data() {
    return {};
  },
  watch: {},
  components: {},
  methods: {},
  mounted() {},
};
</script>
<style scoped lang="less">
// .g-rect-fill {
//   fill: none;
//   // stroke-width: 5;
//   stroke-linejoin: round;
//   stroke-linecap: round;
//   stroke-dashoffset: -100;
//   // stroke-dasharray: 3, 900;
// }
// .move {
//   stroke-width: 7;
//   // stroke-dasharray: 43, 87;
//   stroke-dasharray: 23, 107;
//   animation: lineMove 1.8s cubic-bezier(0.05, 0.1, 0.8, 1) infinite;
// }
// .move1 {
//   stroke-width: 5;
//   stroke-dasharray: 23, 107;
//   animation: lineMove 1.8s cubic-bezier(0, 0, 1, 1) infinite;
// }
// .move-dis {
//   stroke-width: 7;
//   stroke-dasharray: 23, 107;
//   animation: lineMoveDis 1.8s cubic-bezier(0.05, 0.1, 0.8, 1) infinite;
// }
// .move-dis1 {
//   stroke-width: 5;
//   stroke-dasharray: 23, 107;
//   animation: lineMoveDis 1.8s cubic-bezier(0, 0, 1, 1) infinite;
//   // &.line1 {
//   //   animation: lineMoveDis1 1.8s cubic-bezier(0, 0, 1, 1) infinite;
//   // }
// }
// @keyframes lineMove {
//   0% {
//     // stroke-dashoffset: -850;
//     stroke-dashoffset: -260;
//   }
//   100% {
//     stroke-dashoffset: 0;
//   }
// }
// @keyframes lineMoveDis {
//   0% {
//     // stroke-dashoffset: -850;
//     stroke-dashoffset: 260;
//   }
//   100% {
//     stroke-dashoffset: 0;
//   }
// }
</style>
src/views/home/components/svg/svgDyhr.vue
New file
@@ -0,0 +1,873 @@
<template>
  <svg
    width="100%"
    height="100%"
    viewBox="80 100 1840 680"
    xmlns="http://www.w3.org/2000/svg"
    xmlns:xlink="http://www.w3.org/1999/xlink"
  >
    <!-- <floor :offset="[510, 70]"></floor> -->
    <!-- 工作状态 -->
    <svg-text
      :offset="[970, 110]"
      fontSize="20"
      color="#4afd88"
      textAnchor="middle"
      text="工作状态"
    ></svg-text>
    <svg-line
      :points="[
        [120, 160],
        [320, 160],
      ]"
      :lineWidth="6"
      :currColor="currColor"
    ></svg-line>
    <svg-text
      :offset="[130, 180]"
      fontSize="20"
      textAnchor="middle"
      text="AC-1"
    ></svg-text>
    <svg-text
      :offset="[130, 220]"
      fontSize="20"
      textAnchor="middle"
      text="AC-2"
    ></svg-text>
    <svg-line
      :points="[
        [120, 240],
        [320, 240],
      ]"
      :lineWidth="6"
      :currColor="currColor"
    ></svg-line>
    <svg-panel :offset="[100, 306]" width="270" height="460" title="交流进线">
      <div class="acin-info">
        <div class="group">
          <div class="g-name">交流进线1</div>
          <div class="g-content">
            <div class="label">电源频率(Hz)</div>
            <div class="value">50.0</div>
            <div class="label">A相电压(V)</div>
            <div class="value">213</div>
            <div class="label">B相电压(V)</div>
            <div class="value">205</div>
            <div class="label">C相电压(V)</div>
            <div class="value">205</div>
            <div class="label">防雷器</div>
            <div class="value">正常</div>
            <div class="label">防雷器空开</div>
            <div class="value">正常</div>
          </div>
        </div>
        <div class="group">
          <div class="g-name">交流进线2</div>
          <div class="g-content">
            <div class="label">电源频率(Hz)</div>
            <div class="value">50.0</div>
            <div class="label">A相电压(V)</div>
            <div class="value">213</div>
            <div class="label">B相电压(V)</div>
            <div class="value">205</div>
            <div class="label">C相电压(V)</div>
            <div class="value">205</div>
            <div class="label">防雷器</div>
            <div class="value">正常</div>
            <div class="label">防雷器空开</div>
            <div class="value">正常</div>
          </div>
        </div>
      </div>
    </svg-panel>
    <svg-panel :offset="[430, 306]" width="270" height="460" title="通信电源">
      <div class="power-info">
        <div class="group">
          <div class="g-content">
            <div class="label">充放电状态</div>
            <div class="value">浮充</div>
            <div class="label">母排电压(V)</div>
            <div class="value">53.82</div>
            <div class="label">电池电流(A)</div>
            <div class="value">1.98</div>
            <div class="label">模块电流(A)</div>
            <div class="value">2.98</div>
            <div class="label">负载电流(A)</div>
            <div class="value">1.98</div>
            <div class="label">A相电压(V)</div>
            <div class="value">205</div>
            <div class="label">A相电流(A)</div>
            <div class="value">1.98</div>
            <div class="label">B相电压(V)</div>
            <div class="value">205</div>
            <div class="label">B相电流(A)</div>
            <div class="value">1.98</div>
            <div class="label">C相电压(V)</div>
            <div class="value">205</div>
            <div class="label">C相电流(A)</div>
            <div class="value">1.98</div>
          </div>
        </div>
      </div>
    </svg-panel>
    <svg-switch3
      :offset="[324, 160]"
      :state="switchState.acin"
      :color="lineColor"
    ></svg-switch3>
    <svg-text
      :offset="[440, 180]"
      fontSize="20"
      textAnchor="middle"
      text="ATS"
    ></svg-text>
    <svg-line
      :points="[
        [395, 200],
        [493, 200],
      ]"
      :color="lineColor"
      :currColor="currColor"
    ></svg-line>
    <svg-module
      :offset="[493, 126]"
      width="130"
      height="170"
      type="pdg"
    ></svg-module>
    <svg-bg-text
      text="+"
      color="#f00"
      fontColor="#fff"
      :width="30"
      :height="30"
      :fontSize="30"
      :rx="30"
      :offset="[643, 250]"
    ></svg-bg-text>
    <svg-bg-text
      text="-"
      color="#fff"
      :width="30"
      :height="30"
      :fontSize="30"
      :rx="30"
      :offset="[643, 190]"
    ></svg-bg-text>
    <!-- -极线 -->
    <svg-line
      :points="[
        [623, 160],
        [1695, 160],
      ]"
      :color="lineColor"
      :currColor="currColor"
    ></svg-line>
    <svg-info :offset="[1260, 110]">
      <div class="label">电流</div>
      <div class="value">2.9A</div>
    </svg-info>
    <svg-info :offset="[1460, 110]">
      <div class="label">电流</div>
      <div class="value">49.0A</div>
    </svg-info>
    <!-- kc -->
    <svg-switch
      :offset="[1695, 160]"
      :state="switchState.kc"
      :color="lineColor"
    ></svg-switch>
    <svg-panel
      :offset="[1500, 210]"
      width="350"
      height="340"
      title="支路开关分合闸信息"
    >
      <div class="switch-info">
        <div class="name">DK-11</div>
        <div class="state">分闸</div>
        <div class="name">DK-12</div>
        <div class="state">分闸</div>
        <div class="name">DK-13</div>
        <div class="state">分闸</div>
        <div class="name">DK-14</div>
        <div class="state">分闸</div>
        <div class="name">DK-15</div>
        <div class="state">分闸</div>
        <div class="name">DK-16</div>
        <div class="state">分闸</div>
        <div class="name">DK-17</div>
        <div class="state">分闸</div>
        <div class="name">DK-18</div>
        <div class="state">分闸</div>
      </div>
    </svg-panel>
    <svg-text
      :offset="[1725, 180]"
      fontSize="20"
      textAnchor="middle"
      text="KC"
    ></svg-text>
    <svg-line
      :points="[
        [1755, 160],
        [1855, 160],
      ]"
      :color="lineColor"
      :currColor="currColor"
    ></svg-line>
    <svg-triangle :offset="[1855, 160]" :color="lineColor"></svg-triangle>
    <!-- +极线 -->
    <svg-line
      :points="[
        [623, 280],
        [820, 280],
      ]"
      :color="lineColor"
      :currColor="currColor"
    ></svg-line>
    <!-- k1 -->
    <svg-switch
      :offset="[820, 280]"
      :state="switchState.k1"
      :color="lineColor"
    ></svg-switch>
    <svg-text
      :offset="[850, 290]"
      fontSize="20"
      textAnchor="middle"
      text="K1"
    ></svg-text>
    <svg-line
      :points="[
        [780, 280],
        [780, 340],
        [840, 340],
      ]"
      :color="lineColor"
      :currColor="currColor"
    ></svg-line>
    <!-- D1 -->
    <svg-diode :offset="[840, 340]" :color="lineColor"></svg-diode>
    <svg-text
      :offset="[850, 366]"
      fontSize="20"
      textAnchor="middle"
      text="D1"
    ></svg-text>
    <svg-line
      :points="[
        [860, 340],
        [920, 340],
        [920, 280],
      ]"
      :color="lineColor"
      :currColor="currColor"
    ></svg-line>
    <svg-line
      :points="[
        [880, 280],
        [1080, 280],
      ]"
      :color="lineColor"
      :currColor="currColor"
    ></svg-line>
    <svg-batts :offset="[1078, 280]" direct="left"></svg-batts>
    <svg-panel
      :offset="[1090, 330]"
      width="290"
      height="300"
      title="电池组信息"
    >
      <div class="batt-info">
        <div class="group">
          <div class="g-name">蓄电池组1</div>
          <div class="g-content">
            <div class="label">状态</div>
            <div class="value">放电</div>
            <div class="label">组端电压</div>
            <div class="value">47.4</div>
            <div class="label">组端电流</div>
            <div class="value">10.0</div>
          </div>
        </div>
        <div class="group">
          <div class="g-name">蓄电池组2</div>
          <div class="g-content">
            <div class="label">状态</div>
            <div class="value">放电</div>
            <div class="label">组端电压</div>
            <div class="value">47.4</div>
            <div class="label">组端电流</div>
            <div class="value">10.0</div>
          </div>
        </div>
      </div>
    </svg-panel>
    <svg-line
      :points="[
        [1236, 280],
        [1275, 280],
      ]"
      :color="lineColor"
      :currColor="currColor"
    ></svg-line>
    <svg-bg-text :offset="[1275, 280]"></svg-bg-text>
    <svg-line
      :points="[
        [1355, 280],
        [1415, 280],
      ]"
      :color="lineColor"
      :currColor="currColor"
    ></svg-line>
    <svg-line
      :points="[
        [1415, 250],
        [1415, 680],
        [1355, 680],
      ]"
      :color="lineColor"
      :currColor="currColor"
    ></svg-line>
    <!-- k2 -->
    <svg-switch
      :offset="[820, 680]"
      :state="switchState.k2"
      :color="lineColor"
    ></svg-switch>
    <svg-text
      :offset="[850, 690]"
      fontSize="20"
      textAnchor="middle"
      text="K2"
    ></svg-text>
    <svg-line
      :points="[
        [780, 680],
        [780, 740],
        [840, 740],
      ]"
      :color="lineColor"
      :currColor="currColor"
    ></svg-line>
    <!-- D2 -->
    <svg-diode :offset="[840, 740]" :color="lineColor"></svg-diode>
    <svg-text
      :offset="[850, 766]"
      fontSize="20"
      textAnchor="middle"
      text="D2"
    ></svg-text>
    <svg-line
      :points="[
        [860, 740],
        [920, 740],
        [920, 680],
      ]"
      :color="lineColor"
      :currColor="currColor"
    ></svg-line>
    <svg-line
      :points="[
        [880, 680],
        [1080, 680],
      ]"
      :color="lineColor"
      :currColor="currColor"
    ></svg-line>
    <svg-batts :offset="[1078, 680]" direct="left"></svg-batts>
    <svg-line
      :points="[
        [1236, 680],
        [1275, 680],
      ]"
      :color="lineColor"
      :currColor="currColor"
    ></svg-line>
    <svg-bg-text :offset="[1275, 680]" color="#f59a23"></svg-bg-text>
    <svg-line
      :points="[
        [820, 680],
        [715, 680],
        [715, 280],
      ]"
      :color="lineColor"
      :currColor="currColor"
    ></svg-line>
    <!-- kc1支路 -->
    <svg-line
      :points="[
        [715, 480],
        [755, 480],
      ]"
      :color="lineColor"
      :currColor="currColor"
    ></svg-line>
    <svg-switch
      :state="switchState.kc1"
      :offset="[755, 480]"
      :color="lineColor"
    ></svg-switch>
    <svg-text
      :offset="[785, 500]"
      fontSize="20"
      textAnchor="middle"
      text="KC1"
    ></svg-text>
    <svg-line
      :points="[
        [815, 480],
        [855, 480],
      ]"
      :color="lineColor"
      :currColor="currColor"
    ></svg-line>
    <svg-module
      :offset="[855, 395]"
      width="130"
      height="170"
      type="kgg"
    ></svg-module>
    <svg-line
      :points="[
        [985, 480],
        [1035, 480],
      ]"
      :color="lineColor"
      :currColor="currColor"
    ></svg-line>
    <svg-line
      :points="[
        [1035, 280],
        [1035, 360],
      ]"
      :color="lineColor"
      :currColor="currColor"
    ></svg-line>
    <!-- KD1 -->
    <svg-switch
      :state="switchState.kd1"
      isVertical
      :offset="[1035, 360]"
      :color="lineColor"
    ></svg-switch>
    <svg-text
      :offset="[1061, 390]"
      fontSize="20"
      textAnchor="middle"
      text="KD1"
    ></svg-text>
    <svg-line
      :points="[
        [1035, 420],
        [1035, 540],
      ]"
      :color="lineColor"
      :currColor="currColor"
    ></svg-line>
    <!-- KD2 -->
    <svg-switch
      :state="switchState.kd2"
      isVertical
      :offset="[1035, 540]"
      :color="lineColor"
    ></svg-switch>
    <svg-text
      :offset="[1061, 570]"
      fontSize="20"
      textAnchor="middle"
      text="KD2"
    ></svg-text>
    <svg-line
      :points="[
        [1035, 600],
        [1035, 680],
      ]"
      :color="lineColor"
      :currColor="currColor"
    ></svg-line>
    <svg-line
      :points="[
        [1455, 160],
        [1455, 600],
        [1695, 600],
      ]"
      :color="lineColor"
      :currColor="currColor"
    ></svg-line>
    <!-- KD -->
    <svg-switch
      :state="switchState.kd"
      :offset="[1695, 600]"
      :color="lineColor"
    ></svg-switch>
    <svg-text
      :offset="[1725, 616]"
      fontSize="20"
      textAnchor="middle"
      text="KD"
    ></svg-text>
    <svg-line
      :points="[
        [1755, 600],
        [1855, 600],
      ]"
      :color="lineColor"
      :currColor="currColor"
    ></svg-line>
    <svg-triangle :offset="[1855, 600]" :color="lineColor"></svg-triangle>
    <svg-line
      :points="[
        [1415, 160],
        [1415, 190],
      ]"
      :color="lineColor"
      :currColor="currColor"
    ></svg-line>
    <!-- KB -->
    <svg-switch
      :state="switchState.kb"
      isVertical
      :offset="[1415, 190]"
      :color="lineColor"
    ></svg-switch>
    <svg-text
      :offset="[1435, 220]"
      fontSize="20"
      textAnchor="middle"
      text="KB"
    ></svg-text>
  </svg>
</template>
<script>
import card from "./card";
import dotLine from "./dotLine";
import svgModule from "./svgModule";
import svgText from "./svgText";
import svgTextBox from "./svgTextBox";
import svgLine from "./svgLine";
import floor from "./floor";
import svgSwitch3 from "./svgSwitch3";
import svgSwitch from "./svgSwitch";
import svgTriangle from "./svgTriangle.vue";
import svgBgText from "./svgBgText.vue";
import svgDiode from "./svgDiode.vue";
import svgBatts from "./svgBatts.vue";
import svgPanel from "./svgPanel.vue";
import svgInfo from "./svgInfo.vue";
import HdwLight from "@/components/HdwLight";
export default {
  name: "",
  data() {
    return {
      lineColor: "#00f7f9",
      currColor: "#0f0",
      /**
       * L1 交流进线 L2 市电 L3 交流输出1 L4 交流输出2 L5 直流输出1
       * L6 直流输出2 L7 交流负载 L8 直流负载(左) L9 直流负载(右)
       * L10 蓄电池组(上)   L11 核容(上)  L12 蓄电池(左)
       */
      status_L1: 0,
      status_L2: 0,
      status_L3: 0,
      status_L4: 0,
      status_L5: 0,
      status_L6: 0,
      status_L7: 0,
      status_L8: 0,
      status_L9: 0,
      status_L10: 0,
      status_L11: 0,
      status_L12: 0,
      switchState: {
        acin: 0,
        k1: true,
        k2: true,
        kc1: true,
        kd1: true,
        kd2: true,
        kb: true,
        kc: true,
        kd: true,
      },
      list_pdg: [],
      list_gp: [],
      list_hr: [],
      list_batt: [],
      workState: "",
      timeout_pdg: false,
      timeout_hr: false,
      timeout_gp: false,
      timeout_batt: false,
    };
  },
  computed: {},
  components: {
    HdwLight,
    dotLine,
    svgModule,
    svgText,
    svgTextBox,
    svgLine,
    floor,
    svgSwitch3,
    svgSwitch,
    svgTriangle,
    svgBgText,
    svgDiode,
    svgBatts,
    svgPanel,
    svgInfo,
  },
  methods: {
    update(data) {
      // console.log('data', data, '=============');
      let { ac, dc, gp, hr, batt } = data;
      this.list_batt = batt;
      this.list_gp = gp;
      this.list_hr = hr;
      this.list_pdg = [...ac, ...dc];
    },
    // 设置连接状态
    setConnect(obj) {
      let { hr, pdg, gp, batt } = obj;
      this.timeout_hr = hr != 0;
      this.timeout_pdg = pdg != 0;
      this.timeout_gp = gp != 0;
      this.timeout_batt = batt != 0;
    },
    // 设置工作状态
    setWorkstate(type) {
      this.workState =
        [
          "在线浮充",
          "预充电",
          "核容测试",
          "停电放电",
          "内阻测试",
          "K1/D1测试",
          "离线养护测试",
          "未知",
        ][type] || "未知";
    },
    // 设置电流状态
    setCurr(type) {
      switch (type) {
        case "charge":
        case 0:
        case 1:
        case 4:
        case 6:
          this.currColor = "#0f0";
          this.status_L1 = -1;
          this.status_L2 = -1;
          this.status_L3 = 1;
          this.status_L4 = 1;
          this.status_L5 = 1;
          this.status_L6 = 1;
          this.status_L7 = 1;
          this.status_L8 = 1;
          this.status_L9 = -1;
          this.status_L10 = 1;
          this.status_L11 = -1;
          this.status_L12 = -1;
          break;
        case "disCharge":
        case 2:
          this.currColor = "#ff0";
          this.status_L1 = -1;
          this.status_L2 = -1;
          this.status_L3 = 1;
          this.status_L4 = 1;
          this.status_L5 = 1;
          this.status_L6 = 1;
          this.status_L7 = 1;
          this.status_L8 = 1;
          this.status_L9 = -1;
          this.status_L10 = -1;
          this.status_L11 = 1;
          this.status_L12 = 1;
          break;
        case "powerOff":
        case 3:
          this.currColor = "#ff6c37";
          this.status_L1 = 0;
          this.status_L2 = 0;
          this.status_L3 = 0;
          this.status_L4 = 0;
          this.status_L5 = 1;
          this.status_L6 = 1;
          this.status_L7 = 0;
          this.status_L8 = 1;
          this.status_L9 = -1;
          this.status_L10 = -1;
          this.status_L11 = 1;
          this.status_L12 = 1;
          break;
        default:
          this.status_L1 = 0;
          this.status_L2 = 0;
          this.status_L3 = 0;
          this.status_L4 = 0;
          this.status_L5 = 0;
          this.status_L6 = 0;
          this.status_L7 = 0;
          this.status_L8 = 0;
          this.status_L9 = 0;
          this.status_L10 = 0;
          this.status_L11 = 0;
          this.status_L12 = 0;
          break;
      }
    },
  },
  mounted() {},
};
</script>
<style scoped lang="less">
.label {
  padding-right: 0.4em;
  &::after {
    content: ":";
  }
}
.power-info,
.acin-info,
.batt-info {
  box-sizing: border-box;
  height: 100%;
  padding: 10px;
  display: flex;
  flex-direction: column;
}
.group {
  flex: 1;
  display: flex;
  flex-direction: column;
  .g-name {
    color: #ffea70;
    font-size: 18px;
    font-weight: bold;
  }
  .g-content {
    padding-left: 2em;
    flex: 1;
    display: grid;
    gap: 2px;
    grid-template-columns: 1fr 1.3fr;
    grid-template-rows: repeat(3, 30px);
    justify-content: center;
    align-content: center;
    // align-items: center;
    .value {
      background: #000;
      line-height: 30px;
      padding-left: 0.6em;
      color: #ffea70;
      border-radius: 4px;
      // height: 30px;
    }
  }
}
.acin-info {
  .group {
    .g-content {
      grid-template-columns: 1.3fr 1fr;
      grid-template-rows: repeat(6, 28px);
    }
  }
}
.power-info {
  .group {
    .g-content {
      align-content: start;
      grid-template-columns: 1.3fr 1fr;
      grid-template-rows: repeat(auto-fill, 28px);
    }
  }
}
.switch-info {
  padding: 10px 30px;
  height: 100%;
  display: grid;
  gap: 2px;
  grid-template-columns: 1fr 1.3fr;
  grid-template-rows: repeat(auto-fill, 30px);
  place-items: center end;
  gap: 4px 1em;
  .name {
    &::after {
      content: ":";
    }
  }
  .state {
    place-self: stretch;
    line-height: 30px;
    padding-left: 0.6em;
    color: #ffea70;
    border-radius: 4px;
    background: #000;
  }
}
/deep/ .g-rect-fill {
  fill: none;
  // stroke-width: 5;
  stroke-linejoin: round;
  stroke-linecap: round;
  stroke-dashoffset: -100;
  // stroke-dasharray: 3, 900;
}
/deep/ .move {
  stroke-width: 7;
  // stroke-dasharray: 43, 87;
  stroke-dasharray: 23, 107;
  animation: lineMove 1.8s cubic-bezier(0.05, 0.1, 0.8, 1) infinite;
}
/deep/ .move1 {
  stroke-width: 5;
  stroke-dasharray: 23, 107;
  animation: lineMove 1.8s cubic-bezier(0, 0, 1, 1) infinite;
}
/deep/ .move-dis {
  stroke-width: 7;
  stroke-dasharray: 23, 107;
  animation: lineMoveDis 1.8s cubic-bezier(0.05, 0.1, 0.8, 1) infinite;
}
/deep/ .move-dis1 {
  stroke-width: 5;
  stroke-dasharray: 23, 107;
  animation: lineMoveDis 1.8s cubic-bezier(0, 0, 1, 1) infinite;
}
@keyframes lineMove {
  0% {
    // stroke-dashoffset: -850;
    stroke-dashoffset: -260;
  }
  100% {
    stroke-dashoffset: 0;
  }
}
@keyframes lineMoveDis {
  0% {
    // stroke-dashoffset: -850;
    stroke-dashoffset: 260;
  }
  100% {
    stroke-dashoffset: 0;
  }
}
</style>
src/views/home/components/svg/svgInfo.vue
New file
@@ -0,0 +1,61 @@
<template>
  <foreignObject
    :transform="'translate(' + offset.join(',') + ')'"
    :width="width"
    :height="height"
  >
    <!-- foreignObject元素用于包裹非SVG元素 -->
    <div class="bg">
        <slot></slot>
    </div>
    <!-- 这里放入了HTML标签 -->
  </foreignObject>
</template>
<script>
export default {
  name: "",
  props: {
    offset: {
      type: Array,
      default() {
        return [0, 0];
      },
    },
    width: {
      type: [Number, String],
      default: 140,
    },
    height: {
      type: [Number, String],
      default: 38,
    },
    type: {
      type: String,
      default: "",
    },
  },
  data() {
    return {
    };
  },
  computed: {},
  methods: {},
  mounted() {},
};
</script>
<style scoped>
.bg {
  height: 100%;
  box-sizing: border-box;
  border: 1px #fff solid;
  border-radius: 6px;
  background: #017988;
  overflow: hidden;
  display: flex;
  justify-content: center;
  align-items: center;
}
</style>
src/views/home/components/svg/svgPanel.vue
New file
@@ -0,0 +1,92 @@
<template>
  <foreignObject
    :transform="'translate(' + offset.join(',') + ')'"
    :width="width"
    :height="height"
  >
    <!-- foreignObject元素用于包裹非SVG元素 -->
    <div class="bg">
      <div class="border">
        <div class="title" v-if="title">
          {{ title }}
        </div>
        <div class="content">
          <slot></slot>
        </div>
      </div>
    </div>
    <!-- 这里放入了HTML标签 -->
  </foreignObject>
</template>
<script>
export default {
  name: "",
  props: {
    offset: {
      type: Array,
      default() {
        return [0, 0];
      },
    },
    width: {
      type: [Number, String],
      default: 450,
    },
    height: {
      type: [Number, String],
      default: 306,
    },
    title: {
      type: String,
      default: "",
    },
    type: {
      type: String,
      default: "",
    },
  },
  data() {
    return {
    };
  },
  computed: {},
  methods: {
  },
  mounted() {
  },
};
</script>
<style scoped>
.bg {
  height: 100%;
  box-sizing: border-box;
}
.border {
  background: #017988;
  /* border: 1px #0ff solid; */
  border-radius: 6px;
  height: 100%;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
.title {
  background: #0ff;
  color: #000;
  font-size: 18px;
  font-weight: bold;
  height: 32px;
  line-height: 32px;
  text-align: center;
  position: relative;
}
.content {
  flex: 1;
  position: relative;
}
</style>
src/views/home/components/svg/svgSwitch.vue
New file
@@ -0,0 +1,119 @@
<template>
  <g ref="g" :transform="'translate(' + offset.join(',') + ')'">
    <circle :r="r" style="fill: #fff; stroke: none"></circle>
    <circle :r="r" :cx="cx" :cy="cy" style="fill: #fff; stroke: none"></circle>
    <line :x2="cx" :y2="cy" :stroke-width="lineWidth" :stroke="color">
      <animateTransform
        ref="anim"
        attributeName="transform"
        attributeType="XML"
        type="rotate"
        :from="[fromDeg, isVertical ? cx : 0, isVertical ? cy : 0].join(',')"
        :to="[toDeg, isVertical ? cx : 0, isVertical ? cy : 0].join(',')"
        dur="0.3s"
        repeatCount="1"
        fill="freeze"
      />
    </line>
  </g>
</template>
<script>
export default {
  name: "",
  props: {
    r: {
      type: Number,
      default: 3,
    },
    len: {
      type: Number,
      default: 60,
    },
    offset: {
      type: Array,
      default() {
        return [0, 0];
      },
    },
    isVertical: {
      type: Boolean,
      default: false,
    },
    state: {
      type: Boolean,
      defalut: false,
    },
    points: {
      type: Array,
      default() {
        return [
          [0, 0],
          [10, 10],
        ];
      },
    },
    color: {
      type: String,
      default: "#f59a23",
    },
    currColor: {
      type: String,
      default: "#0f0",
    },
    lineWidth: {
      type: [Number, String],
      default: 2,
    },
  },
  computed: {
    cx() {
      let { isVertical, len } = this;
      return isVertical ? 0 : len;
    },
    cy() {
      let { isVertical, len } = this;
      return isVertical ? len : 0;
    },
    pointsStr() {
      return this.points.join(" ");
    },
  },
  data() {
    return {
      fromDeg: -2,
      toDeg: -38,
    };
  },
  watch: {
    state: {
      handler(n) {
        this.$nextTick(() => {
          this.changeSwitch();
        });
      },
      immediate: true,
    },
  },
  components: {},
  methods: {
    changeSwitch() {
      if (this.state) {
        this.fromDeg = -38;
        this.toDeg = -2;
      } else {
        this.fromDeg = -2;
        this.toDeg = -38;
      }
      // 重新开启动画
      this.$refs.anim?.beginElement();
    },
  },
  mounted() {
  },
};
</script>
<style scoped lang="less">
</style>
src/views/home/components/svg/svgSwitch3.vue
New file
@@ -0,0 +1,121 @@
<template>
  <g ref="g" :transform="'translate(' + offset.join(',') + ')'">
    <circle :r="r" :fill="ballColor" stroke="none"></circle>
    <circle :r="r" :cy="h" :fill="ballColor" stroke="none"></circle>
    <circle :r="r" :cx="cx" :cy="cy" :fill="ballColor" stroke="none"></circle>
    <line :x2="cx" :y2="cy" :stroke-width="lineWidth" :stroke="color">
      <animateTransform
        ref="anim"
        attributeName="transform"
        attributeType="XML"
        type="rotate"
        :from="[fromDeg, cx, cy].join(',')"
        :to="[toDeg, cx, cy].join(',')"
        dur="0.3s"
        repeatCount="1"
        fill="freeze"
      />
    </line>
  </g>
</template>
<script>
export default {
  name: "",
  props: {
    r: {
      type: Number,
      default: 5,
    },
    h: {
      type: Number,
      default: 80,
    },
    offset: {
      type: Array,
      default() {
        return [0, 0];
      },
    },
    points: {
      type: Array,
      default() {
        return [
          [0, 0],
          [10, 10],
        ];
      },
    },
    color: {
      type: String,
      default: "#f59a23",
    },
    ballColor: {
      type: String,
      default: "#fff",
    },
    // 0 表示ac-1  1表示 ac-2
    state: {
      type: Number,
      default: 0,
    },
    currColor: {
      type: String,
      default: "#0f0",
    },
    lineWidth: {
      type: [Number, String],
      default: 2,
    },
  },
  computed: {
    cx() {
      const { h } = this;
      return Math.cos((30 * Math.PI) / 180) * h;
    },
    cy() {
      const { h } = this;
      return h / 2;
    },
    pointsStr() {
      return this.points.join(" ");
    },
  },
  data() {
    return {
      fromDeg: -2,
      toDeg: -58,
    };
  },
  watch: {
    state: {
      handler(n) {
        this.$nextTick(() => {
          this.changeSwitch();
        });
      },
      immediate: true,
    },
  },
  components: {},
  methods: {
    changeSwitch() {
      if (0 == this.state) {
        this.fromDeg = -58;
        this.toDeg = -2;
      } else {
        this.fromDeg = -2;
        this.toDeg = -58;
      }
      // 重新开启动画
      this.$refs.anim?.beginElement();
    },
  },
  mounted() {
  },
};
</script>
<style scoped lang="less">
</style>
src/views/home/components/svg/svgTriangle.vue
New file
@@ -0,0 +1,112 @@
<template>
  <polygon
    :points="points"
    :stroke="color"
    :stroke-width="lineWidth"
    style="fill: none"
    :transform="'translate(' + offset.join(',') + ')'"
  />
</template>
<script>
export default {
  name: "",
  props: {
    len: {
      type: Number,
      default: 20,
    },
    offset: {
      type: Array,
      default() {
        return [0, 0];
      },
    },
    color: {
      type: String,
      default: "#f59a23",
    },
    lineWidth: {
      type: [Number, String],
      default: 2,
    },
  },
  computed: {
    points() {
      let len = this.len;
      let len2 = len / 2;
      return [
        [0, len2],
        [Math.cos((30 * Math.PI) / 180) * len, 0],
        [0, -len2],
      ].join(',');
    },
  },
  data() {
    return {
    };
  },
  watch: {
  },
  components: {},
  methods: {
  },
  mounted() {
  },
};
</script>
<style scoped lang="less">
// .g-rect-fill {
//   fill: none;
//   // stroke-width: 5;
//   stroke-linejoin: round;
//   stroke-linecap: round;
//   stroke-dashoffset: -100;
//   // stroke-dasharray: 3, 900;
// }
// .move {
//   stroke-width: 7;
//   // stroke-dasharray: 43, 87;
//   stroke-dasharray: 23, 107;
//   animation: lineMove 1.8s cubic-bezier(0.05, 0.1, 0.8, 1) infinite;
// }
// .move1 {
//   stroke-width: 5;
//   stroke-dasharray: 23, 107;
//   animation: lineMove 1.8s cubic-bezier(0, 0, 1, 1) infinite;
// }
// .move-dis {
//   stroke-width: 7;
//   stroke-dasharray: 23, 107;
//   animation: lineMoveDis 1.8s cubic-bezier(0.05, 0.1, 0.8, 1) infinite;
// }
// .move-dis1 {
//   stroke-width: 5;
//   stroke-dasharray: 23, 107;
//   animation: lineMoveDis 1.8s cubic-bezier(0, 0, 1, 1) infinite;
//   // &.line1 {
//   //   animation: lineMoveDis1 1.8s cubic-bezier(0, 0, 1, 1) infinite;
//   // }
// }
// @keyframes lineMove {
//   0% {
//     // stroke-dashoffset: -850;
//     stroke-dashoffset: -260;
//   }
//   100% {
//     stroke-dashoffset: 0;
//   }
// }
// @keyframes lineMoveDis {
//   0% {
//     // stroke-dashoffset: -850;
//     stroke-dashoffset: 260;
//   }
//   100% {
//     stroke-dashoffset: 0;
//   }
// }
</style>
src/views/test.vue
New file
@@ -0,0 +1,33 @@
<template>
  <div class="">
    <svg-dyhr style="background: gray;"></svg-dyhr>
  </div>
</template>
<script>
import SvgDyhr from '@/views/home/components/svg/svgDyhr.vue';
export default {
  name: '',
  data () {
    return {
    }
  },
  components: {
    SvgDyhr
  },
  methods: {
  },
  mounted () {
  }
}
</script>
<style scoped>
</style>