From f7ac77c7cc193502aff7e2a70f636253ada12386 Mon Sep 17 00:00:00 2001
From: 陶杰 <1378534974@qq.com>
Date: 星期二, 19 十一月 2024 10:14:52 +0800
Subject: [PATCH] 1.区域页面

---
 src/views/screen1/itm.vue            |  203 +++---
 src/utils/request-api.js             |    5 
 src/api/area.js                      |   38 +
 src/views/area/switch-board.vue      |   31 
 src/views/screen1/main-container.vue |   12 
 src/components/device-info.vue       |  287 ++++++++++
 src/views/area/main-container.vue    | 1080 ++++++++++++++++++--------------------
 7 files changed, 974 insertions(+), 682 deletions(-)

diff --git a/src/api/area.js b/src/api/area.js
index 798df58..a5c93fb 100644
--- a/src/api/area.js
+++ b/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
+    }
+  })
 }
\ No newline at end of file
diff --git a/src/components/device-info.vue b/src/components/device-info.vue
new file mode 100644
index 0000000..68cb85c
--- /dev/null
+++ b/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>
\ No newline at end of file
diff --git a/src/utils/request-api.js b/src/utils/request-api.js
index 1f8d9b2..f47277e 100644
--- a/src/utils/request-api.js
+++ b/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
 })
diff --git a/src/views/area/main-container.vue b/src/views/area/main-container.vue
index 48c0a43..9014b69 100644
--- a/src/views/area/main-container.vue
+++ b/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>
\ No newline at end of file
diff --git a/src/views/area/switch-board.vue b/src/views/area/switch-board.vue
index 0ab22da..8f72c19 100644
--- a/src/views/area/switch-board.vue
+++ b/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;
 }
diff --git a/src/views/screen1/itm.vue b/src/views/screen1/itm.vue
index abdd525..895ef4e 100644
--- a/src/views/screen1/itm.vue
+++ b/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>
diff --git a/src/views/screen1/main-container.vue b/src/views/screen1/main-container.vue
index fed0c38..5bc7659 100644
--- a/src/views/screen1/main-container.vue
+++ b/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;

--
Gitblit v1.9.3