he wei
2024-01-05 a9c9544d4c9010077b177f4caf866c8479653d61
UA 断路器做跳闸的处理
6个文件已修改
2个文件已添加
726 ■■■■■ 已修改文件
src/components/FooterScroll.vue 394 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/layout/components/Navbar.vue 20 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/home/components/marqueeLeft.vue 137 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/home/components/protectorBox.vue 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/home/components/textBox.vue 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/home/index.vue 134 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/realTime/index.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/switchControl/index.vue 27 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/FooterScroll.vue
New file
@@ -0,0 +1,394 @@
<template>
    <div ref="wrap">
        <div :style="leftSwitch" v-if="navigation" :class="leftSwitchClass" @click="leftSwitchClick">
            <slot name="left-switch"></slot>
        </div>
        <div :style="rightSwitch" v-if="navigation" :class="rightSwitchClass" @click="rightSwitchClick">
            <slot name="right-switch"></slot>
        </div>
        <div ref="realBox" :style="pos" @mouseenter="enter" @mouseleave="leave" @touchstart="touchStart" @touchmove="touchMove" @touchend="touchEnd">
            <div ref="slotList" :style="float">
                <slot></slot>
            </div>
            <div :style="float">
        <slot></slot>
                <!-- <slot name="copy"></slot> -->
            </div>
        </div>
    </div>
</template>
<script>
// require('comutils/animationFrame')()
// const arrayEqual = require('comutils/arrayEqual')
// const copyObj = require('comutils/copyObj')
export default {
    name: 'FooterScroll',
    data() {
        return {
            xPos: 0,
            yPos: 0,
            delay: 0,
            copyHtml: '',
            height: 0,
            width: 0, // 外容器宽度
            realBoxWidth: 0, // 内容实际宽度
        }
    },
    props: {
        data: {
            type: Array,
            default: () => {
                return []
            }
        },
        classOption: {
            type: Object,
            default: () => {
                return {}
            }
        }
    },
    computed: {
        leftSwitchState() {
            return this.xPos < 0
        },
        rightSwitchState() {
            return Math.abs(this.xPos) < (this.realBoxWidth - this.width)
        },
        leftSwitchClass() {
            return this.leftSwitchState ? '' : this.options.switchDisabledClass
        },
        rightSwitchClass() {
            return this.rightSwitchState ? '' : this.options.switchDisabledClass
        },
        leftSwitch() {
            return {
                position: 'absolute',
                margin: `${this.height / 2}px 0 0 -${this.options.switchOffset}px`,
                transform: 'translate(-100%,-50%)'
            }
        },
        rightSwitch() {
            return {
                position: 'absolute',
                margin: `${this.height / 2}px 0 0 ${this.width + this.options.switchOffset}px`,
                transform: 'translateY(-50%)'
            }
        },
        float() {
            return this.isHorizontal ? { float: 'left', overflow: 'hidden' } : { overflow: 'hidden' }
        },
        pos() {
            return {
                transform: `translate(${this.xPos}px,${this.yPos}px)`,
                transition: `all ${this.ease} ${this.delay}ms`,
                overflow: 'hidden'
            }
        },
        defaultOption() {
            return {
                step: 1, //步长
                limitMoveNum: 5, //启动无缝滚动最小数据数
                hoverStop: true, //是否启用鼠标hover控制
                direction: 1, // 0 往下 1 往上 2向左 3向右
                openTouch: true, //开启移动端touch
                singleHeight: 0, //单条数据高度有值hoverStop关闭
                singleWidth: 0, //单条数据宽度有值hoverStop关闭
                waitTime: 1000, //单步停止等待时间
                switchOffset: 30,
                autoPlay: true,
                navigation: false,
                switchSingleStep: 134,
                switchDelay: 400,
                switchDisabledClass: 'disabled',
                isSingleRemUnit: false // singleWidth/singleHeight 是否开启rem度量
            }
        },
        options() {
            return Object.assign({}, this.defaultOption, this.classOption)
        },
        navigation() {
            return this.options.navigation
        },
        autoPlay() {
            if (this.navigation) return false
            return this.options.autoPlay
        },
        scrollSwitch() {
            return this.data.length >= this.options.limitMoveNum
        },
        hoverStopSwitch() {
            return this.options.hoverStop && this.autoPlay && this.scrollSwitch
        },
        canTouchScroll() {
            return this.options.openTouch
        },
        isHorizontal() {
            return this.options.direction > 1
        },
        baseFontSize() {
            return this.options.isSingleRemUnit ? parseInt(window.getComputedStyle(document.documentElement, null).fontSize) : 1
        },
        realSingleStopWidth() {
            return this.options.singleWidth * this.baseFontSize
        },
        realSingleStopHeight() {
            return this.options.singleHeight * this.baseFontSize
        },
        step() {
            let singleStep
            let step = this.options.step
            if (this.isHorizontal) {
                singleStep = this.realSingleStopWidth
            } else {
                singleStep = this.realSingleStopHeight
            }
            if (singleStep > 0 && singleStep % step > 0) {
                console.error('如果设置了单步滚动,step需是单步大小的约数,否则无法保证单步滚动结束的位置是否准确。~~~~~')
            }
            return step
        }
    },
    methods: {
        reset() {
            this._cancle()
            this._initMove()
        },
        leftSwitchClick() {
            if (!this.leftSwitchState) return
            // 小于单步距离
            if (Math.abs(this.xPos) < this.options.switchSingleStep) {
                this.xPos = 0
                return
            }
            this.xPos += this.options.switchSingleStep
        },
        rightSwitchClick() {
            if (!this.rightSwitchState) return
            // 小于单步距离
            if ((this.realBoxWidth - this.width + this.xPos) < this.options.switchSingleStep) {
                this.xPos = this.width - this.realBoxWidth
                return
            }
            this.xPos -= this.options.switchSingleStep
        },
        _cancle() {
            cancelAnimationFrame(this.reqFrame || '')
        },
        touchStart(e) {
            if (!this.canTouchScroll) return
            let timer
            const touch = e.targetTouches[0] //touches数组对象获得屏幕上所有的touch,取第一个touch
            const { waitTime, singleHeight, singleWidth } = this.options
            this.startPos = {
                x: touch.pageX,
                y: touch.pageY
            } //取第一个touch的坐标值
            this.startPosY = this.yPos //记录touchStart时候的posY
            this.startPosX = this.xPos //记录touchStart时候的posX
            if (!!singleHeight && !!singleWidth) {
                if (timer) clearTimeout(timer)
                timer = setTimeout(() => {
                    this._cancle()
                }, waitTime + 20)
            } else {
                this._cancle()
            }
        },
        touchMove(e) {
            //当屏幕有多个touch或者页面被缩放过,就不执行move操作
            if (!this.canTouchScroll || e.targetTouches.length > 1 || e.scale && e.scale !== 1) return
            const touch = e.targetTouches[0]
            const { direction } = this.options
            this.endPos = {
                x: touch.pageX - this.startPos.x,
                y: touch.pageY - this.startPos.y
            }
            event.preventDefault(); //阻止触摸事件的默认行为,即阻止滚屏
            const dir = Math.abs(this.endPos.x) < Math.abs(this.endPos.y) ? 1 : 0 //dir,1表示纵向滑动,0为横向滑动
            if (dir === 1 && direction < 2) {  // 表示纵向滑动 && 运动方向为上下
                this.yPos = this.startPosY + this.endPos.y
            } else if (dir === 0 && direction > 1) { // 为横向滑动 && 运动方向为左右
                this.xPos = this.startPosX + this.endPos.x
            }
        },
        touchEnd() {
            if (!this.canTouchScroll) return
            let timer
            const direction = this.options.direction
            this.delay = 50
            if (direction === 1) {
                if (this.yPos > 0) this.yPos = 0
            } else if (direction === 0) {
                let h = this.realBoxHeight / 2 * -1
                if (this.yPos < h) this.yPos = h
            } else if (direction === 2) {
                if (this.xPos > 0) this.xPos = 0
            } else if (direction === 3) {
                let w = this.realBoxWidth * -1
                if (this.xPos < w) this.xPos = w
            }
            if (timer) clearTimeout(timer)
            timer = setTimeout(() => {
                this.delay = 0
                this._move()
            }, this.delay)
        },
        enter() {
            if (this.hoverStopSwitch) this._stopMove()
        },
        leave() {
            if (this.hoverStopSwitch) this._startMove()
        },
        _move() {
            // 鼠标移入时拦截_move()
            if (this.isHover) return
            this._cancle() //进入move立即先清除动画 防止频繁touchMove导致多动画同时进行
            this.reqFrame = requestAnimationFrame(
                function () {
                    const h = this.realBoxHeight / 2  //实际高度
                    const w = this.realBoxWidth / 2 //宽度
                    let { direction, waitTime } = this.options
                    let { step } = this
                    if (direction === 1) { // 上
                        if (Math.abs(this.yPos) >= h) {
                            this.$emit('ScrollEnd')
                            this.yPos = 0
                        }
                        this.yPos -= step
                    } else if (direction === 0) { // 下
                        if (this.yPos >= 0) {
                            this.$emit('ScrollEnd')
                            this.yPos = h * -1
                        }
                        this.yPos += step
                    } else if (direction === 2) { // 左
                        if (Math.abs(this.xPos) >= w) {
                            this.$emit('ScrollEnd')
                            this.xPos = 0
                        }
                        this.xPos -= step
                    } else if (direction === 3) { // 右
                        if (this.xPos >= 0) {
                            this.$emit('ScrollEnd')
                            this.xPos = w * -1
                        }
                        this.xPos += step
                    }
                    if (this.singleWaitTime) clearTimeout(this.singleWaitTime)
                    if (!!this.realSingleStopHeight) { //是否启动了单行暂停配置
                        if (Math.abs(this.yPos) % this.realSingleStopHeight < step) { // 符合条件暂停waitTime
                            this.singleWaitTime = setTimeout(() => {
                                this._move()
                            }, waitTime)
                        } else {
                            this._move()
                        }
                    } else if (!!this.realSingleStopWidth) {
                        if (Math.abs(this.xPos) % this.realSingleStopWidth < step) { // 符合条件暂停waitTime
                            this.singleWaitTime = setTimeout(() => {
                                this._move()
                            }, waitTime)
                        } else {
                            this._move()
                        }
                    } else {
                        this._move()
                    }
                }.bind(this)
            )
        },
        _initMove() {
            this.$nextTick(() => {
                const { switchDelay } = this.options
                const { autoPlay, isHorizontal } = this
                this._dataWarm(this.data)
                this.copyHtml = '' //清空copy
                if (isHorizontal) {
                    this.height = this.$refs.wrap.offsetHeight
                    this.width = this.$refs.wrap.offsetWidth
                    let slotListWidth = this.$refs.slotList.offsetWidth
                    // 水平滚动设置warp width
                    if (autoPlay) {
                        // 修正offsetWidth四舍五入
                        slotListWidth = slotListWidth * 2 + 1
                    }
                    this.$refs.realBox.style.width = slotListWidth + 'px'
                    this.realBoxWidth = slotListWidth
                }
                if (autoPlay) {
                    this.ease = 'ease-in'
                    this.delay = 0
                } else {
                    this.ease = 'linear'
                    this.delay = switchDelay
                    return
                }
                // 是否可以滚动判断
                if (this.scrollSwitch) {
                    let timer
                    if (timer) clearTimeout(timer)
                    this.copyHtml = this.$refs.slotList.innerHTML
                    setTimeout(() => {
                        this.realBoxHeight = this.$refs.realBox.offsetHeight
                        this._move()
                    }, 0);
                } else {
                    this._cancle()
                    this.yPos = this.xPos = 0
                }
            })
        },
        _dataWarm(data) {
            if (data.length > 100) {
                console.warn(`数据达到了${data.length}条有点多哦~,可能会造成部分老旧浏览器卡顿。`);
            }
        },
        _startMove() {
            this.isHover = false //开启_move
            this._move()
        },
        _stopMove() {
            this.isHover = true //关闭_move
            // 防止频频hover进出单步滚动,导致定时器乱掉
            if (this.singleWaitTime) clearTimeout(this.singleWaitTime)
            this._cancle()
        },
    arrayEqual() {
    },
    },
    mounted() {
        this._initMove()
    },
    watch: {
        data(newData, oldData) {
            this._dataWarm(newData)
            //监听data是否有变更
            // if (!this.arrayEqual(newData, oldData)) {
      // }
      this.reset()
        },
        autoPlay(bol) {
            if (bol) {
                this.reset()
            } else {
                this._stopMove()
            }
        }
    },
    beforeCreate() {
        this.reqFrame = null // move动画的animationFrame定时器
        this.singleWaitTime = null // single 单步滚动的定时器
        this.isHover = false // mouseenter mouseleave 控制this._move()的开关
        this.ease = 'ease-in'
    },
    beforeDestroy() {
        this._cancle()
        clearTimeout(this.singleWaitTime)
    }
}
</script>
src/layout/components/Navbar.vue
@@ -24,8 +24,14 @@
          跳闸开关
          <div class="num">12</div>
        </div> -->
        <div class="state">{{ isTimeout ? "离线" : "在线" }}</div>
        <div :class="['i', { danger: isTimeout }]"></div>
        <div class="box">
          跳闸开关
          <div class="num">{{ breakSwitch }}</div>
        </div>
        <div class="connect-state">
          <div class="state">{{ isTimeout ? "离线" : "在线" }}</div>
          <div :class="['i', { danger: isTimeout }]"></div>
        </div>
      </div>
    </div>
    <div class="right-menu">
@@ -90,6 +96,7 @@
  },
  data() {
    return {
      breakSwitch: 0,
      onSwitch: 0,
      offSwitch: 0,
      recordTime: -200 * 1000,
@@ -100,9 +107,10 @@
  methods: {
    onWSMessage1(res) {
      let {
        data: { onSwitch, offSwitch, recordTime, nowTime },
        data: { onSwitch, offSwitch, recordTime, nowTime, breakSwitch },
      } = JSON.parse(res.data);
      // console.log(data, "=====data??", data2);
      this.breakSwitch = breakSwitch;
      this.onSwitch = onSwitch;
      this.offSwitch = offSwitch;
      this.recordTime = recordTime;
@@ -183,6 +191,12 @@
        margin-left: 10px;
      }
    }
    .connect-state {
      height: 40px;
      display: flex;
      margin-left: 10px;
      align-items: center;
    }
  }
  .hamburger-container {
    line-height: 46px;
src/views/home/components/marqueeLeft.vue
New file
@@ -0,0 +1,137 @@
<template>
  <footer-scroll
    :data="datas"
    :class-option="classOption"
    ref="root"
    class="breaker-alarms"
  >
    <div class="list">
      <div
        class="item"
        v-for="(item, idx) in datas"
        ref="item"
        :key="'list_' + idx"
      >
        <div v-if="!item.isEmpty">{{ item.content }}</div>
        <div v-else :style="{ width: item.width + 'px' }"></div>
      </div>
    </div>
  </footer-scroll>
</template>
<script>
import FooterScroll from "@/components/FooterScroll";
export default {
  name: "",
  props: {
    list: {
      type: Array,
      default() {
        return [];
      },
    },
  },
  data() {
    return {
      datas: [],
      disArr: [],
      distanceWid: null,
      classOption: {
        limitMoveNum: 0,
        direction: 2,
        step: 1,
      },
    };
  },
  watch: {
    list: {
      handler(val) {
        this.$nextTick(() => {
          this.datas = JSON.parse(JSON.stringify(val));
          var item = this.$refs.item;
          var arr = [];
          // 因为设置的margin值一样,所以取第一个就行。
          var margin = 0;
          if (item && item.length > 0) {
            margin = this.getMargin(item[0]);
          }
          if (this.datas.length > 0) {
            this.datas = this.datas.map((jtem, i) => {
              let obj = {};
              if (jtem) {
                obj.isEmpty = false;
                obj.content = jtem + "跳闸";
              }
              if (item && item.length > 0) {
                arr.push((item[i]?.clientWidth || 0) + margin); // 把宽度和 margin 加起来就是每一个元素需要移动的距离
              }
              return obj;
            });
          }
          this.disArr = arr;
          let allWidth = 0;
          if (this.disArr.length > 0) {
            this.disArr.map((item, i) => {
              if (i > 0) {
                allWidth += item;
              }
            });
          }
          // console.log(allWidth, this.datas, "2443");
          let rootW = this.$refs.root.$el.clientWidth;
          if (allWidth < rootW) {
            this.distanceWid = rootW - allWidth;
            // 如果长度不够就补充一个空li撑满整屏
            this.datas.push({
              isEmpty: true,
              width: this.distanceWid,
            });
          }
          // console.log(this.datas, "345");
          // listData length无变化,仅仅是属性变更,手动调用下组件内部的reset方法
          this.$refs.root.reset();
        });
      },
      immediate: true,
    },
  },
  components: {
    FooterScroll,
  },
  methods: {
    // 获取margin属性
    getMargin(obj) {
      var marg = window.getComputedStyle(obj, null)["margin-right"];
      marg = marg.replace("px", "");
      return Number(marg); // 强制转化成数字
    },
  },
  mounted() {},
};
</script>
<style scoped>
.breaker-alarms {
  /*color: #D7BC8D;*/
  overflow: hidden;
  color: #000;
  height: 100%;
  /*background: #422b02;*/
}
.list {
  white-space: nowrap;
  display: flex;
  align-items: center;
}
.item {
  margin-right: 25px;
  display: inline-block;
  font-size: 0.6rem;
  cursor: pointer;
  position: relative;
}
</style>
src/views/home/components/protectorBox.vue
@@ -15,7 +15,7 @@
    <path
      :d="createRoundRectPath(92, 80, 10)"
      stroke="none"
      fill="url(#color)"
      :fill="alarm ? '#FF3801' : 'url(#color)'"
    />
    <!-- 绘制标题 -->
@@ -40,6 +40,10 @@
        return [0, 0];
      },
    },
    alarm: {
      type: Boolean,
      default: false,
    },
  },
  computed: {},
  data() {
src/views/home/components/textBox.vue
@@ -4,7 +4,7 @@
    <path
      :d="createRoundRectPath(84, 30, 6)"
      stroke="none"
      fill="#F69F40"
      :fill="alarm ? '#FF3801' : '#F69F40'"
    />
    <!-- 绘制标题 -->
@@ -24,6 +24,10 @@
        return [0, 0];
      },
    },
    alarm: {
      type: Boolean,
      default: false,
    },
  },
  computed: {},
  data() {
src/views/home/index.vue
@@ -6,6 +6,7 @@
import ProtectorBox from "./components/protectorBox";
import TextBox from "./components/textBox";
import SvgLine from "./components/svgLine";
import marqueeLeft from "./components/marqueeLeft.vue";
import getBinaryDigits from "@/assets/js/getBinaryDigits";
import FileProcess from "./fileProcess";
@@ -34,6 +35,7 @@
    TextBox,
    SvgLine,
    ListCard,
    marqueeLeft,
  },
  data() {
    const baseURL = getWebUrl();
@@ -61,6 +63,8 @@
        dcin2_switch_trip: [],
        dc1_switch1_trip: [],
        dc2_switch1_trip: [],
        breaker_state1: [],
        breaker_state2: [],
      },
    };
  },
@@ -98,12 +102,17 @@
        dcIn2SwitchTripReal,
        dc1Switch1TripReal,
        dc2Switch1TripReal,
        breakerState1,
        breakerState2,
      } = data2;
      let ac1_outswitch1_trip = getBinaryDigits(ac1OutSwitch1TripReal);
      let ac2_outswitch1_trip = getBinaryDigits(ac2OutSwitch1TripReal);
      let dc1_switch1_trip = getBinaryDigits(dc1Switch1TripReal);
      let dc2_switch1_trip = getBinaryDigits(dc2Switch1TripReal);
      let breaker_state1 = getBinaryDigits(breakerState1);
      let breaker_state2 = getBinaryDigits(breakerState2);
      let acin1_switch_trip = [acIn1SwitchTripReal];
      let acin2_switch_trip = [acIn2SwitchTripReal];
      let dcin1_switch_trip = [dcIn1SwitchTripReal];
@@ -118,6 +127,8 @@
        dcin2_switch_trip,
        dc1_switch1_trip,
        dc2_switch1_trip,
        breaker_state1,
        breaker_state2,
      };
      // this.UPDATE_HOMEDATA(this.rtData);
    },
@@ -143,6 +154,14 @@
          console.log(err);
        });
    },
    getAlarm(name) {
      const breaker =
        this.breakerList.filter((v) => v.breakerName == name)[0] || {};
      if (!breaker.nodeName) {
        return false;
      }
      return !!this.switchStates[breaker.nodeName][breaker.nodeBit];
    },
  },
  computed: {
    ...mapState({
@@ -150,10 +169,44 @@
    }),
    switchState() {
      let v = this.curSwitch;
      if (!v['nodeName']) {
        return '未知';
      if (!v["switchNodeName"]) {
        return "未知";
      }
      return this.switchStates[v.nodeName][v.nodeBit] ? "合闸" : "分闸";
      return this.switchStates[v.switchNodeName][v.switchNodeBit]
        ? "分闸"
        : "合闸";
    },
    alarm_ac1() {
      let breakerList = this.breakerList.filter(
        (v) =>
          v.breakerAddr == "交流进线1" &&
          this.switchStates[v.nodeName][v.nodeBit]
      );
      return breakerList.map((v) => v.breakerType + v.breakerName);
    },
    alarm_ac2() {
      let breakerList = this.breakerList.filter(
        (v) =>
          v.breakerAddr == "交流进线2" &&
          this.switchStates[v.nodeName][v.nodeBit]
      );
      return breakerList.map((v) => v.breakerType + v.breakerName);
    },
    alarm_dc1() {
      let breakerList = this.breakerList.filter(
        (v) =>
          v.breakerAddr == "直流进线1" &&
          this.switchStates[v.nodeName][v.nodeBit]
      );
      return breakerList.map((v) => v.breakerType + v.breakerName);
    },
    alarm_dc2() {
      let breakerList = this.breakerList.filter(
        (v) =>
          v.breakerAddr == "直流进线2" &&
          this.switchStates[v.nodeName][v.nodeBit]
      );
      return breakerList.map((v) => v.breakerType + v.breakerName);
    },
  },
  mounted() {
@@ -258,45 +311,57 @@
              <div class="svg-contain">
                <div class="pos-full">
                  <svg width="100%" height="100%" viewBox="0 0 500 340">
                    <text-box :offset="[220, 10]" @click="(el) => showState(el, 'JK11')"></text-box>
                    <text-box
                      :alarm="getAlarm('JK11')"
                      :offset="[220, 10]"
                      @click="(el) => showState(el, 'JK11')"
                    ></text-box>
                    <protector-box
                      @click="(el) => showState(el, 'JK12')"
                      :offset="[36, 10]"
                      :alarm="getAlarm('JK12')"
                    ></protector-box>
                    <switch-box
                      @click="(el) => showState(el, 'JK13')"
                      :type="3"
                      :offset="[36, 134]"
                      :alarm="getAlarm('JK13')"
                    ></switch-box>
                    <switch-box
                      @click="(el) => showState(el, 'JK14')"
                      :type="3"
                      :offset="[220, 134]"
                      :alarm="getAlarm('JK14')"
                    ></switch-box>
                    <switch-box
                      @click="(el) => showState(el, 'JK15')"
                      :type="3"
                      :offset="[390, 134]"
                      :alarm="getAlarm('JK15')"
                    ></switch-box>
                    <switch-box
                      @click="(el) => showState(el, 'JK16')"
                      :type="1"
                      :offset="[36, 252]"
                      :alarm="getAlarm('JK16')"
                    ></switch-box>
                    <switch-box
                      @click="(el) => showState(el, 'JK17')"
                      :type="1"
                      :offset="[150, 252]"
                      :alarm="getAlarm('JK17')"
                    ></switch-box>
                    <switch-box
                      @click="(el) => showState(el, 'JK18')"
                      :type="1"
                      :offset="[274, 252]"
                      :alarm="getAlarm('JK18')"
                    ></switch-box>
                    <switch-box
                      @click="(el) => showState(el, 'JK19')"
                      :type="1"
                      :offset="[390, 252]"
                      :alarm="getAlarm('JK19')"
                    ></switch-box>
                    <svg-line
                      :points="[
@@ -363,8 +428,10 @@
              </div>
              <div class="yc-panel-footer">
                <!-- TODO 告警 滚动 -->
                <div class="state"></div>
                <div class="state">
                  <marqueeLeft :list="alarm_ac1" v-if="alarm_ac1.length"></marqueeLeft>
                  <div class="no-warning-msg" v-else>无</div>
                </div>
              </div>
            </div>
          </div>
@@ -374,45 +441,57 @@
              <div class="svg-contain">
                <div class="pos-full">
                  <svg width="100%" height="100%" viewBox="0 0 500 340">
                    <text-box :offset="[220, 10]" @click="(el) => showState(el, 'JK21')"></text-box>
                    <text-box
                      :offset="[220, 10]"
                      @click="(el) => showState(el, 'JK21')"
                      :alarm="getAlarm('JK21')"
                    ></text-box>
                    <protector-box
                      @click="(el) => showState(el, 'JK22')"
                      :offset="[390, 10]"
                      :alarm="getAlarm('JK22')"
                    ></protector-box>
                    <switch-box
                      @click="(el) => showState(el, 'JK23')"
                      :type="3"
                      :offset="[36, 134]"
                      :alarm="getAlarm('JK23')"
                    ></switch-box>
                    <switch-box
                      @click="(el) => showState(el, 'JK24')"
                      :type="3"
                      :offset="[220, 134]"
                      :alarm="getAlarm('JK24')"
                    ></switch-box>
                    <switch-box
                      @click="(el) => showState(el, 'JK25')"
                      :type="3"
                      :offset="[390, 134]"
                      :alarm="getAlarm('JK25')"
                    ></switch-box>
                    <switch-box
                      @click="(el) => showState(el, 'JK26')"
                      :type="1"
                      :offset="[36, 252]"
                      :alarm="getAlarm('JK26')"
                    ></switch-box>
                    <switch-box
                      @click="(el) => showState(el, 'JK27')"
                      :type="1"
                      :offset="[150, 252]"
                      :alarm="getAlarm('JK27')"
                    ></switch-box>
                    <switch-box
                      @click="(el) => showState(el, 'JK28')"
                      :type="1"
                      :offset="[274, 252]"
                      :alarm="getAlarm('JK28')"
                    ></switch-box>
                    <switch-box
                      @click="(el) => showState(el, 'JK29')"
                      :type="1"
                      :offset="[390, 252]"
                      :alarm="getAlarm('JK29')"
                    ></switch-box>
                    <svg-line
                      :points="[
@@ -478,7 +557,10 @@
                </div>
              </div>
              <div class="yc-panel-footer">
                <div class="state"></div>
                <div class="state">
                  <marqueeLeft :list="alarm_ac2" v-if="alarm_ac2.length"></marqueeLeft>
                  <div class="no-warning-msg" v-else>无</div>
                </div>
              </div>
            </div>
          </div>
@@ -494,47 +576,56 @@
                      @click="(el) => showState(el, 'DK11')"
                      :type="2"
                      :offset="[269, 14]"
                      :alarm="getAlarm('DK11')"
                    ></switch-box>
                    <switch-box
                      @click="(el) => showState(el, 'DK12')"
                      small
                      :offset="[20, 160]"
                      :alarm="getAlarm('DK12')"
                    ></switch-box>
                    <switch-box
                      @click="(el) => showState(el, 'DK13')"
                      small
                      :offset="[94, 160]"
                      :alarm="getAlarm('DK13')"
                    ></switch-box>
                    <switch-box
                      @click="(el) => showState(el, 'DK14')"
                      small
                      :offset="[168, 160]"
                      :alarm="getAlarm('DK14')"
                    ></switch-box>
                    <!-- alarm -->
                    <switch-box
                      @click="(el) => showState(el, 'DK15')"
                      small
                      :offset="[242, 160]"
                      :alarm="getAlarm('DK15')"
                    ></switch-box>
                    <switch-box
                      @click="(el) => showState(el, 'DK16')"
                      small
                      :offset="[316, 160]"
                      :alarm="getAlarm('DK16')"
                    ></switch-box>
                    <switch-box
                      @click="(el) => showState(el, 'DK17')"
                      small
                      :offset="[390, 160]"
                      :alarm="getAlarm('DK17')"
                    ></switch-box>
                    <switch-box
                      @click="(el) => showState(el, 'DK18')"
                      small
                      :offset="[464, 160]"
                      :alarm="getAlarm('DK18')"
                    ></switch-box>
                    <switch-box
                      @click="(el) => showState(el, 'DK19')"
                      small
                      :offset="[538, 160]"
                      :alarm="getAlarm('DK19')"
                    ></switch-box>
                    <svg-line
                      :points="[
@@ -591,7 +682,10 @@
                </div>
              </div>
              <div class="yc-panel-footer">
                <div class="state"></div>
                <div class="state">
                  <marqueeLeft :list="alarm_dc1" v-if="alarm_dc1.length"></marqueeLeft>
                  <div class="no-warning-msg" v-else>无</div>
                </div>
              </div>
            </div>
          </div>
@@ -605,46 +699,55 @@
                      @click="(el) => showState(el, 'DK21')"
                      :type="2"
                      :offset="[269, 14]"
                      :alarm="getAlarm('DK21')"
                    ></switch-box>
                    <switch-box
                      @click="(el) => showState(el, 'DK22')"
                      small
                      :offset="[20, 160]"
                      :alarm="getAlarm('DK22')"
                    ></switch-box>
                    <switch-box
                      @click="(el) => showState(el, 'DK23')"
                      small
                      :offset="[94, 160]"
                      :alarm="getAlarm('DK23')"
                    ></switch-box>
                    <switch-box
                      @click="(el) => showState(el, 'DK24')"
                      small
                      :offset="[168, 160]"
                      :alarm="getAlarm('DK24')"
                    ></switch-box>
                    <switch-box
                      @click="(el) => showState(el, 'DK25')"
                      small
                      :offset="[242, 160]"
                      :alarm="getAlarm('DK25')"
                    ></switch-box>
                    <switch-box
                      @click="(el) => showState(el, 'DK26')"
                      small
                      :offset="[316, 160]"
                      :alarm="getAlarm('DK26')"
                    ></switch-box>
                    <switch-box
                      @click="(el) => showState(el, 'DK27')"
                      small
                      :offset="[390, 160]"
                      :alarm="getAlarm('DK27')"
                    ></switch-box>
                    <switch-box
                      @click="(el) => showState(el, 'DK28')"
                      small
                      :offset="[464, 160]"
                      :alarm="getAlarm('DK28')"
                    ></switch-box>
                    <switch-box
                      @click="(el) => showState(el, 'DK29')"
                      small
                      :offset="[538, 160]"
                      :alarm="getAlarm('DK29')"
                    ></switch-box>
                    <svg-line
                      :points="[
@@ -701,7 +804,10 @@
                </div>
              </div>
              <div class="yc-panel-footer">
                <div class="state"></div>
                <div class="state">
                  <marqueeLeft :list="alarm_dc2" v-if="alarm_dc2.length"></marqueeLeft>
                  <div class="no-warning-msg" v-else>无</div>
                </div>
              </div>
            </div>
          </div>
@@ -712,11 +818,13 @@
    <div class="pop-info" v-show="popVisible" :style="popPosition">
      <div class="item">
        <div class="label">开关名称</div>
        <div class="value">{{ curSwitch['breakerType'] + curSwitch['breakerName'] }}</div>
        <div class="value">
          {{ curSwitch["breakerType"] + curSwitch["breakerName"] }}
        </div>
      </div>
      <div class="item">
        <div class="label">开关规格</div>
        <div class="value">{{ curSwitch['breakerLevel'] + 'P' }}</div>
        <div class="value">{{ curSwitch["breakerLevel"] + "P" }}</div>
      </div>
      <div class="item">
        <div class="label">开关状态</div>
@@ -918,7 +1026,7 @@
            color: #011f39;
            font-weight: bold;
            border-radius: 4px;
            padding-left: 0.8em;
            padding: 0 0.8em;
          }
        }
      }
src/views/realTime/index.vue
@@ -118,7 +118,7 @@
                <div class="card has-title">
                  <div class="card-title">三相交流输出电压(V)</div>
                  <div class="card-content">
                    <gauge3 unit="V" ref="board3"></gauge3>
                    <gauge3 unit="V" :range="[0, 300]" ref="board3"></gauge3>
                  </div>
                </div>
                <div class="card has-title">
src/views/switchControl/index.vue
@@ -226,6 +226,8 @@
        dcin2_switch_trip: [],
        dc1_switch1_trip: [],
        dc2_switch1_trip: [],
        breaker_state1: [],
        breaker_state2: [],
      },
      rtData: {},
      currIdx: 0,
@@ -337,12 +339,17 @@
        dcIn2SwitchTripReal,
        dc1Switch1TripReal,
        dc2Switch1TripReal,
        breakerState1,
        breakerState2,
      } = data2;
      let ac1_outswitch1_trip = getBinaryDigits(ac1OutSwitch1TripReal);
      let ac2_outswitch1_trip = getBinaryDigits(ac2OutSwitch1TripReal);
      let dc1_switch1_trip = getBinaryDigits(dc1Switch1TripReal);
      let dc2_switch1_trip = getBinaryDigits(dc2Switch1TripReal);
      let breaker_state1 = getBinaryDigits(breakerState1);
      let breaker_state2 = getBinaryDigits(breakerState2);
      let acin1_switch_trip = [acIn1SwitchTripReal];
      let acin2_switch_trip = [acIn2SwitchTripReal];
      let dcin1_switch_trip = [dcIn1SwitchTripReal];
@@ -357,6 +364,8 @@
        dcin2_switch_trip,
        dc1_switch1_trip,
        dc2_switch1_trip,
        breaker_state1,
        breaker_state2,
      };
      if (this.currIdx == 0 || this.currIdx == 1) {
@@ -444,13 +453,17 @@
    },
    getList(res) {
      if (res) {
        let list = res.map((v) => {
          v.breakerLevelStr = v.breakerLevel ? v.breakerLevel + "P" : "";
          v.almState = v.breakerAlmConifgList.length ? "告警" : "正常";
          v.state = this.switchStates[v.nodeName][v.nodeBit] ? "合闸" : "分闸";
          v.stateFlag = this.switchStates[v.nodeName][v.nodeBit];
          return v;
        });
        let list = res
          .filter((v) => v.breakerName != "JK12" && v.breakerName != "JK22")
          .map((v) => {
            v.breakerLevelStr = v.breakerLevel ? v.breakerLevel + "P" : "";
            v.almState = v.breakerAlmConifgList.length ? "告警" : "正常";
            v.state = this.switchStates[v.switchNodeName][v.switchNodeBit]
              ? "分闸"
              : "合闸";
            v.stateFlag = !this.switchStates[v.switchNodeName][v.switchNodeBit];
            return v;
          });
        this.table.datas = list;
      }
    },