Browse Source

pagehome:<feat>电井与商铺联动

YaolongHan 4 years ago
parent
commit
84d406d455

BIN
src/assets/imgs/btn-rect-active.png


BIN
src/assets/imgs/btn-rect.png


BIN
src/assets/imgs/logo1.png


+ 334 - 0
src/components/floorListDark.vue

@@ -0,0 +1,334 @@
+/**
+*@author:Guoxiaohuan
+*@date:2020.06.02
+*@info:楼层列表
+*/
+<template>
+  <div class="floor-box">
+    <div class="floor-list">
+      <div class="icon-top" v-if="floorsArr.length > 8">
+        <!-- @click='changeFloor(1,currIndex)' -->
+        <img
+          v-show="parseInt(marginTop) !== 0"
+          v-repeat-click="increase"
+          src="@/assets/imgs/iconBlackTop.png"
+          alt
+        />
+        <img
+          class="disabled"
+          v-show="parseInt(marginTop) === 0"
+          src="@/assets/imgs/iconLightTop.png"
+          alt
+        />
+      </div>
+      <div class="floor-out" :style="{ height: conHeight + 'px' }">
+        <!--  放开marginTop样式  -->
+        <div class="floor-center" :style="{ marginTop: marginTop }">
+          <div
+            class="floor-item"
+            :class="item.seq == currentFloorId ? 'isActive' : ''"
+            @click="tabFloor(item, index)"
+            v-for="(item, index) in floorsArr"
+            :key="index"
+          >
+            {{ item.code }}
+          </div>
+        </div>
+      </div>
+      <div class="icon-bottom" v-if="floorsArr.length > 8">
+        <!-- v-repeat-click='decrease' -->
+        <img
+          v-show="parseInt(marginTop) !== marginTopMax"
+          v-repeat-click="decrease"
+          src="@/assets/imgs/iconBlackBottom.png"
+          alt
+        />
+        <img
+          class="disabled"
+          v-show="parseInt(marginTop) === marginTopMax"
+          src="@/assets/imgs/iconLightBottom.png"
+          alt
+        />
+      </div>
+    </div>
+  </div>
+</template>
+<script>
+import store from "../store";
+import { mapGetters } from "vuex";
+import RepeatClick from "@/directives/repeat-click";
+
+export default {
+  directives: {
+    repeatClick: RepeatClick,
+  },
+  data() {
+    return {
+      floorId: "F1",
+      showT: true,
+      showB: true,
+      num: 0,
+      floorMapIdName: "",
+      floor: {},
+      currentFloorId: null,
+      marginTop: 0,
+      marginTopMax: 0,
+      startTime: "",
+      endTime: "",
+      floorObj2: {},
+      showNumber: 8, //需要展示的楼层数
+      height: 39, //一个楼层的高度
+      currIndex: 0, //当前楼层在 楼层数组中的下标,上下箭头使用
+      conHeight: 0, // floor-out 的高度
+    };
+  },
+  props: {
+    floorsArr: {
+      type: Array,
+      default: () => {
+        return [];
+      },
+    },
+    // 默认true,
+    // 1. 切换楼层后,是否触发 cookie,vuex数据修改,
+    // 2. 在fenbuPic组件中为false, 1)不触发cookie,vuex , 2) 选中的楼层ID,为楼层列表数组floorIdArr的第0个
+    changeDataFlag: {
+      type: Boolean,
+      default: true,
+    },
+  },
+  computed: {
+    ...mapGetters(["legendTable", "floorObj"]),
+  },
+  mounted() {
+    this.init();
+  },
+  methods: {
+    /**
+     * @description 点击上箭头,marginTop<0时执行楼层滚动
+     */
+    increase() {
+      let marginTop = parseInt(this.marginTop);
+      marginTop < 0 && this.changeFloor(1, this.currIndex);
+    },
+    /**
+     * @description 点击下箭头,marginTop小于最大值marginTopMax时,执行楼层滚动
+     */
+    decrease() {
+      let marginTop = Math.abs(parseInt(this.marginTop)),
+        marginTopMax = Math.abs(parseInt(this.marginTopMax));
+      marginTop < marginTopMax && this.changeFloor(-1, this.currIndex);
+    },
+    init() {
+      if (!this.floorsArr.length) {
+        return false;
+      }
+      this.floorIdArr = [];
+      this.floorsArr.map((item) => {
+        this.floorIdArr.push(item.seq);
+        if (item.seq == this.$cookie.get("currentFloorId")) {
+          this.floor = item;
+        } else {
+          this.floor = this.floorObj;
+        }
+      });
+      this.currentFloorId = Number(
+        this.$cookie.get("currentFloorId") || this.floor.seq
+      );
+      // bug fix 修复 fenbuPic 弹窗中,楼层不能选中的问题
+      // 如果 floorIdArr 不在 floorIdArr数组中,或者changeDataFlag为false(弹窗组件中的楼层组件),使用 floorIdArr[0], 而不使用 cookie
+      let index = this.floorIdArr.findIndex(
+        (item) => item === this.currentFloorId
+      );
+      if (index === -1 || !this.changeDataFlag) {
+        this.currentFloorId = this.floorIdArr[0];
+      }
+      // 修复在设备设施页面中,楼层组件不够 8个楼层时,出现的样式问题,
+      this.conHeight = this.floorsArr.length * 37.5;
+      this.conHeight = this.conHeight >= 300 ? 300 : this.conHeight;
+      this.showNumber = this.floorsArr.length > 8 ? 8 : this.floorsArr.length;
+
+      this.marginTopMax =
+        -(this.floorIdArr.length - this.showNumber) * this.height;
+      this.changeFloor(0, index);
+    },
+    /**
+     * @name changeFloor
+     * @param {Number} flag 1:向上滚动楼层, -1向下滚动 , 0:进入页面初始化时,执行位置处理
+     * @description 点击图例下方的,上下切换按钮
+     */
+    changeFloor(flag, index) {
+      const len = this.floorIdArr.length;
+      // let index = this.floorIdArr.findIndex(item => item === this.currentFloorId)
+      this.currIndex = index;
+      // 点击上箭头
+      if (flag === 1) {
+        index--;
+        this.currIndex = index;
+      } else if (flag === -1) {
+        //点击下箭头
+        index++;
+        this.currIndex = index;
+      }
+      // FEAT:  点击上下箭头,不触发cookie更改 , 只有初始化时,才进行选中的楼层 状态更新
+      if (flag === 0) {
+        this.handleCookie();
+      }
+      this.handlePosition(flag, index, len);
+    },
+    handleCookie() {
+      let currentFloor = this.floorsArr.filter(
+        (item) => item.seq == this.currentFloorId
+      )[0];
+      if (currentFloor) {
+        // 如果 changeDataFlag为true(不是在 分布图弹窗组件中的 楼层组件),设置cookie,vuex
+        if (this.changeDataFlag) {
+          this.$cookie.set("floorNow", currentFloor.code || "", 3);
+          this.$cookie.set("floorMapId", currentFloor.gname, 3);
+          this.$cookie.set("currentFloorId", currentFloor.seq, 3);
+          this.floorId = this.$cookie.get("floorNow") || currentFloor.code;
+          this.floorMapIdName =
+            this.$cookie.get("floorMapId") || currentFloor.gname;
+          store.commit("SETCURRENTFLOOR", currentFloor);
+        }
+        this.$emit("emitFloor", currentFloor);
+      }
+    },
+    /**
+     * @name tabFloor
+     * @param {Object} item 选中的楼层信息
+     * @param {Number} index 楼层信息在floorsArr数组中的位置
+     */
+    tabFloor(item, index) {
+      this.currentFloorId = this.floorIdArr[index];
+      this.handleCookie();
+      this.handlePosition(2, index, this.floorIdArr.length);
+      this.viewLengend();
+    },
+    viewLengend() {
+      if (this.legendTable.length > 0) {
+        this.$store.commit("SETSHOWVIEW", 1);
+      } else {
+        this.$store.commit("SETSHOWVIEW", 0);
+      }
+    },
+    /**
+     * @description 楼层位置动画处理
+     * @param flag 1:向上滚动楼层, -1向下滚动 , 0:进入页面初始化时,执行位置处理 2:直接点击楼层
+     * @param index 楼层 在floorIdArr中的下标
+     * @param len floorIdArr长度
+     */
+    handlePosition(flag, index, len) {
+      // 取出当前 marginTop
+      let marginTop = parseInt(this.marginTop);
+      switch (flag) {
+        // 初始化进入页面,位置处理
+        case 0:
+        // 直接点击楼层,滚动楼层
+        case 2:
+          // 将 marginTop 设置为对应的index 应滚动的距离
+          marginTop = -index * this.height;
+          // marginTop 过大时,取最大值marginTopMax
+          if (Math.abs(marginTop) >= Math.abs(this.marginTopMax)) {
+            marginTop = parseInt(this.marginTopMax);
+          }
+          // marginTop>0时,取0,防止楼层上边出现空白
+          marginTop = marginTop >= 0 ? 0 : marginTop;
+          // index为0,marginTop设置为0
+          index == 0 && (marginTop = 0);
+          // index为最后一个,设置为最大marginTopMax
+          index == len - 1 && (marginTop = parseInt(this.marginTopMax));
+          this.marginTop = marginTop + "px";
+          break;
+        //  1:向上滚动楼层
+        case 1:
+          this.marginTop = marginTop + this.height + "px";
+          break;
+        // -1向下滚动楼层
+        case -1:
+          this.marginTop = marginTop + this.height * -1 + "px";
+          break;
+        default:
+          break;
+      }
+    },
+  },
+};
+</script>
+<style lang="less" scoped>
+.floor-box {
+  .floor-list {
+    width: 44px;
+    // height: 212px;
+    box-shadow: 0px 2px 15px 0px rgba(31, 36, 41, 0.08);
+    border-radius: 2px;
+    position: relative;
+    padding: 6px 4px;
+    text-align: center;
+    background: rgba(22,73,206,0.36);
+    border: 1px solid rgba(105,207,234,0.36);
+    .floor-out {
+      // max-height: 300px; //TODO:
+      min-height: 38px;
+      overflow: hidden;
+      position: relative;
+      overflow-y: auto;
+      &::-webkit-scrollbar {
+        display: none;
+      }
+
+      .floor-center {
+        transition: all linear 0.5s;
+        .floor-item {
+          line-height: 28px;
+          height: 28px;
+          cursor: pointer;
+          position: relative;
+          color: #69cfea;
+          &::after {
+            position: absolute;
+            left: 50%;
+            margin-left: -20%;
+            bottom: -6px;
+            content: "";
+            width: 14px;
+            height: 1px;
+            background: rgba(195, 199, 203, 1);
+            border: 0px solid rgba(228, 229, 231, 1);
+          }
+          & + .floor-item {
+            margin-top: 10px;
+          }
+        }
+      }
+    }
+
+    .icon-top {
+      cursor: pointer;
+      height: 18px;
+      img {
+        width: 18px;
+        height: 100%;
+        margin-top: -10px;
+      }
+    }
+    .icon-bottom {
+      cursor: pointer;
+      height: 18px;
+      img {
+        width: 18px;
+        height: 100%;
+        margin-top: -10px;
+      }
+    }
+    .isActive {
+      background: rgba(98, 196, 221, 0.3);
+      border-radius: 4px;
+      border: 1px solid #62c4dd;
+    }
+  }
+  .disabled {
+    cursor: not-allowed !important;
+  }
+}
+</style>

+ 2 - 2
src/components/floorMap/canvasFun.vue

@@ -141,8 +141,8 @@ export default {
         height: 100%;
         padding: 0 8px;
         margin-top: 10px;
-        border-left: 1px solid #e4e5e7;
-        border-right: 1px solid #e4e5e7;
+        border-left: 1px solid #182464;
+        border-right: 1px solid #182464;
         z-index: 1;
     }
 }

+ 181 - 0
src/components/floorMap/canvasFunDark.vue

@@ -0,0 +1,181 @@
+<template>
+    <div>
+        <div class='action-box'>
+            <div class='small-block'>
+                <el-dropdown size='mini' placement='top-start' @command='handleCommand'>
+                    <i>
+                        <img src='../../assets/imgs/dl.png' alt />
+                    </i>
+                    <el-dropdown-menu slot='dropdown'>
+                        <el-dropdown-item command='savePng'>保存为png</el-dropdown-item>
+                        <!-- <el-dropdown-item command='saveSvg'>保存为svg</el-dropdown-item> -->
+                    </el-dropdown-menu>
+                </el-dropdown>
+            </div>
+            <div class='small-block' @click='showText'>
+                <i>
+                    <el-tooltip v-if='isShow' effect='dark' content='隐藏店铺名称' placement='top'>
+                        <img src='../../assets/imgs/yl.png' alt />
+                    </el-tooltip>
+                    <el-tooltip v-else effect='dark' content='显示店铺名称' placement='top'>
+                        <img src='../../assets/imgs/er.png' alt />
+                    </el-tooltip>
+                </i>
+            </div>
+            <div class='small-block' @click='fitToWindow'>
+                <i>
+                    <img src='../../assets/imgs/eye2.jpg' alt />
+                </i>
+            </div>
+            <div class='small-size' @click='reduce'>
+                <i>-</i>
+            </div>
+            <div class='small-slide'>
+                <el-slider tooltip-class='tooltip-class' :min='min' v-model='sliderVal' :show-tooltip='false' @input='scale' :max='max'></el-slider>
+            </div>
+            <div class='small-size' @click='plus'>
+                <i>+</i>
+            </div>
+        </div>
+    </div>
+</template>
+<script>
+export default {
+    data() {
+        return {
+            sliderVal: 1, // 滑块值
+            active: '',
+            min: 1,
+            max: 200,
+            everyScale: 1, // 每份的放大倍数
+            isSwitch: false, // 是否开启吸附
+            isShow: false
+        }
+    },
+
+    methods: {
+        // 适配大小
+        fitToWindow() {
+            this.$emit('fit')
+        },
+        // 下拉菜单
+        handleCommand(command) {
+            this.$emit(command)
+        },
+        // 是否开启吸附
+        handleDivideCommand(commond) {
+            this.$emit('changeAbsorb', this.isSwitch)
+        },
+        // 切割编辑
+        divide() {
+            this.active = 'divide'
+            this.$emit('divide')
+        },
+        // 清除编辑
+        clearDivide() {
+            this.active = ''
+            this.$emit('clearDivide')
+        },
+        // 减
+        reduce() {
+            this.sliderVal /= 1.1
+            if (this.sliderVal < this.min) {
+                this.sliderVal = this.min
+            }
+            this.scale(this.sliderVal)
+        },
+        // 缩放
+        scale(val) {
+            // 换算
+            let scale = (val * this.everyScale) / 10
+            this.$emit('scale', scale)
+        },
+        // 加
+        plus() {
+            this.sliderVal *= 1.1
+            if (this.sliderVal > this.maxScale) {
+                this.sliderVal = this.maxScale
+            }
+            this.scale(this.sliderVal)
+        },
+        showText() {
+            this.isShow = !this.isShow
+            this.$emit('showText', this.isShow)
+        }
+    },
+    mounted() {}
+}
+</script>
+<style lang="less" scoped>
+.action-box {
+    width: 400px;
+    height: 40px;
+
+
+    background: #182464;
+    color: #62C4DD;
+
+    box-shadow: 0px 2px 15px 0px rgba(31, 36, 41, 0.08);
+    border-radius: 2px;
+    margin: 0 auto;
+    display: flex;
+    align-items: center;
+    overflow: hidden;
+    .small-block {
+        border-right: 1px solid #62C4DD;
+        padding: 12px;
+        cursor: pointer;
+        i {
+            width: 16px;
+            height: 16px;
+            display: inline-block;
+            img {
+                width: 100%;
+                height: 100%;
+            }
+        }
+    }
+    .small-size {
+        cursor: pointer;
+        padding: 12px;
+        font-size: 28px;
+    }
+    .small-slide {
+        flex: 1;
+        height: 100%;
+        padding: 0 8px;
+        margin-top: 10px;
+        border-left: 1px solid #e4e5e7;
+        border-right: 1px solid #e4e5e7;
+        z-index: 1;
+    }
+}
+</style>
+<style lang="less">
+.action-box {
+    .el-slider__button {
+        width: 13px;
+        height: 13px;
+        border: 2px solid #025baa;
+    }
+    .el-slider__runway {
+        height: 3px;
+        background-color: #e4e7ed;
+        background: rgba(0, 0, 0, 0.45);
+        border-radius: 1px;
+    }
+    .el-slider__button-wrapper {
+        top: -17px;
+    }
+    .el-slider__bar {
+        height: 3px;
+        background-color: #025baa;
+        border-top-left-radius: 1px;
+        border-bottom-left-radius: 1px;
+    }
+    .action-box .el-slider__runway {
+        background-color: #e8e8e8 !important;
+        background: #e8e8e8 !important;
+    }
+}
+</style>

+ 995 - 0
src/components/floorMap/darkColorIndex.vue

@@ -0,0 +1,995 @@
+
+<!-- 底图 -->
+<template>
+    <div id='floor_base' v-loading='loading' ref='graphycolor'>
+        <canvas :id='`canvas${id}`' :width='canvasWidth' :height='canvasHeight' tabindex='0'></canvas>
+        <!-- 地图底部操作按钮 -->
+        <div class='strip-bottom'>
+            <canvasFun @fit='fit' @savePng='savePng' @saveSvg='saveSvg' @saveJson='saveJson' @scale='scale' @showText='showText' ref='canvasFun'></canvasFun>
+        </div>
+        <room-box :key='`rommBox${roomKey}`' ref='boxRoom'></room-box>
+        <equip-detail ref='equipDetail' :key='equipKey'></equip-detail>
+        <el-popover ref='popover' placement='right' trigger='manual' v-model='visible' width='380'>
+            <!-- <div style="text-align: right;margin-bottom: 10px;">
+                <span style="float: left;">对应的工程信息化信息</span>
+                <el-link icon="el-icon-close" :underline="false" @click="visible = false"></el-link>
+            </div>-->
+            <!-- 点击图标,出现的弹窗 -->
+            <div v-if='equipIds.length && !tabData.pointData.length' style='margin-top: 10px;'>
+                <el-table
+                    :data='tabData.tableData'
+                    max-height='235'
+                    style='width: 100%'
+                    @row-click='handleClickEquipDetail'
+                    v-loading='eqLoading'
+                    :cell-class-name='tableCellClassName'
+                >
+                    <el-table-column prop='sbjc' label='设备简称' width='144' :show-overflow-tooltip='true'></el-table-column>
+                    <el-table-column prop='sl' width='50' label='数量' :show-overflow-tooltip='true'></el-table-column>
+                    <el-table-column prop='sb_status' width='80' label='设备状态' :show-overflow-tooltip='true'></el-table-column>
+                    <el-table-column prop='sbglgs' width='80' label='管理归属' :show-overflow-tooltip='true'></el-table-column>
+                    <!-- <el-table-column prop="assetnum" width="80" label="设备内码" :show-overflow-tooltip='true'></el-table-column>
+                    <el-table-column label="" width="80" :show-overflow-tooltip='true'>
+                        <template slot-scope="scope">
+                            <span class="equip-detail-btn">台账详情</span>
+                        </template>
+                    </el-table-column>-->
+                </el-table>
+                <!-- <div style="text-align: right; margin-top: 10px;">
+                    <el-button size="mini" type="primary" @click="visible = false">关闭</el-button>
+                </div>-->
+            </div>
+            <!-- 点击空间,出现的弹窗 -->
+            <div v-else-if='!equipIds.length && tabData.pointData.length' style='margin-top: 10px;'>
+                <ul class='pointList'>
+                    <li v-for='point in tabData.pointData' :key='point.id' @click='handleClickPointDeatil(point)'>
+                        <span :title='point.name'>{{point.name}}</span>
+                        <a>查看</a>
+                    </li>
+                </ul>
+                <div style='text-align: right; margin-top: 10px;'>
+                    <el-button v-show='showBtnWell' size='mini' type='primary' @click='handleClickHightLight(tabData.pointData)'>查看控制商铺范围</el-button>
+                    <!-- <el-button size="mini" type="primary" @click="visible = false">关闭</el-button> -->
+                </div>
+            </div>
+            <!-- 既有空间,又有设备的弹窗 -->
+            <el-tabs v-else-if='equipIds.length && tabData.pointData.length' v-model='activeName'>
+                <el-tab-pane label='设备设施' name='equip'>
+                    <el-table
+                        :data='tabData.tableData'
+                        max-height='235'
+                        style='width: 100%'
+                        @row-click='handleClickEquipDetail'
+                        :cell-class-name='tableCellClassName'
+                        v-loading='eqLoading'
+                    >
+                        <el-table-column prop='sbjc' label='设备简称' width='164' :show-overflow-tooltip='true'></el-table-column>
+                        <el-table-column prop='sl' width='50' label='数量' :show-overflow-tooltip='true' align='right'></el-table-column>
+                        <el-table-column prop='sb_status' width='70' label='设备状态' :show-overflow-tooltip='true'></el-table-column>
+                        <el-table-column prop='sbglgs' width='70' label='管理归属' :show-overflow-tooltip='true'></el-table-column>
+                        <!-- <el-table-column prop="assetnum" width="80" label="设备内码" :show-overflow-tooltip='true'></el-table-column>
+                        <el-table-column label="" width="80" :show-overflow-tooltip='true'>
+                            <template slot-scope="scope">
+                                <span class="equip-detail-btn">台账详情</span>
+                            </template>
+                        </el-table-column>-->
+                    </el-table>
+                    <div style='text-align: right; margin-top: 10px;'>
+                        <!-- <el-button size="mini" type="primary" @click="visible = false">关闭</el-button> -->
+                    </div>
+                </el-tab-pane>
+                <el-tab-pane label='位置' name='point'>
+                    <ul class='pointList'>
+                        <li v-for='point in tabData.pointData' :key='point.id' @click='handleClickPointDeatil(point)'>
+                            <span :title='point.name'>{{point.name}}</span>
+                            <a>查看</a>
+                        </li>
+                    </ul>
+                    <div style='text-align: right; margin-top: 10px;'>
+                        <el-button v-show='showBtnWell' size='mini' type='primary' @click='handleClickHightLight(tabData.pointData)'>查看控制商铺范围</el-button>
+                        <!-- <el-button size="mini" type="primary" @click="visible = false">关闭</el-button> -->
+                    </div>
+                </el-tab-pane>
+            </el-tabs>
+        </el-popover>
+        <span class='popStyle' :style='popoverPosition' v-popover:popover></span>
+    </div>
+</template>
+<script>
+/**
+ * @author yunxing
+ * @date 2020年08月21日11:04
+ * @description 停用,已拆除的状态,使用message进行提示
+ */
+import { SFengParser, ProjectRf } from '@saga-web/feng-map'
+import { SFloorParser, ItemOrder, ItemColor, SPolygonItem, SBoardItem } from '@saga-web/big'
+import { FloorView } from '@/lib/FloorView'
+import { FloorScene } from '@/lib/FloorScene'
+import RoomBox from '@/views/room/index'
+import canvasFun from '@/components/floorMap/canvasFunDark'
+import { readGroup, queryStatis, graphQuery } from '@/api/public'
+import { queryShops, queryAssetAll } from '@/api/equipmentList.js'
+import { STopologyParser } from '@/lib/parsers/STopologyParser'
+import { mapGetters, mapActions } from 'vuex'
+import { SImageItem, SImageShowType, SGraphItem } from '@saga-web/graph/lib'
+import { SColor } from '@saga-web/draw/lib'
+import bus from '@/utils/bus.js'
+import { TipelineItem } from '../../lib/items/TipelineItem'
+import { SImageLegendItem } from '../../lib/items/SImageLegendItem'
+import equipDetail from '../../views/equipment/table/equipDetail'
+import { debounce } from 'lodash'
+import { Message } from 'element-ui'
+// import { uuid } from "@/components/mapClass/until";
+
+export default {
+    data() {
+        return {
+            appName: '万达可视化系统',
+            key: '23f30a832a862c58637a4aadbf50a566',
+            mapServerURL: `http://mapapp.wanda.cn/editor`,
+            canvasWidth: 600,
+            canvasHeight: 800,
+            loading: false, // 限制重复查询
+            view: null,
+            urlMsg: {},
+            canvasID: 'canvas',
+            floorid: '', //楼层id
+            topologyParser: null, // 解析器数据
+            fParser: null, // 底图解析器
+            wellMap: {}, // 电井控制商铺映射
+            activeName: 'equip',
+            popoverPosition: {
+                top: 0,
+                left: 0,
+            },
+            statusTextPosition: {
+                top: 0,
+                left: 0,
+            },
+            visible: false,
+            eqLoading: true,
+            equipIds: [],
+            tabData: {
+                tableData: [],
+                pointData: [],
+            },
+            activeItem: null,
+            showBtnWell: false,
+            count: 0, // 顶楼为多张图时计数器
+            equipKey: 1, //设备弹窗使用key值,解决打开弹窗数据为上次弹窗的数据
+            statusDisabled: ['已拆除'], //禁止跳转的设备状态
+            roomKey: 1,
+            shopsnumList:[] //所有与电井相关的商铺
+        }
+    },
+    props: {
+        id: {
+            default: '1',
+            type: String,
+        },
+        categoryId: {
+            default: '',
+            type: String,
+        },
+        // 弹窗高度,适配底图高度使用
+        modalHeight: {
+            type: [Number, undefined],
+            default: undefined,
+        },
+        loadName: null,
+        type: null,
+    },
+    components: { RoomBox, canvasFun, equipDetail },
+    computed: {
+        ...mapGetters(['plazaId', 'fmapID', 'haveFengMap', 'bunkObj']),
+    },
+    methods: {
+        handleClickLegendItem(item, events) {
+            this.tabData = { tableData: [], pointData: [] }
+            this.equipIds = []
+            this.showBtnWell = false
+            this.visible = false
+            this.activeItem = null
+            this.isLoading = true
+            if (item.data.AttachObjectIds && item.data.AttachObjectIds.length) {
+                const e = events[0]
+                this.activeItem = item
+                item.data.AttachObjectIds.forEach((v) => {
+                    if (v.type == 'Image') {
+                        if (v.id) {
+                            this.equipIds.push(v.id)
+                        }
+                        // this.tabData.tableData.push(v);
+                    } else if (v.type == 'Zone') {
+                        this.tabData.pointData.push(v)
+                    }
+                })
+                if (this.equipIds.length) {
+                    this.eqLoading = true
+                    let data = {
+                        plazaId: this.$store.state.plazaId,
+                        page: 1,
+                        size: this.equipIds.length,
+                    }
+                    let postParams = {
+                        assetnumList: this.equipIds,
+                    }
+                    queryAssetAll({ data, postParams }).then((res) => {
+                        this.tabData.tableData = res.data.data
+                        this.eqLoading = false
+                        console.log('this.tabData',this.tabData)
+                    })
+                }
+                this.popoverPosition.top = `${e.clientY}px`
+                this.popoverPosition.left = `${e.clientX}px`
+                this.$nextTick(() => {
+                    if (
+                        item.data.GraphElementId == '100050' ||
+                        item.data.GraphElementId == '100055' ||
+                        item.data.GraphElementId == '100056' ||
+                        item.data.GraphElementId == '100057'
+                    ) {
+                        //判断是否为电井
+                        this.showBtnWell = true
+                    }
+                    this.visible = true
+                })
+            }
+        },
+        // 初始化获取所有电井对应的底图商铺id
+        wellToShop(){
+            // 获取所有电井相关的底图
+            const pointData = this.tabData.pointData;
+            this.clearHightLight()
+            let location = ''
+            pointData.forEach((point) => {
+                location = location + point.id ? point.id+":wellnum;" : ''
+            });
+            let getParams = {
+                    plazaId: this.plazaId,
+                    floor: this.floorid,
+                    keyword: location,
+                }
+            queryShops({ getParams }).then((res) => {
+                let shopsnumList = []
+                if (res.data && res.data.length) {
+                    for (let floor in res.data[0]) {
+                        if (res.data[0][floor].length) {
+                            res.data[0][floor].forEach((v) => {
+                                shopsnumList = shopsnumList.concat(v.shopsnumList.split(','))
+                            })
+                        }
+                    }
+                }
+                this.shopsnumList = shopsnumList
+            })
+        },
+        // 查看浮层设备详情
+        handleClickEquipDetail: debounce(function (row, column, event) {
+            // 设备状态为停用或已拆除时,弹出消息
+            if (this.statusDisabled.includes(row?.sb_status)) {
+                let message = `当前设备状态为“${row.sb_status}”,请复核现场情况,如有需要请前往编辑器删除。` // `当前设备为“${row.sb_status}”状态,请前往编辑器重新编辑`
+                // 防止出现多条message
+                // 已经有 message时,并且this.message的message字段与message一致时, 不进行提示
+                if (this.message && this.message.visible && this.message.message === message) {
+                    return true
+                }
+                this.message = Message({
+                    showClose: true,
+                    message,
+                    type: 'warning',
+                    duration: 0,
+                    iconClass: 'el-icon-warning-outline',
+                    customClass: 'floor-map-warning',
+                })
+                // this.message = this.$message({
+                //     message,
+                //     type: 'warning',
+                // })
+                return true
+            }
+            if (row.assetnum) {
+                this.equipKey++
+                this.$nextTick(() => {
+                    this.$refs.equipDetail.open({ row: JSON.stringify(row) })
+                })
+            }
+        }, 0),
+        // handleClickEquipDetail(row) {
+        //     if (row.assetuid) {
+        //         window.open(`http://gcgl.wanda.cn/maximo/ui/?event=loadapp&value=assetdevic&uniqueid=${row.assetuid}`)
+        //     }
+        // },
+        // 查看浮层位置详情
+        handleClickPointDeatil(point) {
+            if (point.id && this.activeItem) {
+                this.roomKey++
+                this.$nextTick(() => {
+                    this.$refs.boxRoom.open({ name: this.activeItem.name, type: this.type, location: point.id })
+                })
+            }
+        },
+        handleClickHightLight(pointData) {
+            this.clearHightLight()
+            pointData.forEach((point) => {
+                let location = point.id ? point.id : ''
+                // if (this.wellMap.hasOwnProperty(location)) {
+                //     this.wellMap[location].forEach((item) => {
+                //         item.highLightFlag = true
+                //         item.zOrder = 30
+                //     })
+                // } else {
+                    let getParams = {
+                        plazaId: this.plazaId,
+                        floor: this.floorid,
+                        keyword: `${location}:wellnum;`,
+                    }
+                    queryShops({ getParams }).then((res) => {
+                        let shopsnumList = []
+                        // let shopsnumItemList = []
+                        if (res.data && res.data.length) {
+                            for (let floor in res.data[0]) {
+                                if (res.data[0][floor].length) {
+                                    res.data[0][floor].forEach((v) => {
+                                        shopsnumList = shopsnumList.concat(v.shopsnumList.split(','))
+                                    })
+                                }
+                            }
+                        }
+                        if (shopsnumList.length) {
+                            this.fParser.spaceList.forEach((item) => {
+                                if (shopsnumList.findIndex((name) => name == item.data.Name) != -1) {
+                                    item.highLightFlag = true
+                                    item.zOrder = 30
+                                    // shopsnumItemList.push(item)
+                                }
+                            })
+                            // this.wellMap[location] = shopsnumItemList
+                        }
+                    })
+                // }
+            })
+            this.visible = false
+        },
+        ...mapActions(['getfmapID']),
+        init(floorid) {
+            this.loading = true
+            this.floorid = floorid
+            this.mapSize()
+            this.$refs.canvasFun.isShow = false
+            setTimeout(() => {
+                this.clearGraphy()
+                this.scene = new FloorScene()
+                if (this.haveFengMap == 1) {
+                    this.scene.selectContainer.connect('listChange', this, this.listChange)
+                    if (this.canvasID != `canvas${this.id}`) {
+                        this.canvasID = `canvas${this.id}`
+                    }
+                    this.getGraphDetail().then((res) => {
+                        if (res.Content.length == 1) {
+                            const data = res.Content[0]
+                            if (data.MaxY && data.MinX) {
+                                window.fengmapData.maxY = data.MaxY
+                                window.fengmapData.minX = data.MinX
+                            }
+                        }
+                        this.parserData(floorid)
+                    })
+                    // this.parserData(floorid);
+                } else if (this.haveFengMap == 0) {
+                    this.view.scene = this.scene
+                    this.readGraph()
+                } else {
+                    this.loading = false
+                }
+            }, 100)
+        },
+        parserData(floor) {
+            if (floor == 'g80') {
+                // 屋顶
+                if (window.fengmapData.frImg) {
+                    const pj = this.fmapID.split('_')[0]
+                    // 单张图片
+                    if (!ProjectRf[pj]) {
+                        let imgItem = new SImageItem(null, `${this.mapServerURL}/webtheme/${this.fmapID}/${window.fengmapData.frImg}`)
+                        imgItem.showType = SImageShowType.AutoFit
+                        imgItem.connect('imgLoadOver', this, () => {
+                            this.readGraph()
+                        })
+                        this.scene.addItem(imgItem)
+                        this.view.scene = this.scene
+                        // this.view.fitSceneToView()
+                    } else {
+                        // 多张图
+                        try {
+                            // 初始化0
+                            this.count = 0
+                            ProjectRf[pj].forEach((t) => {
+                                const item = new SImageItem(null, `${this.mapServerURL}/webtheme/${this.fmapID}/${t.name}`)
+                                item.width = t.width
+                                item.height = t.height
+                                item.moveTo(t.x, t.y)
+                                item.connect('imgLoadOver', this, () => {
+                                    this.countRf(ProjectRf[pj].length)
+                                })
+                                this.scene.addItem(item)
+                            })
+                            this.view.scene = this.scene
+                        } catch (e) {
+                            console.log(e)
+                        }
+                    }
+                } else {
+                    // 屋顶图不为图片
+                    this.readBaseMap(floor)
+                }
+            } else {
+                if (window.fengmapData.gnameToGid[floor]) {
+                    this.readBaseMap(floor)
+                } else {
+                    console.log('楼层不正确')
+                }
+            }
+        }, // 解析底图
+        // 解析楼地板
+        loadBoard(floor) {
+            window.fengmapData.loadFloor(floor, (res) => {
+                const zone = new SBoardItem(null, res)
+                this.scene.addItem(zone)
+            })
+        },
+        readBaseMap(floor) {
+            this.loadBoard(window.fengmapData.gnameToGid[floor])
+            window.fengmapData.parseData(window.fengmapData.gnameToGid[floor], (res) => {
+                if (res.err) {
+                    console.log('errr', res.err)
+                    return
+                }
+                this.fParser = new SFloorParser(null)
+                this.fParser.parseData(res)
+                this.fParser.spaceList.forEach((t) => {
+                    this.scene.addItem(t)
+                    t.nameSize = 12
+                    t.nameColor = '#2a2a2a';
+                    if (t.data.Name && this.bunkObj[t.data.Name]) {
+                        t.name = this.bunkObj[t.data.Name].brandname
+                    } else {
+                        // t.name = t.data.Name
+                        t.name = ''
+                    }
+                })
+                this.fParser.wallList.forEach((t) => this.scene.addItem(t))
+                this.fParser.virtualWallList.forEach((t) => this.scene.addItem(t))
+                this.fParser.doorList.forEach((t) => this.scene.addItem(t))
+                this.fParser.columnList.forEach((t) => this.scene.addItem(t))
+                this.fParser.casementList.forEach((t) => this.scene.addItem(t))
+                this.view.scene = this.scene
+                // this.view.fitSceneToView()
+                this.readGraph()
+            })
+        },
+        readGraph() {
+            this.readGroup(this.floorid)
+                .then((data) => {
+                    if (data.Result == 'failure') {
+                        this.$store.commit('SETISMESSAGE', false)
+                        this.view.fitSceneToView()
+                        this.view.minScale = this.view.scale
+                        if (this.$refs.canvasFun) {
+                            this.$refs.canvasFun.everyScale = this.view.scale
+                        }
+                        this.loading = false
+                        return
+                    } else {
+                        if (
+                            data.Data[0].Elements.Nodes.length === 0 &&
+                            data.Data[0].Elements.Markers.length === 0 &&
+                            data.Data[0].Elements.Relations.length === 0
+                        ) {
+                            this.$store.commit('SETISMESSAGE', false)
+                        } else {
+                            this.$store.commit('SETISMESSAGE', true)
+                        }
+                    }
+                    // 无返回Data处理
+                    if (!(data.Data && data.Data.length)) {
+                        this.view.fitSceneToView()
+                        this.view.minScale = this.view.scale
+                        if (this.$refs.canvasFun) {
+                            this.$refs.canvasFun.everyScale = this.view.scale
+                        }
+                        return false
+                    }
+                    // 请求回来的备注
+                    if (data.Data && data.Data[0].Note) {
+                        let note = data.Data[0].Note
+                        bus.$emit('queryRemarksMethods', note)
+                    } else {
+                        bus.$emit('queryRemarksMethods', '')
+                    }
+                    //土建装饰的图例展示
+                    if (this.$cookie.get('categoryId') == 'SCPZ') {
+                        let scpzTable = [],
+                            arr = []
+                        scpzTable = data.Data[0].Elements.Nodes || []
+                        console.log(scpzTable)
+                        if (scpzTable.length > 0) {
+                            scpzTable.forEach((e) => {
+                                if (e.Properties.ItemExplain) {
+                                    let obj = e
+                                    arr.push(obj)
+                                }
+                            })
+                        }
+                        console.log(arr)
+                        this.$store.commit('SETSCPZTABLE', arr)
+                    }
+                    if (data.Data[0].Elements.Nodes.length > 0) {
+                        this.$store.commit('SETTYPENUM', '')
+                        let Lengd = data.Data[0].Elements.Nodes
+                        Lengd.forEach((el) => {
+                            if (el.Type == 'Image' && el.Num > 1) {
+                                console.log(el.Num)
+                                this.$store.commit('SETTYPENUM', el.Num)
+                            }
+                        })
+                    }
+                    // 放到后边 $cookie graphId
+                    this.$cookie.set('graphId', data.Data[0].ID, 3)
+                    if (this.$cookie.get('graphId')) {
+                        // 得到graphId 就请求图例
+                        // 除土建装饰之外的图例展示 包括楼层功能
+                        bus.$emit('queryViewMethods')
+                    }
+                     // 改变底图演示
+                    ItemColor.spaceColor = new SColor('#0C102C')
+                    this.topologyParser = new STopologyParser(null)
+                    this.topologyParser.parseData(data.Data[0].Elements)
+                    // 多边形
+                    this.topologyParser.zoneLegendList.forEach((t) => {
+                        this.scene.addItem(t)
+                        t.connect('legendItemClick', t, this.handleClickLegendItem)
+                    })
+                    // 增加文字
+                    this.topologyParser.textMarkerList.forEach((t) => {
+                        this.scene.addItem(t)
+                    })
+                    // 增加图片
+                    this.topologyParser.imageMarkerList.forEach((t) => {
+                        this.scene.addItem(t)
+                    })
+                    // 增加直线
+                    this.topologyParser.lineMarkerList.forEach((t) => {
+                        this.scene.addItem(t)
+                    })
+                    // 增加图标类图例
+                    this.topologyParser.imageLegendList.forEach((t) => {
+                        t.textItem.color = new SColor('#ffffff')
+                        this.scene.addItem(t)
+                        t.connect('legendItemClick', t, this.handleClickLegendItem)
+                    })
+                    // 增加管线类
+                    // 增加图标类图例
+                    this.topologyParser.relationList.forEach((t) => {
+                        t.selectable = true
+                        this.scene.addItem(t)
+                        t.connect('legendItemClick', t, this.handleClickLegendItem)
+                    })
+                    this.view.fitSceneToView()
+                    this.view.minScale = this.view.scale
+                    if (this.$refs.canvasFun) {
+                        this.$refs.canvasFun.everyScale = this.view.scale
+                    }
+                    this.loading = false
+                })
+                .catch(() => {
+                    this.loading = false
+                })
+        },
+        // 顶楼为多张图时计数器
+        countRf(len) {
+            this.count++
+            if (len == this.count) {
+                this.readGraph()
+            } else {
+                console.log('所有图片未加载完成')
+            }
+        },
+        clearGraphy() {
+            if (this.view) {
+                this.view.scene = null
+                return
+            }
+            this.view = new FloorView(`canvas${this.id}`)
+        },
+        listChange(item, ev) {
+            // if (ev[0].length) {
+            //     let selectItem1 = ev[0][0],
+            //         location = selectItem1.data.AttachObjectIds[0] ? selectItem1.data.AttachObjectIds[0].id : ''
+            //     // 空间类型都可打开弹窗(除防火分区 编号100131,商管办公室 编号100112,铺装石材 编号100129)
+            //     if (selectItem1.data.GraphElementType == 'Zone') {
+            //         if (
+            //             selectItem1.data.GraphElementId != '100131' &&
+            //             selectItem1.data.GraphElementId != '100112' &&
+            //             selectItem1.data.GraphElementId != '100129'
+            //         ) {
+            //             if (location) {
+            //                 this.$refs.boxRoom.open({ name: selectItem1.name, type: this.type, location: location })
+            //             }
+            //         }
+            //     }
+            //     // // 选中电井设置电井关联的商铺高亮
+            //     // this.setHightLight(ev[0])
+            // }
+            // else {
+            // this.clearHightLight()
+            // }
+            if (ev[0].length) {
+                if (!(ev[0][0] instanceof SPolygonItem || ev[0][0] instanceof TipelineItem || ev[0][0] instanceof SImageLegendItem)) {
+                    this.visible = false
+                }
+            } else {
+                this.visible = false
+            }
+            this.clearHightLight()
+        },
+        // 选中电井关联的商铺高亮
+        setHightLight(arr) {
+            this.clearHightLight()
+            arr.forEach((item) => {
+                let location = item.data.AttachObjectIds[0] ? item.data.AttachObjectIds[0].id : ''
+                // 添加了位置类型并且选中的类型为电井类型
+                if (
+                    (item.data.GraphElementId == '100050' ||
+                        item.data.GraphElementId == '100055' ||
+                        item.data.GraphElementId == '100056' ||
+                        item.data.GraphElementId == '100057') &&
+                    location
+                ) {
+                    if (this.wellMap.hasOwnProperty(location)) {
+                        this.wellMap[location].forEach((item) => {
+                            item.highLightFlag = true
+                            item.zOrder = 30
+                        })
+                    } else {
+                        let getParams = {
+                            plazaId: this.plazaId,
+                            floor: this.floorid,
+                            keyword: `${location}:wellnum;`,
+                        }
+                        queryShops({ getParams }).then((res) => {
+                            let shopsnumList = []
+                            let shopsnumItemList = []
+                            if (res.data && res.data.length) {
+                                for (let floor in res.data[0]) {
+                                    if (res.data[0][floor].length) {
+                                        res.data[0][floor].forEach((v) => {
+                                            shopsnumList = shopsnumList.concat(v.shopsnumList.split(','))
+                                        })
+                                    }
+                                }
+                            }
+                            if (shopsnumList.length) {
+                                this.fParser.spaceList.forEach((item) => {
+                                    if (shopsnumList.findIndex((name) => name == item.data.Name) != -1) {
+                                        item.highLightFlag = true
+                                        item.zOrder = 30
+                                        shopsnumItemList.push(item)
+                                    }
+                                })
+                                this.wellMap[location] = shopsnumItemList
+                            }
+                        })
+                    }
+                }
+            })
+        },
+        // 清除电井关联商铺的高亮状态
+        clearHightLight() {
+            ItemColor.spaceHighColor = new SColor('#FBF2CC')
+            // for (let key in this.wellMap) {
+            //     this.wellMap[key].forEach((item) => {
+            //         item.highLightFlag = false
+            //         item.zOrder = ItemOrder.spaceOrder
+            //     })
+            // }
+            this.fParser.spaceList.forEach((item) => {
+                item.highLightFlag = false
+                item.zOrder = ItemOrder.spaceOrder
+            })
+        },
+        // 适配底图到窗口
+        fit() {
+            this.view.fitSceneToView()
+        },
+        // 保存为png
+        savePng() {
+            // this.view.saveImage(`${this.loadName}.png`, 'png')
+            this.view.saveImageSize(`${this.loadName}.png`, 'png', 1920 * 2, 1080 * 2)
+            //console.log(`${this.loadName}.png`)
+        },
+        // 保存为svg
+        saveSvg() {
+            this.view.saveSceneSvg(`${this.loadName}.svg`, 6400, 4800)
+        },
+        // 保存为json
+        saveJson() {
+            this.view.saveFloorJson(`${this.loadName}.json`)
+        },
+        // 缩放
+        scale(val) {
+            if (!this.view) {
+                return
+            }
+            let scale = this.view.scale
+            this.view.scaleByPoint(val / scale, this.canvasWidth / 2, this.canvasHeight / 2)
+        },
+        // 小眼睛控制显示铺位名称
+        showText(val) {
+            // this.topologyParser.zoneLegendList.forEach(t => {
+            //     t.showText = val
+            // })
+            this.fParser.spaceList.forEach((t) => {
+                t.showBaseName = val
+            })
+        },
+        // 读取数据
+        readGroup(FloorID) {
+            const data = {
+                BuildingID: '1',
+                FloorID: FloorID,
+                categoryId: this.categoryId ? this.categoryId : this.$cookie.get('categoryId'),
+                projectId: this.urlMsg.ProjectID,
+                Pub: true,
+            }
+            return readGroup(data)
+        },
+        // 获取图最大最小值
+        getGraphDetail() {
+            const categoryId = this.categoryId ? this.categoryId : this.$cookie.get('categoryId')
+            const data = {
+                Filters: `categoryId='${categoryId}';projectId='${this.urlMsg.ProjectID}';BuildingID='1';FloorID='${this.floorid}';isPub=true`,
+            }
+            return graphQuery(data)
+        },
+        // 地图尺寸
+        mapSize() {
+            this.canvasWidth = this.$refs.graphycolor.offsetWidth
+            if (window.screen.height == '768') {
+                this.canvasHeight = this.$refs.graphycolor.offsetHeight - 100
+            } else {
+                this.canvasHeight = 570
+            }
+            // 弹窗中底图高度适配
+            if (this.modalHeight) {
+                this.canvasHeight = this.modalHeight
+            }
+        },
+        getEvent() {
+            bus.$on('changeShow', (res) => {
+                this.topologyParser &&
+                    this.topologyParser.zoneLegendList.forEach((t) => {
+                        let id = t.data.GraphElementId
+                        t.maskFlag = !(res.indexOf(id) > -1)
+                    })
+                // this.topologyParser.textMarkerList.forEach(t => {
+                //     let id = t.data.GraphElementId
+                //     t.maskFlag = !(res.indexOf(id) > -1)
+                // })
+                // this.topologyParser.imageMarkerList.forEach(t => {
+                //     let id = t.data.GraphElementId
+                //     t.maskFlag = !(res.indexOf(id) > -1)
+                // })
+                // this.topologyParser.lineMarkerList.forEach(t => {
+                //     let id = t.data.GraphElementId
+                //     t.maskFlag = !(res.indexOf(id) > -1)
+                // })
+                this.topologyParser &&
+                    this.topologyParser.imageLegendList.forEach((t) => {
+                        let id = t.data.GraphElementId
+                        t.maskFlag = !(res.indexOf(id) > -1)
+                    })
+                this.topologyParser &&
+                    this.topologyParser.relationList.forEach((t) => {
+                        let id = t.data.GraphElementId || t.data.GraphElementID
+                        t.maskFlag = !(res.indexOf(id) > -1)
+                    })
+            })
+        },
+        /**
+         * @description 处理popover显隐
+         * 当点击位置不在canvas内部时 ( 如点击 页面空白,图例,楼层,设备设施左侧列表项时),将visible置为false,隐藏popover
+         */
+        handlePopover(e) {
+            this.$nextTick(() => {
+                if (!this.$refs.graphycolor.contains(e.target)) {
+                    this.visible = false
+                }
+                this.showStatusText = false
+                this.statusText = ''
+                // 关闭message提示
+                if (this.message) {
+                    this.message.close()
+                    this.message = null
+                }
+            })
+        },
+        /**
+         * @description 设备状态列, 状态为停用或已拆除时,样式红色
+         */
+        tableCellClassName({ row, column, rowIndex, columnIndex }) {
+            if (columnIndex === 2 && this.statusDisabled.includes(row.sb_status)) {
+                return 'status-disabled'
+            }
+        },
+    },
+    watch: {
+        'view.scale': {
+            handler(n) {
+                if (this.$refs.canvasFun) {
+                    let s = (n * 10) / this.view.minScale
+                    this.$refs.canvasFun.sliderVal = s > 1000 ? 1000 : s
+                }
+            },
+        },
+        haveFengMap() {
+            this.init(this.floorid)
+        },
+    },
+    mounted() {
+        this.mapSize()
+        this.getEvent()
+        // 添加监听点击事件,处理popover显隐
+        window.addEventListener('click', this.handlePopover, false)
+        this.$once('hook:beforeDestroy', () => {
+            window.removeEventListener('click', this.handlePopover)
+        })
+    },
+    created() {
+        // document.addEventListener("mousedown", () => {
+        //     this.visible = false;
+        // })
+        this.urlMsg = {
+            categoryId: this.$cookie.get('categoryId'),
+            ProjectID: this.plazaId,
+            BuildingID: '1',
+            FloorID: this.$cookie.get('floorMapId') || 'f1',
+            fmapID: this.fmapID,
+        }
+    },
+}
+</script>
+<style lang="less" scoped>
+#floor_base {
+    position: relative;
+    height: 100%;
+    .fengMap {
+        position: fixed;
+        width: 100px;
+        height: 100px;
+        z-index: -1;
+    }
+    .strip-bottom {
+        position: absolute;
+        right: 0;
+        bottom: 40px;
+        width: 100%;
+    }
+    .popStyle {
+        position: fixed;
+    }
+}
+</style>
+<style lang="less">
+a:hover {
+    text-decoration: none;
+}
+.el-popover {
+    .el-table {
+        tr {
+            .equip-detail-btn {
+                display: none;
+            }
+        }
+        tr:hover {
+            cursor: pointer;
+            .equip-detail-btn {
+                cursor: pointer;
+                display: inline-block;
+                color: #025baa;
+            }
+        }
+    }
+    .pointList {
+        max-height: 235px;
+        overflow-y: auto;
+        text-align: right;
+        li {
+            height: 38px;
+            line-height: 38px;
+            padding: 0 12px;
+            cursor: pointer;
+            border-bottom: 1px solid rgba(0, 0, 0, 0.06);
+            span {
+                float: left;
+                width: 260px;
+                text-align: left;
+                overflow: hidden;
+                text-overflow: ellipsis;
+                white-space: nowrap;
+            }
+            a {
+                display: none;
+                color: #025baa;
+                font-size: 13px;
+            }
+        }
+        li:hover {
+            background-color: #f5f6f7;
+            a {
+                display: inline-block;
+            }
+        }
+    }
+    .el-button--primary {
+        background: linear-gradient(180deg, #369cf7 0%, #025baa 100%);
+    }
+    .el-tabs--bottom .el-tabs__item.is-bottom:nth-child(2),
+    .el-tabs--bottom .el-tabs__item.is-top:nth-child(2),
+    .el-tabs--top .el-tabs__item.is-bottom:nth-child(2),
+    .el-tabs--top .el-tabs__item.is-top:nth-child(2) {
+        padding-left: 16px;
+    }
+    .el-tabs--bottom .el-tabs__item.is-bottom:last-child,
+    .el-tabs--bottom .el-tabs__item.is-top:last-child,
+    .el-tabs--top .el-tabs__item.is-bottom:last-child,
+    .el-tabs--top .el-tabs__item.is-top:last-child {
+        padding-right: 16px;
+    }
+    .el-tabs__nav-wrap::after {
+        height: 0;
+    }
+    .is-active {
+        color: #025baa !important;
+        border-color: #025baa !important;
+        background: rgba(2, 91, 170, 0.15);
+    }
+    .el-tabs__item {
+        padding: 5px 16px;
+        height: 30px;
+        line-height: 20px;
+        font-size: 14px;
+        font-family: MicrosoftYaHei;
+        color: rgba(31, 36, 41, 1);
+        border: 1px solid rgba(195, 199, 203, 1);
+    }
+    .el-tabs__active-bar {
+        background-color: transparent !important;
+    }
+    /deep/ .el-tabs__item:last-child {
+        border-radius: 0px 4px 4px 0px;
+    }
+    /deep/ .el-tabs__item:nth-child(2) {
+        border-radius: 4px 0px 0px 4px;
+    }
+    // 设备状态
+    .status-disabled {
+        color: #c0c4cc !important;
+        text-decoration: line-through;
+    }
+}
+// 警告message样式修改
+.floor-map-warning {
+    background-color: #ffa53d;
+    color: #fff;
+    font-size: 14px;
+    /deep/ .el-icon-warning-outline {
+        font-weight: 600 !important;
+        margin-right: 5px;
+    }
+    /deep/.el-icon-close {
+        color: #fff;
+        opacity: 0.5;
+    }
+}
+</style>

+ 1 - 1
src/components/floorMap/index.vue

@@ -235,7 +235,7 @@ export default {
                 })
             }
         },
-        // 查看浮层设备详情 
+        // 查看浮层设备详情
         handleClickEquipDetail: debounce(function (row, column, event) {
             // 设备状态为停用或已拆除时,弹出消息
             if (this.statusDisabled.includes(row?.sb_status)) {

+ 392 - 288
src/components/menuList.vue

@@ -1,318 +1,422 @@
 <template>
-    <!-- 顶部路由 -->
-    <div class='menu'>
-        <div class='home' @click='$emit("update:modelNum", 0)'>
-            <div class='downright'></div>
-            <div class='home-box'>
-                <img src='@/assets/imgs/logo.png' alt />
-                <span>{{plazaName||'万达集团'}}</span>
-                <!-- <span v-if='plazas'>{{plazas.length>0?formatter(plazaId,plazas):'--'}}</span> -->
-            </div>
-        </div>
-        <div>
-            <div
-                v-for='(item, index) in list'
-                :key='index'
-                :class='{ "is-active": item.state }'
-                @click='clickEventAcitve(item, index)'
-            >{{ item.name }}</div>
-        </div>
-        <div class='home-right'>
-            <span @click='dumpLegend' v-show="permissions ? permissions.includes('GLSMS_SYMBOL_MANAGE'):false">
-                <img class='img1' src='../assets/imgs/scj.png' alt />
-                <span class='span1'>图例库</span>
-            </span>
+  <!-- 顶部路由 -->
+  <div :class="['menu', showStyle ? 'menu-style' : '']">
+    <div
+      :class="['home', showStyle ? 'home-style' : '']"
+      @click="$emit('update:modelNum', 0)"
+    >
+      <div class="downright"></div>
+      <div class="home-box">
+        <img v-if="!showStyle" src="@/assets/imgs/logo.png" alt />
+        <img v-else src="@/assets/imgs/logo1.png" alt="" />
+        <span>{{ plazaName || "万达集团" }}</span>
+        <!-- <span v-if='plazas'>{{plazas.length>0?formatter(plazaId,plazas):'--'}}</span> -->
+      </div>
+    </div>
+    <div v-if="!showStyle" class="btnlist">
+      <div
+        v-for="(item, index) in list"
+        :key="index"
+        :class="{ 'is-active': item.state }"
+        @click="clickEventAcitve(item, index)"
+      >
+        {{ item.name }}
+      </div>
+    </div>
+    <div v-else class="btnlist-style">
+      <div
+        v-for="(item, index) in list"
+        :key="index"
+        :class="{ 'is-active': item.state }"
+        @click="clickEventAcitve(item, index)"
+      >
+        {{ item.name }}
+      </div>
+    </div>
+    <div class="home-right">
+      <span
+        @click="dumpLegend"
+        v-show="
+          permissions ? permissions.includes('GLSMS_SYMBOL_MANAGE') : false
+        "
+      >
+        <img class="img1" src="../assets/imgs/scj.png" alt />
+        <span class="span1">图例库</span>
+      </span>
 
-            <span @click='toDrafts' class='span-out' v-show="permissions ? permissions.includes('GLSMS_PLANARGRAPH_MANAGE'):false">
-                <img class='img2' src='../assets/imgs/cgx.png' alt />
-                <span class='span2'>草稿箱</span>
-                <span class='span2-num' v-if='draftNum && draftNum <= 99'>{{draftNum}}</span>
-                <span class='span2-num' style='line-height:10px' v-else-if='draftNum && draftNum > 99'>...</span>
-            </span>
-            <span>
-                <img class='img3' src='../assets/imgs/clock.png' alt />
-                <span class='span3'>{{times}}</span>
-            </span>
-            <span>
-                切换
-                <!-- <img class='img3' src='../assets/images/change.png' alt /> -->
-            </span>
-        </div>
+      <span
+        @click="toDrafts"
+        class="span-out"
+        v-show="
+          permissions ? permissions.includes('GLSMS_PLANARGRAPH_MANAGE') : false
+        "
+      >
+        <img class="img2" src="../assets/imgs/cgx.png" alt />
+        <span class="span2">草稿箱</span>
+        <span class="span2-num" v-if="draftNum && draftNum <= 99">{{
+          draftNum
+        }}</span>
+        <span
+          class="span2-num"
+          style="line-height: 10px"
+          v-else-if="draftNum && draftNum > 99"
+          >...</span
+        >
+      </span>
+      <span>
+        <img class="img3" src="../assets/imgs/clock.png" alt />
+        <span class="span3">{{ times }}</span>
+      </span>
+      <span v-show="showStyleBtn" @click="checkColor">
+        切换
+        <!-- <img class='img3' src='../assets/images/change.png' alt /> -->
+      </span>
     </div>
+  </div>
 </template>
 
 <script>
-import { formatTime } from '@/utils/format.js'
-import { mapGetters } from 'vuex'
-import moment from 'moment'
-import { queryDraftNum } from '../../src/api/public'
-import store from '../store'
+import { formatTime } from "@/utils/format.js";
+import { mapGetters } from "vuex";
+import moment from "moment";
+import { queryDraftNum } from "../../src/api/public";
+import store from "../store";
+import bus from "@/utils/bus.js";
 export default {
-    data() {
-        return {
-            state: '',
-            list: [
-                { name: '首页', state: false, route: 'homepage' },
-                { name: '项目概况', state: false, route: 'overview' },
-                { name: '楼层功能', state: false, route: 'floorFunc' }, //楼层功能
-                { name: '设备设施', state: false, route: 'equipment' }, //设备设施
-                { name: '其他事项', state: false, route: 'other' }, //其他
-                { name: '分析|报表', state: false, route: 'analysis' }
-            ],
-            times: `${new Date().getFullYear()}.${formatTime(new Date().getMonth() + 1)}.${formatTime(new Date().getDate())} ${formatTime(
-                new Date().getHours()
-            )}:${formatTime(new Date().getMinutes())}`,
-            draftNum: null, //草稿箱数量
-            interval: 10 * 60 * 1000, //定时器时长,默认 10分钟
-            timer: null, //保存定时器
-            // 路由词典
-            dict: {
-                homepage: 1,
-                overview: 2,
-                floorFunc: 3,
-                equipment: 4,
-                other: 5,
-                analysis: 6
-            }
-        }
+  data() {
+    return {
+      state: "",
+      list: [
+        { name: "首页", state: false, route: "homepage" },
+        { name: "项目概况", state: false, route: "overview" },
+        { name: "楼层功能", state: false, route: "floorFunc" }, //楼层功能
+        { name: "设备设施", state: false, route: "equipment" }, //设备设施
+        { name: "其他事项", state: false, route: "other" }, //其他
+        { name: "分析|报表", state: false, route: "analysis" },
+      ],
+      times: `${new Date().getFullYear()}.${formatTime(
+        new Date().getMonth() + 1
+      )}.${formatTime(new Date().getDate())} ${formatTime(
+        new Date().getHours()
+      )}:${formatTime(new Date().getMinutes())}`,
+      draftNum: null, //草稿箱数量
+      interval: 10 * 60 * 1000, //定时器时长,默认 10分钟
+      timer: null, //保存定时器
+      // 路由词典
+      dict: {
+        homepage: 1,
+        overview: 2,
+        floorFunc: 3,
+        equipment: 4,
+        other: 5,
+        analysis: 6,
+      },
+      //   是否显示暗色样式
+      showStyle: false,
+      // 是否展示切换按钮
+      showStyleBtn: false,
+    };
+  },
+  computed: {
+    ...mapGetters(["plazas", "plazaId", "fmapID", "plazaName", "permissions"]),
+  },
+  watch: {
+    $route: "handleRoute",
+  },
+  created() {
+    this.currentTime();
+    // 如果为首页显示转换风格按钮
+    if (this.$route.fullPath == "/home/homepage") {
+      this.showStyleBtn = true;
+    }
+  },
+  mounted() {
+    this.handleRoute(this.$route);
+    // console.log(this.fmapID)
+    // 定时查询草稿箱数量
+    this.getDraftNum(); //首次查询
+    this.timer = setInterval(() => {
+      this.getDraftNum();
+    }, this.interval);
+    // 页面销毁前,清除定时器
+    this.$once("hook:beforeDestroy", () => {
+      clearInterval(this.timer);
+    });
+    console.log("permissions", this.permissions);
+  },
+  methods: {
+    /**
+     * @name getDraftNum
+     * @description 查询草稿箱数量
+     */
+    async getDraftNum() {
+      let res = null,
+        data = {
+          Distinct: true,
+          Filters: `projectId='${this.plazaId}';isPub=false`,
+          PageNumber: 1,
+          PageSize: 500,
+          Projection: ["floorId"],
+        };
+      try {
+        // 调用接口
+        res = await queryDraftNum(data);
+      } catch (error) {
+        console.error(error);
+      }
+      if (!res) {
+        this.draftNum = null;
+        return false;
+      }
+      // 草稿箱总条数使用 res.Total, 不使用 Content数组的长度
+      this.draftNum = res.Total || null;
     },
-    computed: {
-        ...mapGetters(['plazas', 'plazaId', 'fmapID', 'plazaName','permissions'])
+    //入草稿箱
+    toDrafts() {
+      const { conf } = window.__systemConf;
+      // { editerUrl } = conf;
+      if (!this.plazaId) {
+        return;
+      }
+      const editerUrl = conf[process.env.NODE_ENV + "_editerUrl"];
+      let data = `projectId=${this.plazaId}&fmapID=${this.fmapID}&token=${this.$store.state.ssoToken}`;
+      let url = editerUrl + "drafts?" + encodeURIComponent(data);
+      window.open(url, "drafts");
     },
-    watch: {
-        $route: 'handleRoute'
+    currentTime() {
+      this.times = moment().format("YYYY.MM.DD HH:mm");
+      setTimeout(this.currentTime, 1000);
     },
-    created() {
-        this.currentTime()
+    handleRoute(newRouter) {
+      if (!newRouter) {
+        return false;
+      }
+      const { path } = newRouter;
+      let router = path.split("home/")[1];
+      this.modelNum(this.dict[router]);
     },
-    mounted() {
-        this.handleRoute(this.$route)
-        // console.log(this.fmapID)
-        // 定时查询草稿箱数量
-        this.getDraftNum() //首次查询
-        this.timer = setInterval(() => {
-            this.getDraftNum()
-        }, this.interval)
-        // 页面销毁前,清除定时器
-        this.$once('hook:beforeDestroy', () => {
-            clearInterval(this.timer)
-        });
-        console.log('permissions',this.permissions)
+    formatter(str, arrv) {
+      if (str && arrv) {
+        const Objs = arrv.find((e) => e && e.plazaid == str);
+        return Objs ? Objs.plazaname : "--";
+      } else {
+        return "";
+      }
     },
-    methods: {
-        /**
-         * @name getDraftNum
-         * @description 查询草稿箱数量
-         */
-        async getDraftNum() {
-            let res = null,
-                data = {
-                    Distinct: true,
-                    Filters: `projectId='${this.plazaId}';isPub=false`,
-                    PageNumber: 1,
-                    PageSize: 500,
-                    Projection: ['floorId']
-                }
-            try {
-                // 调用接口
-                res = await queryDraftNum(data)
-            } catch (error) {
-                console.error(error)
-            }
-            if (!res) {
-                this.draftNum = null
-                return false
-            }
-            // 草稿箱总条数使用 res.Total, 不使用 Content数组的长度
-            this.draftNum = res.Total || null
-        },
-        //入草稿箱
-        toDrafts() {
-            const { conf } = window.__systemConf
-            // { editerUrl } = conf;
-            if(!this.plazaId){
-                return
-            }
-            const editerUrl = conf[process.env.NODE_ENV + '_editerUrl']
-            let data = `projectId=${this.plazaId}&fmapID=${this.fmapID}&token=${this.$store.state.ssoToken}`
-            let url = editerUrl + 'drafts?' + encodeURIComponent(data)
-            window.open(url, "drafts")
-        },
-        currentTime() {
-            this.times = moment().format('YYYY.MM.DD HH:mm')
-            setTimeout(this.currentTime, 1000)
-        },
-        handleRoute(newRouter) {
-            if (!newRouter) {
-                return false
-            }
-            const { path } = newRouter
-            let router = path.split('home/')[1]
-            this.modelNum(this.dict[router])
-        },
-        formatter(str, arrv) {
-            if (str && arrv) {
-                const Objs = arrv.find(e => e && e.plazaid == str)
-                return Objs ? Objs.plazaname : '--'
-            } else {
-                return ''
-            }
-        },
-        modelNum(val) {
-            this.list = this.list.map((item, index) => {
-                if (val == index + 1) {
-                    item.state = true
-                } else {
-                    item.state = false
-                }
-                return item
-            })
-        },
-        clickEventAcitve(item) {
-            if (item.name == '楼层功能') {
-                this.$cookie.set('categoryId', 'LCGN', 3)
-                store.commit('SETCATEGORYID', 'LCGN')
-            } else {
-                this.$cookie.set('categoryId', 'GDXT', 3)
-                store.commit('SETCATEGORYID', 'GDXT')
-            }
-            this.list.forEach(ele => {
-                ele.state = false
-            })
-            item.state = true
-            this.state = item.state
-            this.$router.push({ path: `/home/${item.route}` })
-        },
-
-        dumpLegend() {
-            const { conf } = window.__systemConf;
-            const wandaBmGuideUrl = conf[process.env.NODE_ENV + '_wandaBmGuideUrl']
-            window.open(`${wandaBmGuideUrl}home/legendLibrary?token=${this.$store.state.ssoToken}`, "legendLibrary")
+    modelNum(val) {
+      this.list = this.list.map((item, index) => {
+        if (val == index + 1) {
+          item.state = true;
+        } else {
+          item.state = false;
         }
-    }
-}
+        return item;
+      });
+    },
+    clickEventAcitve(item) {
+      if (item.name == "楼层功能") {
+        this.$cookie.set("categoryId", "LCGN", 3);
+        store.commit("SETCATEGORYID", "LCGN");
+      } else {
+        this.$cookie.set("categoryId", "GDXT", 3);
+        store.commit("SETCATEGORYID", "GDXT");
+      }
+      this.list.forEach((ele) => {
+        ele.state = false;
+      });
+      item.state = true;
+      this.state = item.state;
+      this.$router.push({ path: `/home/${item.route}` });
+      //   是否显示切换按钮
+      if (item.route == "homepage") {
+        this.showStyleBtn = true;
+      } else {
+        this.showStyleBtn = false;
+        this.showStyle = false;
+      }
+    },
+
+    dumpLegend() {
+      const { conf } = window.__systemConf;
+      const wandaBmGuideUrl = conf[process.env.NODE_ENV + "_wandaBmGuideUrl"];
+      window.open(
+        `${wandaBmGuideUrl}home/legendLibrary?token=${this.$store.state.ssoToken}`,
+        "legendLibrary"
+      );
+    },
+    // 切换风格
+    checkColor() {
+      this.showStyle = !this.showStyle;
+      //   改变颜色风格
+      bus.$emit("changeStyleColor", this.showStyle);
+    },
+  },
+};
 </script>
 
 <style scoped lang="less">
 .menu {
+  height: 48px;
+  min-width: 1366px;
+  color: #1f2429;
+  font-size: 16px;
+  background: rgba(255, 255, 255, 1);
+  box-shadow: 0px 2px 10px 0px rgba(31, 35, 41, 0.1);
+  // overflow: hidden;
+  .home {
+    min-width: 265px;
+    max-width: 350px;
     height: 48px;
-    min-width: 1366px;
-    color: #1f2429;
-    font-size: 16px;
-    background: rgba(255, 255, 255, 1);
-    box-shadow: 0px 2px 10px 0px rgba(31, 35, 41, 0.1);
-    // overflow: hidden;
-    .home {
-        min-width: 265px;
-        max-width: 320px;
-        height: 48px;
-        // line-height: 48px;
-        text-align: center;
-        cursor: pointer;
-        color: #ffffff;
-        float: left;
-        margin-right: 83px;
-        // background: linear-gradient(180deg, rgba(54, 156, 247, 1) 0%, rgba(2, 91, 170, 1) 100%);
-        background: linear-gradient(180deg, rgba(54, 156, 247, 1) 0%, rgba(2, 91, 170, 1) 100%);
-        position: relative;
-        .downright {
-            position: absolute;
-            width: 0;
-            height: 0;
-            border-left: 20px solid transparent;
-            border-bottom: 48px solid #fff;
-            right: 0px;
-            top: 0;
-        }
-        .home-box {
-            height: 100%;
-            display: flex;
-            align-items: center;
-            img {
-                width: 28px;
-                height: 28px;
-                margin-left: 20px;
-                margin-right: 24px;
-                margin-top: -3px;
-            }
-            span {
-                font-size: 20px;
-                font-family: MicrosoftYaHei;
-                height: 27px;
-                line-height: 27px;
-                margin-top: -4px;
-                &:after {
-                    content: '|';
-                    position: absolute;
-                    left: 60px;
-                }
-            }
-        }
-    }
-    & > div:nth-of-type(2) {
-        & > div {
-            line-height: 48px;
-            text-align: center;
-            //background: url('../assets/images/topbar1.png') no-repeat;
-            float: left;
-            width: 88px;
-            height: 48px;
-            margin: 0 8px;
-            cursor: pointer;
-            transition: all 0.2s;
-        }
-        .is-active {
-            color: #025baa;
-            font-weight: bolder;
-            border-bottom: 2px solid #025baa;
-            background: linear-gradient(180deg, rgba(2, 91, 170, 0) 0%, rgba(2, 91, 170, 0.2) 100%);
-        }
+    // line-height: 48px;
+    text-align: center;
+    cursor: pointer;
+    color: #ffffff;
+    float: left;
+    margin-right: 83px;
+    // background: linear-gradient(180deg, rgba(54, 156, 247, 1) 0%, rgba(2, 91, 170, 1) 100%);
+    background: linear-gradient(
+      180deg,
+      rgba(54, 156, 247, 1) 0%,
+      rgba(2, 91, 170, 1) 100%
+    );
+    position: relative;
+    .downright {
+      position: absolute;
+      width: 0;
+      height: 0;
+      border-left: 20px solid transparent;
+      border-bottom: 48px solid #fff;
+      right: 0px;
+      top: 0;
     }
-    .home-right {
-        float: right;
-        margin-right: 20px;
-        line-height: 48px;
-        color: #646c73;
-        font-size: 14px;
-        cursor: pointer;
-        display: flex;
-        align-content: center;
-        img {
-            margin-top: -2px;
-        }
-        .span-out {
-            position: relative;
-            margin: 0 16px;
-            .span2-num {
-                position: absolute;
-                right: -5px;
-                top: 5px;
-                display: inline-block;
-                width: 18px;
-                height: 18px;
-                background: red;
-                border-radius: 90px;
-                font-size: 12px;
-                text-align: center;
-                line-height: 16px;
-                color: #ffffff;
-            }
+    .home-box {
+      height: 100%;
+      display: flex;
+      align-items: center;
+      img {
+        width: 28px;
+        height: 28px;
+        margin-left: 20px;
+        margin-right: 24px;
+        margin-top: -3px;
+      }
+      span {
+        font-size: 20px;
+        font-family: MicrosoftYaHei;
+        height: 27px;
+        line-height: 27px;
+        margin-top: -4px;
+        &:after {
+          content: "|";
+          position: absolute;
+          left: 60px;
         }
+      }
     }
-    .span1,
-    .span2 {
-        padding: 0 6px 0 3px;
+  }
+  .home-style {
+    background: linear-gradient(180deg, #103979 0%, #162653 100%);
+    .downright {
+      position: absolute;
+      width: 0;
+      height: 0;
+      border-left: 20px solid transparent;
+      border-bottom: 48px solid #0c102c;
+      right: 0px;
+      top: 0;
     }
+  }
 
-    .span3 {
-        padding-left: 3px;
+  .btnlist {
+    & > div {
+      line-height: 48px;
+      text-align: center;
+      //background: url('../assets/images/topbar1.png') no-repeat;
+      float: left;
+      width: 88px;
+      height: 48px;
+      margin: 0 8px;
+      cursor: pointer;
+      transition: all 0.2s;
+    }
+    .is-active {
+      color: #025baa;
+      font-weight: bolder;
+      border-bottom: 2px solid #025baa;
+      background: linear-gradient(
+        180deg,
+        rgba(2, 91, 170, 0) 0%,
+        rgba(2, 91, 170, 0.2) 100%
+      );
+    }
+  }
+  .btnlist-style {
+    & > div {
+      line-height: 48px;
+      text-align: center;
+      background: url("../assets/imgs/btn-rect.png") no-repeat;
+      float: left;
+      width: 142px;
+      height: 48px;
+      margin: 0 8px;
+      cursor: pointer;
+      transition: all 0.2s;
+      color: #fff;
+    }
+    .is-active {
+      color: #95bfff;
+      font-weight: bolder;
+      background: url("../assets/imgs/btn-rect-active.png") no-repeat;
     }
+  }
+  .home-right {
+    float: right;
+    margin-right: 20px;
+    line-height: 48px;
+    color: #646c73;
+    font-size: 14px;
+    cursor: pointer;
+    display: flex;
+    align-content: center;
+    img {
+      margin-top: -2px;
+    }
+    .span-out {
+      position: relative;
+      margin: 0 16px;
+      .span2-num {
+        position: absolute;
+        right: -5px;
+        top: 5px;
+        display: inline-block;
+        width: 18px;
+        height: 18px;
+        background: red;
+        border-radius: 90px;
+        font-size: 12px;
+        text-align: center;
+        line-height: 16px;
+        color: #ffffff;
+      }
+    }
+  }
+  .span1,
+  .span2 {
+    padding: 0 6px 0 3px;
+  }
+
+  .span3 {
+    padding-left: 3px;
+  }
+}
+.menu-style {
+  background: #0c102c;
 }
 </style>
 <style lang="less">
 .menu {
-    .el-badge__content.is-fixed {
-        top: 10px;
-    }
+  .el-badge__content.is-fixed {
+    top: 10px;
+  }
 }
 </style>

+ 110 - 0
src/views/homepage/Circle.js

@@ -0,0 +1,110 @@
+/**
+ * 双环形图
+ *
+ * @author hanyaolong
+ */
+export class SCircle {
+
+    /**
+     * 构造函数
+     *
+     * @param {canvasid} id
+     */
+    constructor(id) {
+        const canvas = document.getElementById(id);
+        this.ctx = canvas.getContext("2d");
+        this.percent = 100;  //最终百分比
+        this.circleX = canvas.width / 2;  //中心x坐标
+        this.circleY = canvas.height / 2;  //中心y坐标
+        this.radius = 60; //圆环半径
+        this.lineWidth = 5;  //圆形线条的宽度
+        this.fontSize = 40; //字体大小
+    }
+
+    /**
+     * 绘制圆
+     *
+     * @param {x} cx
+     * @param {y} cy
+     * @param {半径} r
+     */
+    circle(cx, cy, r) {
+        this.ctx.beginPath();
+        this.ctx.lineWidth = this.lineWidth;
+        this.ctx.strokeStyle = '#2a4886';
+        this.ctx.arc(cx, cy, r, 0, (Math.PI * 2), true);
+        this.ctx.stroke();
+    }
+
+    /**
+     * 设置中心文字
+     *
+     * @param {文本} text
+     */
+    setText(text) {
+        this.ctx.beginPath();
+        //中间的字
+        this.ctx.font = this.fontSize + 'px April';
+        this.ctx.textAlign = 'center';
+        this.ctx.textBaseline = 'middle';
+        this.ctx.fillStyle = '#ffffff';
+        this.ctx.fillText(text, this.circleX, this.circleY);
+        this.ctx.stroke();
+        this.ctx.beginPath()
+        this.ctx.font = this.fontSize / 3 + 'px April';
+        this.ctx.textAlign = 'center';
+        this.ctx.textBaseline = 'middle';
+        this.ctx.fillStyle = '#ffffff';
+        this.ctx.fillText("本月总任务", this.circleX, this.circleY + this.fontSize * 3 / 4);
+        this.ctx.stroke();
+    }
+
+    /**
+     * 绘制圆弧
+     *
+     * @param {x} cx
+     * @param {y} cy
+     * @param {半径} r
+     */
+    sector(cx, cy, r,endAngle) {
+        this.ctx.beginPath();
+        this.ctx.lineWidth = this.lineWidth;
+        this.ctx.strokeStyle = '#c81d39';
+        //圆弧两端的样式
+        this.ctx.lineCap = 'round';
+        this.ctx.arc(
+            cx, cy, r,
+            (Math.PI * -1 / 2),
+            (Math.PI * -1 / 2) + endAngle / 100 * (Math.PI * 2),
+            false
+        );
+        this.ctx.stroke();
+    }
+
+    /**
+     * 初始化
+     *
+     * @param {x} x
+     * @param {y} y
+     * @param {半径} r
+     */
+    init(x, y, r) {
+        //清除canvas内容
+        this.ctx.clearRect(0, 0, x * 2, y * 2);
+        this.circle(x, y, r);
+        this.circle(x, y, r * 1.2);
+    }
+
+    /**
+     * 设置百分比
+     *
+     * @param {内环百分比(100最大)} p1
+     * @param {外环百分比(100最大)} p2
+     */
+    setPersent(p1, p2) {
+        this.init(this.circleX, this.circleY, this.radius);
+        //圆弧
+        this.sector(this.circleX, this.circleY, this.radius, p1);
+        this.sector(this.circleX, this.circleY, this.radius * 1.2,p2);
+    }
+    }

+ 128 - 23
src/views/homepage/darkColor.vue

@@ -5,6 +5,7 @@
       <div class="left">
         <div class="system-main-title">
           <h4 class="section-title">系统概况</h4>
+          <div class="downright"></div>
         </div>
         <div class="system-list">
           <ul>
@@ -114,6 +115,7 @@
         <div class="update-record">
           <div class="system-main-title">
             <h4 class="section-title">说明书更新记录</h4>
+            <div class="downright"></div>
           </div>
           <!-- 进度调 -->
           <div class="progress">
@@ -122,7 +124,7 @@
               <span>当月更新</span>
             </div>
             <div class="progress-box">
-              <div class="progress-list">
+              <div class="progress-list" ref="plist">
                 <div class="progress-item"></div>
                 <div class="progress-item"></div>
                 <div class="progress-item"></div>
@@ -161,6 +163,7 @@
             ref="floorMap"
             :loadName="loadName"
             :type="'floor'"
+            categoryId="LCGN"
           ></floorMap>
           <!-- 图例 -->
           <div class="legend-boxs">
@@ -184,11 +187,14 @@
           <div class="box-center">
             <div class="system-main-title">
               <h4 class="section-title">维保</h4>
+              <div class="downright"></div>
             </div>
             <div class="select">全部</div>
           </div>
           <div class="box-bottom">
-            <div class="circle"></div>
+            <div class="circle">
+              <canvas id="canvas22" width="150" height="150"></canvas>
+            </div>
             <div class="msg">
               <div class="msg-item item-1">
                 <span class="msg-color"></span>
@@ -207,11 +213,14 @@
           <div class="box-center">
             <div class="system-main-title">
               <h4 class="section-title">第三方检测</h4>
+              <div class="downright"></div>
             </div>
             <div class="select">全部</div>
           </div>
           <div class="box-bottom">
-            <div class="circle"></div>
+            <div class="circle">
+               <canvas id="canvas2" width="150" height="150"></canvas>
+            </div>
             <div class="msg">
               <div class="msg-item item-1">
                 <span class="msg-color"></span>
@@ -230,11 +239,14 @@
           <div class="box-center">
             <div class="system-main-title">
               <h4 class="section-title">专维</h4>
+              <div class="downright"></div>
             </div>
             <div class="select">全部</div>
           </div>
           <div class="box-bottom">
-            <div class="circle"></div>
+            <div class="circle">
+               <canvas id="canvas3" width="150" height="150"></canvas>
+            </div>
             <div class="msg">
               <div class="msg-item item-1">
                 <span class="msg-color"></span>
@@ -255,9 +267,10 @@
 </template>
 <script>
 import { getCardList } from "@/api/homePage";
-import floorMap from "@/components/floorMap/index.vue";
-import floorList from "@/components/floorList.vue";
+import floorMap from "@/components/floorMap/darkColorIndex.vue";
+import floorList from "@/components/floorListDark.vue";
 import { mapGetters } from "vuex";
+import { SCircle } from "./Circle.js";
 export default {
   components: { floorMap, floorList },
   data() {
@@ -364,7 +377,6 @@ export default {
     },
 
     emitFloor(item) {
-      console.log(item);
       this.floorInfo = item;
       this.$refs.floorMap.init(this.floorInfo.gname);
       this.init();
@@ -383,12 +395,35 @@ export default {
       } else {
       }
     },
+    // 模拟横条数据
+    getPercent() {
+      let domList = this.$refs.plist.childNodes;
+      let width = this.$refs.plist.offsetWidth - 18;
+      setTimeout(() => {
+        domList[0].style.width = width * 0.2 + "px";
+        domList[1].style.width = width * 0.4 + "px";
+        domList[2].style.width = width * 0.2 + "px";
+        domList[3].style.width = width * 0.2 + "px";
+        // 设置圆
+        const circle = new  SCircle('canvas22');
+         circle.setPersent(37,50);
+         circle.setText('1');
+        //  const circle2 = new SCircle('canvas2',100);
+        //  circle2.setPersent(70,20);
+        //  circle2.setText('23')
+        //  const circle3 = new  SCircle('canvas3',100);
+        //  circle3.setPersent(40,80);
+        //  circle3.setText('39')
+      }, 3000);
+
+    },
   },
   created() {
     this.getSystemList(103000, 1);
   },
   mounted() {
     this.init();
+    this.getPercent();
     this.$refs.floorMap.init(this.floorInfo.gname);
   },
 };
@@ -408,13 +443,23 @@ export default {
     .system-main-title {
       width: 152px;
       height: 40px;
-      background: #1649ce;
+      background: rgba(22, 73, 206, 0.36);
       line-height: 40px;
       margin-bottom: 12px;
+      position: relative;
       h4 {
         color: #fff;
         margin-left: 18px;
       }
+      .downright {
+        position: absolute;
+        width: 0;
+        height: 0;
+        border-left: 20px solid transparent;
+        border-bottom: 48px solid #0c102c;
+        right: 0px;
+        top: 0;
+      }
     }
     .left {
       width: 30.05%;
@@ -493,9 +538,10 @@ export default {
                 .number {
                   width: 30%;
                   margin-right: 1%;
-                  background: #385ecc;
+                  background: rgba(56, 94, 204, 0.22);
                   border-radius: 2px;
                   padding: 14px 0 10px 4px;
+                  color: #ffffff;
                   .title {
                     display: inline-block;
                     position: relative;
@@ -503,7 +549,7 @@ export default {
                     p {
                       display: inline-block;
                       position: relative;
-                      color: #1f2429;
+                      color: #fff;
                       font-size: 14px;
                       line-height: 20px;
                       white-space: nowrap;
@@ -523,7 +569,7 @@ export default {
                   }
                   p {
                     span:first-child {
-                      color: #1f2429;
+                      color: #ffffff;
                       font-size: 18px;
                       font-weight: bold;
                     }
@@ -544,23 +590,48 @@ export default {
             box-shadow: 0 2px 10px 0px rgba(195, 199, 203, 0.4);
           }
           li:nth-of-type(1),
-          li:nth-of-type(4),
-          li:nth-of-type(7) {
+          li:nth-of-type(5) {
             .system-name {
-              background: linear-gradient(to left, #4064cc, #6c8be2);
+              background: linear-gradient(
+                133deg,
+                rgba(64, 204, 202, 0.3) 0%,
+                rgba(108, 194, 226, 0.3) 100%
+              );
+              border-radius: 6px 0px 0px 6px;
             }
           }
           li:nth-of-type(2),
-          li:nth-of-type(5),
           li:nth-of-type(6) {
             .system-name {
-              background: linear-gradient(to left, #3998db, #70bbef);
+              background: linear-gradient(
+                133deg,
+                rgba(57, 152, 219, 0.3) 0%,
+                rgba(112, 187, 239, 0.3),
+                100%
+              );
+              border-radius: 6px 0px 0px 6px;
             }
           }
           li:nth-of-type(3),
+          li:nth-of-type(7) {
+            .system-name {
+              background: linear-gradient(
+                133deg,
+                rgba(174, 48, 118, 0.3) 0%,
+                rgba(213, 83, 135, 0.3) 100%
+              );
+              border-radius: 6px 0px 0px 6px;
+            }
+          }
+          li:nth-of-type(4),
           li:nth-of-type(8) {
             .system-name {
-              background: linear-gradient(to left, #30ae88, #53d5b1);
+              background: linear-gradient(
+                133deg,
+                rgba(240, 84, 59, 0.3) 0%,
+                rgba(226, 133, 108, 0.3) 100%
+              );
+              border-radius: 6px 0px 0px 6px;
             }
           }
         }
@@ -587,14 +658,28 @@ export default {
               background: #ccc;
               border-radius: 6px 6px;
               display: flex;
+              margin-right: 30px;
+              overflow: hidden;
               .progress-item {
                 height: 12px;
-                width: 33%;
-                margin-right: 1px;
+                width: 30%;
+                border-right: 6px #0c102c solid;
                 overflow: hidden;
               }
+              .progress-item:nth-of-type(1) {
+                background: #0a8fef;
+              }
+              .progress-item:nth-of-type(2) {
+                background: #2bc58b;
+              }
+              .progress-item:nth-of-type(3) {
+                background: #fd9039;
+              }
+              .progress-item:nth-of-type(4) {
+                background: #c348fd;
+              }
               .progress-box-bottom {
-                margin-right: 0px;
+                border-right: 0px;
               }
             }
             .progress-legend {
@@ -617,6 +702,26 @@ export default {
                   margin-right: 10px;
                 }
               }
+              .legend-item:nth-of-type(1) {
+                .legend-color {
+                  background: #0a8fef;
+                }
+              }
+              .legend-item:nth-of-type(2) {
+                .legend-color {
+                  background: #2bc58b;
+                }
+              }
+              .legend-item:nth-of-type(3) {
+                .legend-color {
+                  background: #fd9039;
+                }
+              }
+              .legend-item:nth-of-type(4) {
+                .legend-color {
+                  background: #c348fd;
+                }
+              }
             }
           }
           .number {
@@ -680,7 +785,7 @@ export default {
           position: absolute;
           z-index: 9;
           right: 32px;
-          top: 142px;
+          top: 50px;
         }
       }
     }
@@ -706,10 +811,10 @@ export default {
           }
         }
         .box-bottom {
-          margin-top: 36px;
+          // padding-top: 36px;
+          box-sizing: border-box;
           display: flex;
           .circle {
-            margin: 40px;
             width: 150px;
             height: 150px;
           }

+ 9 - 3
src/views/homepage/index.vue

@@ -1,6 +1,6 @@
 <template>
     <div class="homepage-box">
-    <main class='homepage' v-if="false">
+    <main class='homepage' v-if="!showDark">
         <section class='homepage-cards-content'>
             <div  v-for='(arr , index) in cardsList' :key='index' class="items-container">
                 <section v-for="(item ,index) in arr" :key="index" class='cards-item'  >
@@ -112,6 +112,7 @@ import { getCardList, getQueryList, getChangeList } from '@/api/homePage'
 import {sortBy} from 'lodash'
 import moment from 'moment'
 import darkColor from "./darkColor"
+import bus from '@/utils/bus.js'
 export default {
     components:{darkColor},
     data() {
@@ -128,7 +129,8 @@ export default {
                 1: require('../../assets/images/icons/protect.png'),
                 2: require('../../assets/images/icons/check.png'),
             },
-
+           // 是否展示暗色风格
+            showDark:false,
         }
     },
     created () {
@@ -140,7 +142,11 @@ export default {
     mounted() {
         this.testAjax()
         this.getItemsQuery()
-        this.getInstructionList()
+        this.getInstructionList();
+        // 触发风格颜色的调整
+        bus.$on('changeStyleColor',(val)=>{
+            this.showDark =val;
+        })
     },
 
     methods: {

+ 2 - 2
vue.config.js

@@ -34,8 +34,8 @@ module.exports = {
             // 图例库服务
             "/serve": {
                 // target: 'http://192.168.200.87:8088',
-                target: 'http://60.205.177.43:28888', //阿里云
-            //    target: 'http://10.199.143.129:8080',    //生产环境
+                target: 'http://60.205.177.43:8080', //阿里云
+                // target: 'http://10.199.143.129:8080',    //生产环境
                 changeOrigin: true,
                 pathRewrite: {
                     "^/serve": "",