陶杰
2024-11-19 f7ac77c7cc193502aff7e2a70f636253ada12386
1.区域页面
已修改6个文件
已添加1个文件
1656 ■■■■■ 文件已修改
src/api/area.js 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/device-info.vue 287 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/utils/request-api.js 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/area/main-container.vue 1080 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/area/switch-board.vue 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/screen1/itm.vue 203 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/screen1/main-container.vue 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/area.js
@@ -159,4 +159,42 @@
      
    }
  })
}
/**
 *
 * @returns 获取所有交换机柜列表
 */
export function getSwitchBord() {
  return request({
    url: '/api/services/app/SwitchDevice/GetSwitchBord',
    method: 'get',
    params: {
    }
  })
}
/**
 * 获取所有区域列表
 */
export function getAreaCode() {
  return request({
    url: '/api/services/app/SwitchDevice/GetAreaCode',
    method: 'get',
    params: {
    }
  })
}
export function AssignSwitch(dto) {
  return request({
    url: '/api/services/app/SwitchDevice/AssignSwitch',
    method: 'post',
    data: {
      ...dto
    }
  })
}
src/components/device-info.vue
对比新文件
@@ -0,0 +1,287 @@
<template>
      <div
        v-if="local_show_info"
        class="device-info"
        @click="local_show_info = false"
      >
        <div class="title">接口</div>
        <div class="each">
          <div class="label">网络连接性:</div>
          <div class="value">{{ device_info.status }}</div>
        </div>
        <div class="each">
          <div class="label">IP地址:</div>
          <div class="value">{{ device_info.ip || "" }}</div>
        </div>
        <div class="each">
          <div class="label">Mac:</div>
          <div class="value">{{ device_info.mac }}</div>
        </div>
        <div class="each">
          <div class="label">桥架端口:</div>
          <div class="value">{{ device_info.networkPort }}</div>
        </div>
        <div class="each">
          <div class="label">交换机名字:</div>
          <div class="value">{{ device_info.switchName }}</div>
        </div>
        <div class="each">
          <div class="label">交换机端口:</div>
          <div class="value">{{ device_info.port }}</div>
        </div>
        <div class="each">
          <div class="label">名称:</div>
          <div class="value">{{ device_info.clhwName }}</div>
        </div>
        <div class="each">
          <div class="label">类型:</div>
          <div class="value">{{ device_info.clhwTier }}</div>
        </div>
        <div class="each">
          <div class="label">操作系统:</div>
          <div class="value">{{ device_info.clhwOperating_System }}</div>
        </div>
        <div class="button-to-switch" @click="toSwitchInfo()">交换机</div>
        <div class="button-del-port" @click="delPort()">删除</div>
        <div
          class="button-to-check"
          v-if="
            device_info?.status==1 ||
            device_info?.status==2 ||
            device_info?.status==3 ||
            device_info?.status==4
          "
          @click="statusPort(index)"
        >
          确认
        </div>
        <div class="close" @click="handleClose"></div>
      </div>
</template>
<script>
import { updateDevicePosition } from "@/api/area";
export default {
  props: {
    show_info: {
      type: Boolean,
      default() {
        return false;
      },
    },
    device_info: {
      type: Object,
      default() {
        return {};
      },
    },
    configs: {
      type: Object,
      default() {
        return {};
      },
    },
    datamap: {
      type: Object,
      default() {
        return {};
      },
    },
    devicelist: {
      type: Array,
      default() {
        return [];
      },
    },
    width: {
      type: Number,
      default() {
        return 4;
      },
    },
    code: "",
    areacode: "",
    current_show_id: "",
    grouplevel: {
      type: Number,
      default() {
        return 0;
      },
    },
    status_indrag: false,
    current_drag_index: {
      type: Object,
      default() {
        return {};
      },
    },
  },
  watch: {
    // 监听 props 的变化并同步到 data
    show_info(newVal) {
      this.local_show_info = newVal;
    },
  },
  methods: {
    toSwitchInfo() {
      this.$emit("toSwitchInfo",this.device_info);
    },
    async delPort(index) {
      await this.$modal.confirm("是否删除此端口");
      this.$emit("delPort", this.device_info);
    },
    async statusPort(index) {
      await this.$modal.confirm("是否设置此端口状态为正常");
      this.$emit("statusPort",this.device_info);
    },
    handleClose(){
      this.local_show_info=false
    },
  },
  data() {
    return {
      local_show_info: false,
      current_show_info: {
        status:"",
        ip:"",
        mac:"",
        networkPort:"",
        switchName:"",
        port:"",
        clhwName:"",
        clhwTier:"",
        clhwOperating_System:""
      },
    };
  },
};
</script>
<style lang="scss" scoped>
.device-info {
      cursor: default;
      background-image: url("../assets/area/device-info-bg.svg");
      /* background-color: #a6c6e5; */
      background-size: 100% 100%;
      height: 24.4rem;
      width: 29rem;
      position: absolute;
      // top: -31.5rem;
      top: -28.7rem;
      transform: translate(-50%, 0%);
      left: 50%;
      z-index: 120;
      padding: 3.1rem;
      padding-top: 2.5rem;
      padding-left: 1.6rem;
      padding-right: 1.6rem;
      .title {
        height: 2.5rem;
        font-size: 1.8rem;
        font-family: PingFangSC-Semibold, PingFang SC;
        font-weight: 600;
        color: #265696;
        line-height: 2.5rem;
        text-align: left;
        margin-bottom: 0.5rem;
      }
      .each {
        display: flex;
        height: 2rem;
        font-size: 1.4rem;
        font-family: PingFangSC-Regular, PingFang SC;
        font-weight: 400;
        color: #265696;
        line-height: 2rem;
        .label {
          margin-right: 1rem;
          text-align: left;
        }
        .value {
        }
      }
      .close {
        background-image: url("../assets/area/close.svg");
        background-size: 100% 100%;
        position: absolute;
        width: 1.2rem;
        height: 1.2rem;
        top: 3rem;
        right: 2rem;
      }
      .button-to-switch {
        cursor: pointer;
        width: 5.9rem;
        height: 2.2rem;
        border-radius: 0.2rem;
        border: 0.1rem solid #278afa;
        font-size: 1.2rem;
        font-family: PingFangSC-Regular, PingFang SC;
        font-weight: 400;
        color: #278afa;
        line-height: 2.2rem;
        position: absolute;
        right: 9.2rem;
        bottom: 4rem;
      }
      .button-to-switch:hover {
        color: #fff;
        background-color: #278afa;
      }
      .button-to-check {
        cursor: pointer;
        width: 5.2rem;
        height: 2.2rem;
        border-radius: 0.2rem;
        border: 0.1rem solid rgb(15, 243, 76);
        font-size: 1.2rem;
        font-family: PingFangSC-Regular, PingFang SC;
        font-weight: 400;
        color: rgb(2, 76, 22);
        line-height: 2.2rem;
        position: absolute;
        right: 16.2rem;
        bottom: 4rem;
      }
      .button-to-check:hover {
        color: #fff;
        background-color: rgb(15, 243, 76);
      }
      .button-del-port {
        cursor: pointer;
        width: 5.2rem;
        height: 2.2rem;
        border-radius: 0.2rem;
        border: 0.1rem solid rgb(243, 15, 15);
        font-size: 1.2rem;
        font-family: PingFangSC-Regular, PingFang SC;
        font-weight: 400;
        color: rgb(243, 15, 15);
        line-height: 2.2rem;
        position: absolute;
        right: 2.2rem;
        bottom: 4rem;
      }
      .button-del-port:hover {
        color: #fff;
        background-color: rgb(243, 15, 15);
      }
    }
</style>
src/utils/request-api.js
@@ -5,9 +5,10 @@
// create an axios instance
const service = axios.create({
  // baseURL: process.env.VUE_APP_BASE_API, // url = base url + request url
  baseURL: 'http://114.55.97.167:8125',
  // baseURL: 'http://114.55.97.167:8125',
  // baseURL: 'https://szhaeapp150.apac.bosch.com:441',
  // baseURL: 'http://192.168.1.235:8125',
  baseURL: 'http://192.168.1.235:8125',
  // baseURL: 'http://localhost:44311/',
  // withCredentials: true, // send cookies when cross-domain requests
  timeout: 60000 // request timeout
})
src/views/area/main-container.vue
@@ -11,9 +11,8 @@
      @mousedown="handleMouseDown"
      @mouseleave="handleMouseLeave" -->
    <div id="content" class="equipments-container area-map" :class="['area-map-' + code]" v-show="hideServe"
         @mousemove="handleMouseMove" @mouseup="handleMouseUp" @mousedown="handleMouseDown"
         @mouseleave="handleMouseLeave"
         :style="{
      @mousemove="handleMouseMove" @mouseup="handleMouseUp" @mousedown="handleMouseDown" @mouseleave="handleMouseLeave"
      :style="{
        transform: `scale(${scale_container})`,
        width: screen_width + 'rem',
        height: screen_height + 'rem',
@@ -23,39 +22,8 @@
        'margin-left': `${container_offset_left}rem`,
        'margin-top': `${container_offset_top}rem`,
      }">
      <!-- <div
        class="equipment-item itm-svg-a"
        draggable="true"
        style="width: 10rem; height: 10rem; position: absolute"
        @dragstart="dragstart($event)"
        @dragend="dragend($event)"
        @click.prevent.stop="showServe"
        :style="{ left: tleft + 'rem' }" -->
      <!-- <div
        class="equipment-item itm-svg-a"
        :class="[item.typeclass]"
        :id="item.id"
        draggable="true"
        v-for="item in device_list"
        :key="item.id"
        @dragstart="dragstart($event)"
        @dragend="dragend($event)"
        @click.prevent.stop="showServe"
        :style="{ left: item.currentX + 'rem', top: item.currentY + 'rem' }"
      ></div> -->
      <div class="bridge-group" v-for="group in bridge_infos" :key="group.code" :code="group.code">
        <!-- {{ group.pad }} -->
        <!-- @showServeInfo="showServeInfo" -->
        <!-- <bridge v-for="(item, index) of group.cells" :key="item.cell" :code="group.code" :areacode="code"
          @update_map="update_map" @update_status_indrag="update_status_indrag"
          @click_item="click_item" @click_item_add="click_item_add" @toSwitchInfo="toSwitchInfo" @delPort="delPort"
          @statusPort="statusPort" :current_drag_index="current_drag_index" :status_indrag="status_indrag"
          :grouplevel="item.cell" :devicelist="device_list" :current_show_id="current_show_id"
          :width="item.width || group.width" :datamap="item.datamap" :left="group.left || 0" :right="group.right || 0" -->
        <!-- :grouplevel="item.cell" -->
        <!-- @showServeInfo="showServeInfo" -->
        <!-- :key="item.cell" -->
      <!-- <div class="bridge-group" v-for="group in bridge_infos" :key="group.code" :code="group.code">
        <bridge v-for="(item, index) of group.cells" :key="item.cell" :code="group.code" :areacode="code"
                @update_map="update_map" @update_status_indrag="update_status_indrag" @click_item="click_item"
                @click_item_add="click_item_add" @toSwitchInfo="toSwitchInfo" @delPort="delPort"
@@ -65,24 +33,61 @@
                :datamap="item.datamap" :left="group.left || 0" :right="group.right || 0"
                :top="group.top ? group.top + index * (group.pad || 3) : 0"
                :bottom="group.bottom ? group.bottom - index * (group.pad || 3) : 0"></bridge>
      </div> -->
      <div v-for="(item, index) in elements" :key="index" class="grid-item bridge-items" :style="{
        width: elementWidth + 'rem',
        height: elementHeight + 'rem',
        top: `${item.y * elementHeight}rem`,
        left: `${item.x * elementWidth}rem`
      }">
        <!-- 每个元素的内容可以放在这里 -->
        <div v-if="item.isPlaceholder" class="bridge-item" @dblclick="handleItemClickCancel(item)"
          @click="handleClickToAddItem(index,item)"
          :class="[item?.deviceInfo ? 'space-in' : '',!item?.deviceInfo || !item?.deviceInfo?.id?'space-text-gray': '',
              status_indrag &&
              (!item?.deviceInfo || !item?.deviceInfo?.id)? 'space-drag': '',
            ]"
        >
          <!-- <div v-show="item.deviceInfo &&  item.deviceInfo?.networkPort" -->
           <div
            class="space-text" @dragstart="dragstart($event, index)" @dragend="dragend($event, index)"
            @drop="handleDrop($event, index)" @dragover="handleDragOver($event)" draggable="true"
            @click="showDeviceInfo(index,item,$event)"
            >
            {{ item.deviceInfo?.networkPort }}
            <device-info v-show="selectedIndex === index " :show_info="show_device_info"
              :device_info="cur_device_info" @toSwitchInfo="toSwitchInfo"
              ></device-info>
          </div>
        </div>
        <div v-else @click="handleItemClick(item)" class="bridge-item-none hover-shadow">
          <div :style="{
            width: elementWidth + 'rem',
            height: elementHeight / 2 + 'rem'
          }"></div>
        </div>
      </div>
    </div>
    <!-- 需要渲染一个canvas,然后基于数据,和滚动坐标,缩放坐标,位置中点吧 -->
    <tj-container v-if="true && code" :code="code" :key="code" @closeself="closeself"
                  :chartclose="chartclose"></tj-container>
      :chartclose="chartclose"></tj-container>
    <!-- 显示图标的开关 -->
    <div v-if="true && code && chartclose" class="chart-open" @click="chartclose = false">
      <div class="img-button"></div>
    </div>
    <equ-add-form ref="equAddForm" :code="code" :areas="areas" :init_device_list="device_list"
                  @update="update_map"></equ-add-form>
    <server-info v-if="!hideServe"
    :serve_info="serve_info"
    :serve_select="serve_select"
    :code="code"></server-info>
      @update="update_map"></equ-add-form>
    <server-info v-if="!hideServe" :serve_info="serve_info" :serve_select="serve_select" :code="code"></server-info>
    <div class="back-button-left-bottom" @click="backToTop">返回</div>
  </div>
</template>
<script>
@@ -90,6 +95,7 @@
import bridge from "@/components/bridge";
import serverInfo from "./server-info";
import equAddForm from "@/components/equ-add-form.vue";
import deviceInfo from "@/components/device-info";
import {
  getAreaServeInfo,
@@ -100,13 +106,13 @@
  delport,
  statusPort,
} from "@/api/area";
import {getAreaTjData} from "@/api/area";
import { getAreaTjData } from "@/api/area";
import {mapdata} from "./map-data.js";
import { mapdata } from "./map-data.js";
import Bridge from "@/components/bridge.vue";
export default {
  components: {tjContainer, bridge, equAddForm, Bridge,serverInfo},
  components: { tjContainer, bridge, equAddForm, Bridge, serverInfo, deviceInfo },
  props: {
    item_show: false,
    code: "",
@@ -136,9 +142,9 @@
      scale_container: 0.9,
      //设备数据,实际便宜多少米+实际的宽高大小
      equipmentdata: [
        {t: "a", x: 20, y: 30, w: 1, h: 2},
        {t: "a", x: 40, y: 30, w: 2, h: 2},
        {t: "a", x: 60, y: 35, w: 2, h: 1},
        { t: "a", x: 20, y: 30, w: 1, h: 2 },
        { t: "a", x: 40, y: 30, w: 2, h: 2 },
        { t: "a", x: 60, y: 35, w: 2, h: 1 },
      ],
      //实际的像素比,单位rem
@@ -176,17 +182,7 @@
        //   time: "1-10",
        //   desc: "Host: SZHMESVMA544<br/>Line: SMT26<br/>Critical",
        //   status: "red",
        // },
        // {
        //   time: "11-20",
        //   desc: "Host: SZHMESVMA557<br/>Line: IB2 FA2<br/>Overall Execution Time 2103",
        //   status: "yellow",
        // },
        // {
        //   time: "31-40",
        //   desc: "Host: SZHMESVMA320<br/>Line: DBC8<br/>Overall Execution Time 3120",
        //   status: "yellow",
        // },
        // }
      ],
      //图标的
      chartclose: false,
@@ -194,10 +190,36 @@
      //新增的
      areas: [],
      activateSwitchPorts: {},
      switchAllDetialInfos:[],
      switchAllDetialInfos: [],
      dialog_activateSwitchPorts: false,
      first_query_ip:true,
      first_query_ip: true,
      totalElements: 1000, // 元素总数
      elements: [], // 初始化 elements 数据为空数组
      isDragging: false,
      dragSource: null, // 当前被拖拽的元素
      show_device_info: false, // 展示设备信息
      selectedIndex: null,
      cur_device_info: null,  // 当前的设备信息
    };
  },
  computed: {
    // 计算行数和列数
    gridDimensions() {
      const columns = Math.ceil(Math.sqrt(this.totalElements * (this.screen_width / this.screen_height)));
      const rows = Math.ceil(this.totalElements / columns);
      return { columns, rows };
    },
    // 每个元素的宽度
    elementWidth() {
      return this.screen_width / this.gridDimensions.columns;
    },
    // 每个元素的高度
    elementHeight() {
      return this.screen_height / this.gridDimensions.rows;
    },
  },
  created() {
    var zoom = this.$route.query.zoom;
@@ -228,6 +250,11 @@
      // console.log('areas',res.switchAreaInfo || [])
      this.areas = res.switchAreaInfo || [];
    });
    // 根据屏幕初始化格子
    this.initializeElements(); // 在组件加载时初始化 elements
    // 初始化设备信息
    this.handleBindElementsItems()
  },
  destroyed() {
    const content = document.getElementById("content");
@@ -235,6 +262,90 @@
    this.stopScrolling();
  },
  methods: {
    initializeElements() {
      const elements = [];
      for (let i = 0; i < this.totalElements; i++) {
        const x = i % this.gridDimensions.columns;
        const y = Math.floor(i / this.gridDimensions.columns);
        const isPlaceholder = false
        const name = x + "-" + y
        // 绑定设备信息
        const deviceInfo = {}
        elements.push({ x, y, isPlaceholder, name, deviceInfo });
      }
      // 判断最后一行是否需要补齐
      const remainder = this.totalElements % this.gridDimensions.columns;
      if (remainder !== 0) {
        const placeholdersNeeded = this.gridDimensions.columns - remainder;
        for (let i = 0; i < placeholdersNeeded; i++) {
          const x = remainder + i;
          const y = Math.floor(this.totalElements / this.gridDimensions.columns);
          const isPlaceholder = false
          const name = x + "-" + y
          // 绑定设备信息
          const deviceInfo = {}
          elements.push({ x, y, isPlaceholder, name, deviceInfo });
        }
      }
      this.elements = elements; // 赋值给 data 中的 elements
    },
    // 根据元素的行列绑定元素信息
    async handleBindElementsItems() {
      const deviceInfoList = await getDeviceList(this.code)
      // 所有的格子信息
      console.log("所有的格子信息")
      console.log(this.elements)
      // 所有的设备信息
      console.log("所有的设备信息")
      console.log(deviceInfoList.switchDetialInfos)
      // 遍历 switchDetialInfos,构造 Map
      const switchDetailInfosMap = new Map();
      const switchDetialInfos = deviceInfoList.switchDetialInfos
      switchDetialInfos.forEach((info) => {
        const key = `${info.areaRow}-${info.areaCell}`;
        // 直接将单个对象作为值放入 Map
        switchDetailInfosMap.set(key, info);
      });
      console.log("设备信息转换后的 Map");
      console.log(switchDetailInfosMap);
      // 遍历 elements,将匹配的设备信息添加到每个元素的 deviceInfo 属性
      this.elements.forEach((element) => {
        const key = `${element.y}-${element.x}`; // 使用元素的 y 和 x 构造 key
        const deviceInfo = switchDetailInfosMap.get(key); // 从 Map 中查找设备信息
        if (deviceInfo) {
          // 如果找到设备信息,存放到 element 的 deviceInfo 属性
          element.deviceInfo = deviceInfo;
          element.isPlaceholder = true
        } else {
          // 如果未找到,则清空或设置默认值
          element.deviceInfo = null;
          element.isPlaceholder = false
        }
      });
    },
    handleItemClick(item) {
      item.deviceInfo = null;
      this.$set(item, 'isPlaceholder', true)
    },
    handleItemClickCancel(item) {
      // 这里的取消操作需要判断当前的元素是不是空的
      if(item?.deviceInfo?.id){
        // this.$message('空设备才可双击删除!');
      }else{
        this.$set(item, 'isPlaceholder', false)
        this.$message('空设备删除成功!');
      }
    },
    toSwitchInfo(info) {
      this.showServe(info);
    },
@@ -256,9 +367,7 @@
      this.update_map();
    },
    async delPort(info) {
      //删除接口,传什么呢??
      console.log("delPort", info);
      // return
      var json = {
        id: info.id,
        operateType: 4,
@@ -270,14 +379,17 @@
      this.$modal.closeLoading();
      this.update_map();
      // 根据屏幕初始化格子
      this.initializeElements(); // 在组件加载时初始化 elements
       // 初始化设备信息
       this.handleBindElementsItems()
    },
    backToTop() {
      if (!this.hideServe) {
        this.hideServe = !this.hideServe;
        return;
      }
      this.$router.push({path: "/area-all"});
      this.$router.push({ path: "/area-all" });
    },
    async update_map() {
      this.$modal.loading("加载中");
@@ -285,37 +397,28 @@
      this.device_list = re.switchDetialInfos || [];
      await this.init_data();
      this.$modal.closeLoading();
      if(this.query_networkPort&&this.bridge_infos&&this.first_query_ip){
      if (this.query_networkPort && this.bridge_infos && this.first_query_ip) {
        this.first_query_ip = false
        //查询并调用,展示?
        // this.bridge_infos[item.areaIndex] = {
        //   left: 0,
        //   top: 0,
        //   bottom: 0,
        //   right: 0,
        //   ...(mapdata["common"] || {}),
        //   ...(currentareaconfig[item.areaIndex] || ""),
        //   cells: item.areaCellRow || [],
        //   code: item.areaIndex,
        // };
        console.log('this.bridge_infos',this.bridge_infos,this.query_networkPort)
        for(var key of  Object.keys(this.bridge_infos)){
          var allcells = this.bridge_infos[key]
          for(var cell of allcells.cells){
              var datamaps = cell.datamap || {}
              console.log('datamaps',datamaps)
              for(var itemkey of Object.keys(datamaps)){
                if(datamaps[itemkey].name === this.query_networkPort){
                  //默认打开
                  // id itemcode@3_3_14 ud itemtext@3_3_14
                  var dom = document.getElementById('itemtext@'+key+'_'+(cell.cell)+'_'+itemkey)
                  // console.log('datamaps get',datamaps[itemkey],dom,datamaps,this.bridge_infos,)
                  if(dom){
                    dom.click()
                  }
        console.log('this.bridge_infos', this.bridge_infos, this.query_networkPort)
        for (var key of Object.keys(this.bridge_infos)) {
          var allcells = this.bridge_infos[key]
          for (var cell of allcells.cells) {
            var datamaps = cell.datamap || {}
            console.log('datamaps', datamaps)
            for (var itemkey of Object.keys(datamaps)) {
              if (datamaps[itemkey].name === this.query_networkPort) {
                //默认打开
                // id itemcode@3_3_14 ud itemtext@3_3_14
                var dom = document.getElementById('itemtext@' + key + '_' + (cell.cell) + '_' + itemkey)
                // console.log('datamaps get',datamaps[itemkey],dom,datamaps,this.bridge_infos,)
                if (dom) {
                  dom.click()
                }
              }
            }
          }
        }
      }
@@ -328,6 +431,7 @@
      this.$refs.equAddForm && this.$refs.equAddForm.openform(locInfo);
    },
    async showServeInfo(info) {
      //展示交换机全部端口
      console.log("showServeInfo", info);
      //弹出框展示全部端口,并且每个端口的情况
@@ -398,34 +502,25 @@
            if (offsetx != 0) {
              if (offsetx > 0) {
                this.container_offset_left +=
                    this.base_move_offset * this.scale_container;
                  this.base_move_offset * this.scale_container;
              } else {
                this.container_offset_left -=
                    this.base_move_offset * this.scale_container;
                  this.base_move_offset * this.scale_container;
              }
            }
            if (offsety != 0) {
              if (offsety > 0) {
                console.log("plus container_offset_top");
                this.container_offset_top +=
                    this.base_move_offset * this.scale_container;
                  this.base_move_offset * this.scale_container;
              } else {
                console.log("mul container_offset_top");
                this.container_offset_top -=
                    this.base_move_offset * this.scale_container;
                  this.base_move_offset * this.scale_container;
              }
            }
            // if (this.container_offset_x < -90 / this.scale_container) {
            //   this.container_offset_x = -90 / this.scale_container;
            // } else if (this.container_offset_x > 90 / this.scale_container) {
            //   this.container_offset_x = 90 / this.scale_container;
            // }
            // if (this.container_offset_y <  -90 / this.scale_container) {
            //   this.container_offset_y =  -90 / this.scale_container;
            // } else if (this.container_offset_y > 90 / this.scale_container) {
            //   this.container_offset_y = 90 / this.scale_container;
            // }
          }
        }
        this.mouse_offset_last = event;
@@ -440,8 +535,8 @@
          //直接修改坐标就行了
          //计算鼠标偏移量,然后转换为屏幕坐标,再转换为显示单位坐标,同时弹出提示?是否要更改吧,更改就调用接口
          if (
              this.mouse_offset_last &&
              (this.cal_offset_x || this.cal_offset_y)
            this.mouse_offset_last &&
            (this.cal_offset_x || this.cal_offset_y)
          ) {
            console.log("update?", this.tleft);
            alert("是否要修改设备坐标");
@@ -455,56 +550,15 @@
    },
    handleMouseDown(event) {
      // console.log("handleMouseDown", event, event.target.className);
      if (event.target.className.indexOf("equipment-item") >= 0) {
        // console.log("handleMouseDown2", event, event.target.id);
        // this.mouse_click = event.target;
      } else if (event.target.id == "content") {
        this.mouse_click = event.target;
      }
    },
    handleMouseLeave(event) {
      // console.log("handleMouseLeave", event);
      //直接取消
      // if (this.mouse_click) {
      //   // console.log("handleMouseMove", event);
      //   //记录坐标,支持实时的?
      //   if (this.mouse_offset_last) {
      //     // this.tleft += 20 - this.mouse_offset_last.offsetX
      //     var offsetx = event.offsetX - this.mouse_offset_last.offsetX;
      //     var offsety = event.offsetY - this.mouse_offset_last.offsetY;
      //     if (offsety >= offsetx) {
      //       offsetx = 0;
      //     } else {
      //       offsety = 0;
      //     }
      //     console.log("offsetx", offsetx, offsety);
      //     if (event.target.id == "content") {
      //       //让看板内部有偏移量
      //       if (offsetx != 0) {
      //         this.container_offset_x +=
      //           2 * this.scale_container * (offsetx > 0 ? 1 : -1);
      //       }
      //       if (offsety != 0) {
      //         var a = 2 * this.scale_container * (offsety > 0 ? 1 : -1);
      //         console.log(
      //           "change this.container_offset_y1",
      //           this.container_offset_y,
      //           a
      //         );
      //         this.container_offset_y += a;
      //         console.log(
      //           "change this.container_offset_y2",
      //           this.container_offset_y,
      //           a
      //         );
      //       }
      //     }
      //   }
      //   this.mouse_offset_last = event;
      // }
      this.mouse_click = undefined;
      this.mouse_offset_last = undefined;
    },
@@ -513,11 +567,11 @@
      event.preventDefault();
      const delta = event.deltaY < 0 ? 0.2 : -0.2;
      this.container_offset_left =
          this.container_offset_left /
          (this.scale_container / (delta + this.scale_container));
        this.container_offset_left /
        (this.scale_container / (delta + this.scale_container));
      this.container_offset_top =
          this.container_offset_top /
          (this.scale_container / (delta + this.scale_container));
        this.container_offset_top /
        (this.scale_container / (delta + this.scale_container));
      this.scale_container += delta;
      if (this.scale_container < 0.2) {
@@ -528,108 +582,169 @@
        this.container_offset_top = 0;
      }
    },
    dragstart(e) {
    dragstart(e, index) {
      console.log(e);
      this.startclientX = e.clientX; // 记录拖拽元素初始位置
      this.startclientY = e.clientY;
      this.dragSource = index; // 记录拖拽的源元素
      console.log("start", e);
      console.log("拖拽事件开始", index)
      console.log(this.elements[index])
    },
    // 拖拽完成事件
    async dragend(e) {
    async dragend(e, index) {
      //确定是否需要更新
      let that = this;
      console.log("拖拽事件完成", index)
      console.log("拖拽目标Id:", e.target.id)
      return;
      var dto = this.device_list_map[e.target.id];
      that.$modal
          .confirm(
              "是否确定修改坐标,设备名:" + dto.switchName + "/" + dto.networkPort
          )
          .then(async (res) => {
            that.$modal.loading();
            console.log("end", e);
            console.log(e);
            that.cal_offset_x = e.clientX - that.startclientX; // 计算偏移量
            that.cal_offset_y = e.clientY - that.startclientY;
            // console.log(
            //   "end drag",
            //   this.startclientX,
            //   e.clientX,
            //   this.cal_offset_x,
            //   this.device_list_map[e.target.id],
            //   this.device_list_map[e.target.id].currentX,
            //   parseFloat(this.device_list_map[e.target.id].currentX),
            //   parseFloat(this.device_list_map[e.target.id].currentX) +
            //     parseFloat(
            //       (this.cal_offset_x / this.html_base) * (1 / this.scale_container)
            //     ).toFixed(2)
            // );
            var rawx = that.device_list_map[e.target.id].currentX;
            var rawy = that.device_list_map[e.target.id].currentY;
            that.device_list_map[e.target.id].currentX =
                parseFloat(that.device_list_map[e.target.id].currentX) +
                parseFloat(
                    (that.cal_offset_x / that.html_base) * (1 / that.scale_container)
                ); // 实现拖拽元素随偏移量移动
            that.device_list_map[e.target.id].currentY =
                parseFloat(that.device_list_map[e.target.id].currentY) +
                parseFloat(
                    (that.cal_offset_y / that.html_base) * (1 / that.scale_container)
                );
            // this.elTop += this.cal_offset_y;
            console.log("end drag2", that.device_list_map[e.target.id].currentX);
            //更新坐标信息,并保存
            var json = {
              id: dto.id.replace("content_", ""),
              operateType: 1,
              operateTime: new Date(),
              moveBeforeX: rawx,
              moveBeforeY: rawy,
              currentX: that.device_list_map[e.target.id].currentX,
              currentY: that.device_list_map[e.target.id].currentY,
            };
            const data = await updateDevicePosition(json);
        .confirm(
          "是否确定修改坐标,设备名:" + dto.switchName + "/" + dto.networkPort
        )
        .then(async (res) => {
          that.$modal.loading();
          console.log("end", e);
          console.log(e);
          that.cal_offset_x = e.clientX - that.startclientX; // 计算偏移量
          that.cal_offset_y = e.clientY - that.startclientY;
            that.$modal.closeLoading();
            console.log("updateDevicePosition", data);
          })
          .catch((e) => {
          })
          .finally(() => {
          });
          var rawx = that.device_list_map[e.target.id].currentX;
          var rawy = that.device_list_map[e.target.id].currentY;
          that.device_list_map[e.target.id].currentX =
            parseFloat(that.device_list_map[e.target.id].currentX) +
            parseFloat(
              (that.cal_offset_x / that.html_base) * (1 / that.scale_container)
            ); // 实现拖拽元素随偏移量移动
          that.device_list_map[e.target.id].currentY =
            parseFloat(that.device_list_map[e.target.id].currentY) +
            parseFloat(
              (that.cal_offset_y / that.html_base) * (1 / that.scale_container)
            );
          // this.elTop += this.cal_offset_y;
          console.log("end drag2", that.device_list_map[e.target.id].currentX);
          //更新坐标信息,并保存
          var json = {
            id: dto.id.replace("content_", ""),
            operateType: 1,
            operateTime: new Date(),
            moveBeforeX: rawx,
            moveBeforeY: rawy,
            currentX: that.device_list_map[e.target.id].currentX,
            currentY: that.device_list_map[e.target.id].currentY,
          };
          const data = await updateDevicePosition(json);
          that.$modal.closeLoading();
          console.log("updateDevicePosition", data);
        })
        .catch((e) => {
        })
        .finally(() => {
        });
    },
    // async init_data() {
    //   this.$modal.loading();
    //   const data = await getDeviceList(this.code);
    //   this.$modal.closeLoading();
    //   var arr = (data && data.switchDetialInfos) || [];
    //   this.device_list = [];
    //   var index = -1;
    //   for (var item of arr) {
    //     index++;
    //     if (item.baseX) {
    //       var dto = {
    //         ...item,
    //         id: "content_" + item.id,
    //         //todo 需要根据类型来模拟设备
    //         typeclass: "equ-" + (index % 7),
    //         currentX: parseFloat(item.currentX || item.baseX),
    //         currentY: parseFloat(item.currentY || item.baseY),
    //       };
    //       this.device_list.push(dto);
    //       this.device_list_map[dto.id] = dto;
    //     }
    //   }
    //   console.log("this.device_list", this.device_list);
    // },
    /**两个元素交换位置 */
    handleDrop(e, targetIndex) {
      console.log("handleDrop")
      console.log(targetIndex)
      let that = this;
      let sourceIndex = this.dragSource;
      // 实现逻辑,例如交换两个元素的位置
      if (sourceIndex !== targetIndex &&(this.elements[sourceIndex].deviceInfo||this.elements[targetIndex].deviceInfo)) {
        const sourceDeviceInfo = this.elements[sourceIndex].deviceInfo;
        const targetDeviceInfo = this.elements[targetIndex].deviceInfo;
        let sourceNetworkPort="指定位置"
        if(sourceDeviceInfo?.networkPort){
          sourceNetworkPort=sourceDeviceInfo?.networkPort
        }
        let targetNetworkPort="指定位置"
        if(targetDeviceInfo?.networkPort){
          targetNetworkPort=targetDeviceInfo?.networkPort
        }
        let type=false;
        if(sourceDeviceInfo?.networkPort&&targetDeviceInfo?.networkPort){
          type=true;
        }
        that.$modal
        .confirm(
          `是否确定${type ? "交换" : "移动"}位置:从${sourceNetworkPort
          }到${targetNetworkPort}上`
        )
        .then(async (res) => {
          this.elements[sourceIndex].deviceInfo = targetDeviceInfo
          this.elements[targetIndex].deviceInfo = sourceDeviceInfo
          if(this.elements[sourceIndex].deviceInfo==null){
            this.elements[sourceIndex].isPlaceholder=false;
          }
          if(this.elements[targetIndex].deviceInfo==null){
            this.elements[targetIndex].isPlaceholder=false;
          }
          that.$modal.loading();
          var json = {
              id: sourceDeviceInfo.id,
              operateType: 1,
              operateTime: new Date(),
              networkPort: sourceDeviceInfo.networkPort,
              areaCell:this.elements[sourceIndex].x,
              areaRow:this.elements[sourceIndex].y,
              areaCellTarget:this.elements[targetIndex].x,
              areaRowTarget:this.elements[targetIndex].y,
            };
            if (targetDeviceInfo?.id) {
              json["changeId"] = targetDeviceInfo?.id;
              json["operateType"] = 3;
            }
          const data = await updateDevicePosition(json);
          that.$modal.closeLoading();
          if (data) {
              this.$message.success(`${targetid ? "交换" : "移动"}成功`);
          }
            // 根据屏幕初始化格子
            this.initializeElements(); // 在组件加载时初始化 elements
            // 初始化设备信息
            this.handleBindElementsItems()
        })
        .catch((e) => { })
        .finally(() => { });
      }
    },
    handleDragOver(e) {
      e.preventDefault();
    },
    // 点击增加
    handleClickToAddItem(index,item){
      // 如果存在设备的话则直接返回
      if(item?.deviceInfo?.id) return;
      this.$refs.equAddForm && this.$refs.equAddForm.openform();
    },
    async init_data() {
      this.$modal.loading();
      var {data} = await getBridgeInfos(this.code);
      var { data } = await getBridgeInfos(this.code);
      this.$modal.closeLoading();
      var arr = (data && data) || [];
      console.log("arr", arr);
      var currentareaconfig = mapdata[this.code] || {};
      this.bridge_infos = {};
      // var name2ip = {}
      // for(var item of this.device_list){
      //     name2ip[item.networkPort] = item.ip
@@ -684,21 +799,21 @@
        };
        console.log("bridge_infos", this.bridge_infos);
        console.log(
            "currentareaconfig",
            currentareaconfig[item.areaIndex],
            currentareaconfig["pad"]
          "currentareaconfig",
          currentareaconfig[item.areaIndex],
          currentareaconfig["pad"]
        );
        if (currentareaconfig["pad"]) {
          this.bridge_infos[item.areaIndex]["pad"] = currentareaconfig["pad"];
        }
        if (
            currentareaconfig[item.areaIndex] &&
            currentareaconfig[item.areaIndex]["pad"]
          currentareaconfig[item.areaIndex] &&
          currentareaconfig[item.areaIndex]["pad"]
        ) {
          this.bridge_infos[item.areaIndex]["pad"] =
              currentareaconfig[item.areaIndex]["pad"];
            currentareaconfig[item.areaIndex]["pad"];
        }
        // console.log('currentareaconfig',item.areaCode,currentareaconfig[item.areaCode],arr,currentareaconfig)
      }
    },
@@ -725,6 +840,7 @@
      this.serve_timer && clearInterval(this.serve_timer);
    },
    async showServe(info) {
      if (!this.hideServe) {
        this.hideServe = !this.hideServe;
        return;
@@ -733,49 +849,28 @@
      this.serve_info = {};
      this.serve_select = info;
      console.log("serve_select", this.serve_select);
      const {switchCabinet} = await getAreaServeInfo(this.code, info);
      const { switchCabinet } = await getAreaServeInfo(this.code, info);
      console.log("switchCabinet", switchCabinet);
      if (switchCabinet && switchCabinet.length > 0) {
        this.serve_info = switchCabinet[0];
        // const data = await getFaultInfo(this.code);
        // this.data_service_list = [];
        // if (data && data.faultInfo) {
        //   // this.data_service_list =  [];
        //   // time: "1-10",
        //   //   desc: "Host: SZHMESVMA557<br/>Line: IB2 FA2<br/>Overall Execution Time 2103",
        //   // status: "red",
        //   var index = 0;
        //   for (var item of data.faultInfo) {
        //     //需要根据名字过滤
        //     // console.log('item.ip == info.ip',info.ip)
        //     // if (item.ip == info.ip)
        //     {
        //       this.data_service_list.push({
        //         status: item.node == "异常" ? "red" : "green",
        //         time: ++index,
        //         desc: `${item.areaCode}/${item.portMessage}<br/>${item.cabineName}/${item.switchDeviceName}/${item.switchPort}`,
        //       });
        //     }
        //   }
        //   setTimeout(() => {
        //     this.startScrolling();
        //   }, 1000);
        // }
        // console.log("data_service_list", this.data_service_list);
      }
      this.hideServe = false;
      // console.log("showServe", this.hideServe);
      this.$modal.closeLoading();
    },
    showDeviceInfo(index, item,event) {
      event.stopPropagation(); // 阻止事件冒泡
      this.selectedIndex = index
      this.show_device_info = !this.show_device_info
      this.cur_device_info = item.deviceInfo
    },
  },
};
</script>
<style lang="scss" scoped>
@import "../../common/itm_svg.scss";
@import "../../common/area-bg.scss";
@import "@/common/itm_svg.scss";
@import "@/common/area-bg.scss";
$width-screen1: 174.17rem;
@@ -787,7 +882,6 @@
  left: 0;
  right: 0; */
  /* background-color: rgba(209, 227, 247, 1); */
  // overflow: hidden;
  margin: 0 auto;
  margin-bottom: 5rem;
@@ -810,290 +904,12 @@
    }
  }
  .serve-item {
    margin: 0 auto;
    display: flex;
    width: fit-content;
    cursor: pointer;
    .serve-img {
      margin-right: 2rem;
      background-image: url("../../assets/equipment/serve.svg");
      background-image: url("../../assets/equipment/serve_v2.png");
      background-size: 100% 100%;
      width: 30.3rem;
      height: 62.3rem;
      /* padding-left: 1rem; */
      .each-item-container {
        margin-top: 21rem;
        margin-left: 3rem;
        .each-item {
          background-image: url("../../assets/equipment/serve_item.png");
          width: 18.9rem;
          height: 4.8rem;
          background-size: 100% 100%;
          margin-bottom: 0.9rem;
          color: #265696;
          position: relative;
          .desc {
            text-align: left;
            padding-left: 1rem;
            padding-top: 0.5rem;
            .title {
              font-weight: 600;
              margin-bottom: 0.8rem;
              /* */
            }
            .value {
            }
          }
        }
        .each-item:hover::before {
          position: absolute;
          left: 0;
          right: 0;
          top: 0;
          bottom: 0;
          content: "";
          background-color: #059ce293;
        }
        .each-item-default::before {
          position: absolute;
          left: 0;
          right: 0;
          top: 0;
          bottom: 0;
          content: "";
          background-color: #4bb6e854;
        }
        .tip-msg {
          display: none;
          position: absolute;
          left: calc(50% + 5rem); //起始是在body中,横向距左50%的位置
          top: 55%; //起始是在body中,纵向距上50%的位置,这个点相当于body的中心点,div的左上角的定位
          min-width: 21rem;
          height: 13.6rem;
          background: #f1f9ff;
          box-shadow: 0.6rem 0.4rem 2.4rem 0rem rgba(56, 92, 131, 0.77);
          border-radius: 0.6rem;
          z-index: 2;
          padding: 1.3rem;
          .title {
            font-size: 2.5rem;
            font-family: PingFangSC-Semibold, PingFang SC;
            font-weight: 600;
            color: #012b5e;
            line-height: 3.6rem;
            text-align: left;
            margin-bottom: 1rem;
            text-overflow: ellipsis;
            /* width: 10rem; */
            overflow: hidden;
            word-break: break-all;
            white-space: nowrap;
            .dot {
              width: 1.6rem;
              height: 1.6rem;
              min-width: 1.6rem;
              min-height: 1.6rem;
              /* background: #e20505; */
              border-radius: 50%;
              margin-top: 1rem;
              margin-right: 0.5rem;
            }
          }
          .desc {
            font-size: 1.8rem;
            font-family: PingFangSC-Regular, PingFang SC;
            font-weight: 400;
            color: #666666;
            line-height: 2rem;
            text-align: left;
            /* margin-left: 2.1rem; */
            margin-top: 0.5rem;
            .f-n {
              color: #0dbe79;
              font-weight: 600;
            }
            .f-r {
              color: #e10808;
              font-weight: 600;
            }
            .f-y {
              color: #ffc310;
              font-weight: 600;
            }
          }
        }
        .each-item:hover .tip-msg {
          display: unset;
        }
      }
    }
    .tj-item {
      margin-left: 2rem;
      width: 33.5rem;
      min-height: 47.5rem;
      min-height: 17.5rem;
      height: fit-content;
      background: #f2f8fd;
      box-shadow: 0.6rem 0.4rem 2.4rem 0rem rgba(198, 212, 228, 0.38),
      inset 0rem 0.2rem 0.3rem 0rem rgba(255, 255, 255, 0.5);
      border-radius: 1rem;
      .tj-nums {
        padding: 1.8rem;
        .title {
          font-size: 2.5rem;
          font-family: PingFangSC-Semibold, PingFang SC;
          font-weight: 600;
          color: #265696;
          line-height: 3.6rem;
          text-align: left;
          margin-bottom: 1.8rem;
        }
        .equ-num-item {
          margin: 0 auto;
          text-align: center;
          .desc2 {
            font-size: 1.6rem;
            font-family: PingFangSC-Medium, PingFang SC;
            font-weight: 500;
            color: #235884;
            line-height: 2.2rem;
          }
          .num {
            font-size: 2.4rem;
            font-family: Impact;
            line-height: 2.9rem;
          }
          .num.g {
            color: #0dbe79;
          }
          .num.y {
            color: #ffc310;
          }
          .num.r {
            color: #e10808;
          }
        }
        .equ-num-item.a {
          margin-left: 0;
          margin-right: auto;
        }
        .equ-num-item.c {
          margin-right: 0;
          margin-left: auto;
        }
      }
      .tj-list {
        padding: 2.2rem;
        padding-top: 1.4rem;
        .service-list-arr {
          background-color: #f2f8fd;
          overflow: hidden;
          height: 30.3rem;
          .service-list-arr-item {
            width: 100%;
            min-height: 3rem;
            /* margin-top: 2.2rem; */
            display: flex;
            flex-direction: row;
            align-items: center;
            height: fit-content;
            .time {
              font-size: 1.2rem;
              font-family: PingFangSC-Medium, PingFang SC;
              font-weight: 500;
              color: #a1b6c8;
              line-height: 1.7rem;
              margin-right: 1rem;
            }
            .service-list-arr-item_content {
              font-family: PingFangSC-Medium, PingFang SC;
              color: #235884;
              line-height: 1.17rem;
              text-align: left;
              margin-left: 0.4rem;
              margin-right: 1.5rem;
              padding-top: 1rem;
              font-size: 1.4rem;
              font-weight: 500;
              line-height: 1.4rem;
            }
            .dot {
              width: 0.58rem;
              height: 0.58rem;
              border-radius: 50%;
              margin-top: 0.8rem;
              margin-left: auto;
              margin-right: 10px;
            }
            .dot.red {
              background: #c10b0b;
            }
            .dot.yellow {
              background: #fda928;
            }
            .dot.green {
              background: #17a537;
            }
          }
        }
      }
      .tj-line {
        width: 30.1rem;
        height: 0.1rem;
        border: 0.1rem solid #ccdeec;
        margin: 0 auto;
      }
    }
  }
  .chart-open {
    width: 6.1rem;
    height: 7.5rem;
    background: #e9f4fd;
    box-shadow: 0.6rem 0.4rem 2.4rem 0rem rgba(198, 212, 228, 0.83),
    inset 0rem 0.2rem 0.3rem 0rem rgba(255, 255, 255, 0.5);
      inset 0rem 0.2rem 0.3rem 0rem rgba(255, 255, 255, 0.5);
    border-radius: 1rem;
    position: fixed;
    right: 3rem;
@@ -1103,7 +919,7 @@
    .img-button {
      background-size: 100% 100%;
      background-image: url("../../assets/area/chart-open.svg");
      background-image: url("@/assets/area/chart-open.svg");
      width: 2.6rem;
      height: 2.6rem;
      transform: translate(-50%, -50%);
@@ -1117,43 +933,43 @@
<style scoped lang="scss">
//7个设备
.equ-0 {
  background-image: url("../../assets/equipment/arm.svg");
  background-image: url("@/assets/equipment/arm.svg");
  width: 9.6rem;
  height: 9.6rem;
}
.equ-1 {
  background-image: url("../../assets/equipment/pda.svg");
  background-image: url("@/assets/equipment/pda.svg");
  width: 4.1rem;
  height: 6.1rem;
}
.equ-2 {
  background-image: url("../../assets/equipment/pc.svg");
  background-image: url("@/assets/equipment/pc.svg");
  width: 15rem;
  height: 12.6rem;
}
.equ-3 {
  background-image: url("../../assets/equipment/print.svg");
  background-image: url("@/assets/equipment/print.svg");
  width: 8.2rem;
  height: 8.1rem;
}
.equ-4 {
  background-image: url("../../assets/equipment/screen.svg");
  background-image: url("@/assets/equipment/screen.svg");
  width: 15.9rem;
  height: 13.1rem;
}
.equ-5 {
  background-image: url("../../assets/equipment/setting.svg");
  background-image: url("@/assets/equipment/setting.svg");
  width: 7.8rem;
  height: 7.5rem;
}
.equ-6 {
  background-image: url("../../assets/equipment/video.svg");
  background-image: url("@/assets/equipment/video.svg");
  width: 12.7rem;
  height: 9.4rem;
}
@@ -1197,7 +1013,7 @@
    height: 1.6rem;
    //        background: #fff;
    //  box-shadow: 0rem -2rem 2.1rem 0rem #fff;
    background-image: url("../../assets/area/space.svg");
    background-image: url("@/assets/area/space.svg");
    background-size: 100% 100%;
    position: relative;
@@ -1217,10 +1033,10 @@
    }
    .space-text {
      background-image: url("../../assets/area/space-text.svg");
      background-size: 100% 100%;
      min-width: 6rem;
      min-height: 2.5rem;
      background-image: url("@/assets/area/space-text.svg");
      // background-size: 100% 100%;
      // min-width: 6rem;
      // min-height: 2.5rem;
      transform: translate(-50%, 0%);
      left: 50%;
      padding-top: 0.5rem;
@@ -1260,4 +1076,130 @@
.port-items:nth-child(2n) {
  margin-bottom: 8rem;
}
</style>
<style scoped>
.grid-item {
  position: absolute;
  box-sizing: border-box;
  /* border: 1px solid #ccc; 可选样式,便于查看布局 */
  display: flex;
  justify-content: center;
  align-items: center;
  border: none;
}
</style>
<style lang="scss" scoped>
.bridge-items {
  //width: 102.8rem;
  // height: 1.5rem;
  // background: #a6c6e5;
  // box-shadow: 0rem -2rem 2.1rem 0rem #89a2bd;
  display: flex;
  position: absolute;
  /* flex-wrap: wrap; */
  .bridge-item {
    background: #A6C7E3;
    flex: 1;
    margin: 0 auto;
    // min-width: 7.5rem;
    /* max-width: 6rem; */
    height: 1.3rem;
    //  background: #fff;
    //  box-shadow: 0rem -2rem 2.1rem 0rem #fff;
    background-image: url("@/assets/area/space.svg");
    background-size: 100% 100%;
    position: relative;
    .bridge-item-element {
      margin: 1 auto;
      background-image: url("@/assets/area/space.svg");
      background-repeat: no-repeat;
      /* 不重复显示图片 */
      background-position: center;
      /* 图片居中显示 */
      background-size: contain;
      /* 调整图片大小以适应容器 */
      cursor: grabbing;
      cursor: move;
    }
    .space-text {
      background-image: url("@/assets/area/space-text.svg");
      background-size: 100% 100%;
      min-width: 7.5rem;
      min-height: 2.5rem;
      transform: translate(-50%, 0%);
      left: 50%;
      padding-top: 0.5rem;
      top: -2.5rem;
      position: absolute;
      cursor: grabbing;
      cursor: move;
      /* line-height: 100%; */
      /* font-size: 12px; */
      /* span { */
      word-break: break-all;
      word-wrap: break-word;
      /*但在有些场景中,还需要加上下面这行代码*/
      white-space: normal;
      overflow-wrap: anywhere;
      /* } */
      font-size: 1rem;
      font-family: PingFangSC-Semibold, PingFang SC;
      font-weight: 600;
      color: #3299ff;
      z-index: 20;
    }
    .space-text-yellow {
      color: #e8be19;
    }
    .space-text-red {
      color: #e20909;
    }
  }
  .bridge-item-none {
    transition: box-shadow 0.3s ease;
    /* 平滑的阴影过渡效果 */
  }
  .hover-shadow:hover {
    // box-shadow: 0 4px 8px rgba(0, 0, 0, 0.3); /* 鼠标悬停时的阴影效果 */
    box-shadow: 0 6px 15px rgba(0, 0, 0, 0.5);
    /* 加深的阴影效果 */
    // box-shadow: 0 6px 15px rgba(162, 194, 221, 0.5); /* 加深的阴影效果 */
  }
  .space-drag {
    filter: unset !important;
    background-color: rgb(243, 15, 15);
    .space-text-gray {
      z-index: -1;
    }
  }
  .space-drag-start {
    background-color: rgb(243, 15, 15);
  }
}
.space-text-gray {
  .space-text {
    color: #818181 !important;
    background-image: url("@/assets/area/space-text-gray.svg") !important;
  }
}
</style>
src/views/area/switch-board.vue
@@ -1,6 +1,6 @@
<template>
  <div>
    <dv-full-screen-container>
    <!-- <dv-full-screen-container> -->
      <self-header title="ITM Device Monitoring System"></self-header>
      <server-info v-if="!hideServe" :serve_info="serve_info" :serve_select="serve_select" :code="code"></server-info>
@@ -8,7 +8,7 @@
      <div class="main-container" :style="{
        zoom: zoom_main,
        width: screen_width + 'rem',
        height: screen_height + 'rem',
        // height: screen_height + 'rem',
        // width:'100%',
        // height:'calc(100vh - 10rem)'
      }">
@@ -22,7 +22,7 @@
            :style="{
            transform: `scale(${scale_container})`,
            width: screen_width + 'rem',
            height: screen_height + 'rem',
            // height: screen_height + 'rem',
            // container_offset_x:''
            // container_offset_x:''
@@ -68,7 +68,7 @@
        <div class="back-button-left-bottom" @click="backToTop">返回</div>
        
      </div>
    </dv-full-screen-container>
    <!-- </dv-full-screen-container>oo -->
  </div>
</template>
<script>
@@ -168,14 +168,21 @@
    this.chartclose = true;
    console.log("main-container1,mounted");
    const content = document.getElementById("content");
    content.addEventListener("wheel", this.handleWheel);
    // const content = document.getElementById("content");
    // content.addEventListener("wheel", this.handleWheel);
    
    document.addEventListener("DOMContentLoaded", () => {
      const content = document.getElementById("content");
      content.addEventListener("wheel", this.handleWheel);
    });
  },
  destroyed() {
    const content = document.getElementById("content");
    content.removeEventListener("wheel", this.handleWheel);
    document.addEventListener("DOMContentLoaded", () => {
      const content = document.getElementById("content");
      content.removeEventListener("wheel", this.handleWheel);
    });
    this.stopScrolling();
  },
  methods: {
@@ -389,7 +396,7 @@
    cursor: pointer;
    max-width: 100%;
    min-height: 100vh;
    overflow: auto;
    // overflow: auto;
    .equipment-item {
      cursor: pointer;
@@ -773,8 +780,8 @@
  color: #ffffff;
  line-height: 3.9rem;
  position: fixed;
  left: 3rem;
  // bottom: 3.5rem;
  left: 1rem;
  bottom: 2rem;
  cursor: pointer;
  z-index: 99;
}
src/views/screen1/itm.vue
@@ -83,17 +83,6 @@
          </div>
        </div>
      </div>
      <div class="itm-container container-alert" style="cursor: pointer;margin-top: 1rem" @click="showSwitchBoardInfoTableAdd=true">
        <div class="flex1">
          <div class="reg-num flex">
            <span class="div1">{{ switchInfo.switchInfo && switchInfo.switchInfo.length || 0 }}</span>
            <span class="div2">个</span>
          </div>
          <div class="reg-desc">
           新增交换机
          </div>
        </div>
      </div>
      <div class="itm-container container-alert" style="cursor: pointer;margin-top: 1rem" @click="showSwitchBoardInfoTable=true">
        <div class="flex1">
          <div class="reg-num flex">
@@ -101,7 +90,7 @@
            <span class="div2">个</span>
          </div>
          <div class="reg-desc">
            交换机清单
            新增交换机
          </div>
        </div>
      </div>
@@ -117,37 +106,15 @@
            :data="switchInfo.lackSwitchInfo||[]"
            border
            style="width: 100%;max-height: 650px;overflow-y: scroll">
<!--          <el-table-column-->
<!--              fixed-->
<!--              label="index"-->
<!--              width="80"-->
<!--              type="index">-->
<!--          </el-table-column>-->
<!--          <el-table-column-->
<!--              prop="assetName"-->
<!--              label="asset name">-->
<!--          </el-table-column>-->
<!--          <el-table-column-->
<!--              prop="clentSiteCode"-->
<!--              label="clent site code"-->
<!--          >-->
<!--          </el-table-column>-->
<!--          <el-table-column-->
<!--              prop="createdTime"-->
<!--              label="created time">-->
<!--          </el-table-column>-->
<!--          <el-table-column-->
<!--              prop="dateTimeConnected"-->
<!--              label="connected datetime">-->
<!--          </el-table-column>-->
          <el-table-column
              prop="deviceName"
            <el-table-column
              prop="deviceNameDNS"
              label="device name">
          </el-table-column>
          <el-table-column
          <!-- <el-table-column
              prop="deviceNameDNS"
              label="DNS">
          </el-table-column>
          </el-table-column> -->
          <el-table-column
              prop="ipAddress"
              label="ip address">
@@ -165,66 +132,53 @@
              prop="switchType"
              label="switch type">
          </el-table-column>
          <el-table-column
              prop="cabinetName"
              label="Cabinet Name">
              <template slot-scope="scope">
                  <el-select v-model="scope.row.cabinetName" placeholder="请选择机柜" filterable clearable="" >
                    <el-option
                      v-for="item in cabinetList"
                      :key="item.id"
                      :label="item.name"
                      :value="item.id"
                      >
                    </el-option>
                  </el-select>
              </template>
          </el-table-column>
          <el-table-column
              prop="areaCode"
              label="Area Code">
              <template slot-scope="scope">
                  <el-select v-model="scope.row.areaCode" placeholder="请选择区域" filterable clearable="" >
                    <el-option
                      v-for="item in areaList"
                      :key="item.id"
                      :label="item.name"
                      :value="item.id"
                      >
                    </el-option>
                  </el-select>
              </template>
          </el-table-column>
          <el-table-column
              label="Operator">
              <template slot-scope="scope">
                <el-button
                size="mini"
                type="primary"
                @click="handleConfirm(scope.row)">确认</el-button>
            </template>
          </el-table-column>
        </el-table>
      </el-dialog>
      <!-- 新增交换机弹窗 -->
      <el-dialog :visible.sync="showSwitchBoardInfoTableAdd" title="新增交换机" append-to-body>
        <el-table
            :data="switchInfo.lackSwitchInfo||[]"
            border
            style="width: 100%;max-height: 650px;overflow-y: scroll">
<!--          <el-table-column-->
<!--              fixed-->
<!--              label="index"-->
<!--              width="80"-->
<!--              type="index">-->
<!--          </el-table-column>-->
<!--          <el-table-column-->
<!--              prop="assetName"-->
<!--              label="asset name">-->
<!--          </el-table-column>-->
<!--          <el-table-column-->
<!--              prop="clentSiteCode"-->
<!--              label="clent site code"-->
<!--          >-->
<!--          </el-table-column>-->
<!--          <el-table-column-->
<!--              prop="createdTime"-->
<!--              label="created time">-->
<!--          </el-table-column>-->
<!--          <el-table-column-->
<!--              prop="dateTimeConnected"-->
<!--              label="connected datetime">-->
<!--          </el-table-column>-->
          <el-table-column
              prop="deviceName"
              label="device name">
          </el-table-column>
          <el-table-column
              prop="deviceNameDNS"
              label="DNS">
          </el-table-column>
          <el-table-column
              prop="ipAddress"
              label="ip address">
          </el-table-column>
          <el-table-column
              width="180"
              prop="macAddress"
              label="mac address">
          </el-table-column>
          <el-table-column
              prop="nasPort"
              label="nas port">
          </el-table-column>
          <el-table-column
              prop="switchType"
              label="switch type">
          </el-table-column>
        </el-table>
      </el-dialog>
    </div>
    <div v-if="!chartclose" @click="closeself" class="chart-close"></div>
  </div>
@@ -232,6 +186,7 @@
<script>
import itmEqu from "./components/chart-itm";
import itmLine from "./components/chart-itm-line";
import {getSwitchBord,getAreaCode,AssignSwitch} from "@/api/area";
export default {
  components: {itmEqu, itmLine},
@@ -240,22 +195,72 @@
    chartclose: false,
    switchDeviceStatus: {},
    switchInfo: {},
    switchInfoAdd:{}
  },
  mounted(){
    this.getSwitchBord()
    this.getAreaCode()
  },
  data() {
    return {
      showSwitchBoardInfoTable: false,
      showSwitchBoardInfoTableAdd:false,
      cabinetList:[],
      areaList:[],
    }
  },
  methods: {
    async handleConfirm(row) {
      // 检查必填项
      if (!row.cabinetName || !row.areaCode) {
        this.$message.error('交换机柜名和区域代码不能为空');
        return;
      }
      let confirmRes= await this.$confirm('确认提交吗?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      })
      if(confirmRes=="confirm"){
        let deviceInfo = {
          deviceInfo: {
            cabinetName: row.cabinetName,
            switchName: row.deviceNameDNS,
            port: row.nasPort,
            macAddress: row.macAddress,
            ipAddress: row.ipAddress,
            areaCode: row.areaCode,
          }
        };
        let res= await AssignSwitch(deviceInfo)
        if(res.isSuccess){
          this.showSwitchBoardInfoTable=false
          this.$emit("refresh", "")
        }
      }
    },
    closeself() {
      this.$emit("show", false);
    },
    showSwitchBoard(){
      this.$router.push({path: "/switch-board"});
      // this.$router.push({path: "/area", query: {code: '01'}});
    }
    },
    getSwitchBord(){
        getSwitchBord().then((res) => {
        this.cabinetList = res.cabinetList || [];
      });
    },
    getAreaCode(){
      getAreaCode().then((res) => {
        this.areaList = res.cabinetList || [];
      });
    },
  },
};
</script>
src/views/screen1/main-container.vue
@@ -19,6 +19,8 @@
          :switchInfo="switchInfo"
          :chartclose="chartclose1"
          @show="chartclose1 = true"
          @refresh="getSwitchInfoStatic"
          :key="componentKey"
      ></itm>
      <itm-left
          v-if="areas && !chartclose2"
@@ -67,6 +69,7 @@
      chartclose2: false,
      switchDeviceStatus: {},
      switchInfo:{},
      componentKey:0,
    };
  },
  created() {
@@ -96,7 +99,16 @@
      getSwitchInfoStatic().then(res => {
        this.switchInfo = res
      })
      // this.getSwitchInfoStatic()
    },
    getSwitchInfoStatic(){
      getSwitchInfoStatic().then(res => {
        this.switchInfo = res
      })
      this.componentKey+=1
    },
    handleWheel(event) {
      event.preventDefault();
      const delta = event.deltaY < 0 ? 0.05 : -0.05;