<template>
|
<div class="main-container" :style="{
|
zoom: zoom_main,
|
width: screen_width + 'rem',
|
height: screen_height + 'rem',
|
// width:'100%',
|
// height:'calc(100vh - 10rem)'
|
}">
|
<!-- @mousemove="handleMouseMove"
|
@mouseup="handleMouseUp"
|
@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="{
|
transform: `scale(${scale_container})`,
|
width: screen_width + 'rem',
|
height: screen_height + 'rem',
|
// container_offset_x:''
|
// container_offset_x:''
|
|
'margin-left': `${container_offset_left}rem`,
|
'margin-top': `${container_offset_top}rem`,
|
}">
|
|
<!-- <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"
|
@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"
|
: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>
|
<!-- 显示图标的开关 -->
|
<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>
|
|
<div class="back-button-left-bottom" @click="backToTop">返回</div>
|
|
</div>
|
</template>
|
<script>
|
import tjContainer from "./tj-container";
|
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,
|
getFaultInfo,
|
getDeviceList,
|
updateDevicePosition,
|
getBridgeInfos,
|
delport,
|
statusPort,
|
} from "@/api/area";
|
import { getAreaTjData } from "@/api/area";
|
|
import { mapdata } from "./map-data.js";
|
import Bridge from "@/components/bridge.vue";
|
|
export default {
|
components: { tjContainer, bridge, equAddForm, Bridge, serverInfo, deviceInfo },
|
props: {
|
item_show: false,
|
code: "",
|
query_networkPort: '',
|
},
|
//根据
|
//后端存储的是世界坐标,初次时候也是世界坐标,最小单位为0.01吧,这个间距或者大小,不考虑实际像素
|
//渲染时候,需要把 坐标,变为实际rem等像素坐标
|
//每个厂房大小不一样,先用一定的数代表吧.
|
|
data() {
|
return {
|
status_indrag: false,
|
current_drag_index: undefined,
|
bridge_infos: {},
|
//如果显示服务器的话
|
hideServe: true,
|
|
html_base: 10,
|
zoom_main: 0.8,
|
width: "160",
|
height: "60",
|
//默认的视点
|
x: 0,
|
y: 0,
|
zoom: 1, //默认的缩放级别,应该保证可以容纳整个项目
|
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 },
|
],
|
|
//实际的像素比,单位rem
|
//屏幕和实际像素,默认比应该是,1:1?,反正有个比例吧,类似1米(其他单位)=多少px
|
//这个可以定死
|
screen_width: "160",
|
screen_height: "80",
|
base_move_offset: 0.6,
|
screen_margin_left: 0,
|
screen_margin_top: 0, //放大后的实际坐标-原本坐标,就是实际可以做的偏移量了,不能小于0,不能大于比例的,
|
// 当scale变化时候,的时候,恢复一下?或者scale放大的时候会有个,变化
|
|
//至于网桥,实际无非也是一组设备,到时候按照渲染出来就好了,先考虑canvas的拖拽?
|
mouse_click: undefined,
|
mouse_offset_last: undefined,
|
tleft: 20,
|
cal_offset_x: 0,
|
cal_offset_y: 0,
|
startclientX: 0, // 元素拖拽前距离浏览器的X轴位置
|
startclientY: 0, //元素拖拽前距离浏览器的Y轴位置
|
//设备列表
|
device_list: [],
|
device_list_map: {},
|
container_offset_x: 0,
|
container_offset_y: 0,
|
container_offset_left: 0,
|
container_offset_top: 0,
|
//服务器的
|
serve_timer: null,
|
serve_scroll_num: 0,
|
serve_info: {},
|
serve_select: {},
|
data_service_list: [
|
// {
|
// time: "1-10",
|
// desc: "Host: SZHMESVMA544<br/>Line: SMT26<br/>Critical",
|
// status: "red",
|
// }
|
],
|
//图标的
|
chartclose: false,
|
current_show_id: "",
|
//新增的
|
areas: [],
|
activateSwitchPorts: {},
|
switchAllDetialInfos: [],
|
dialog_activateSwitchPorts: false,
|
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;
|
console.log(this.$route, this.$router);
|
if (zoom) {
|
this.zoom_main = parseFloat(zoom);
|
}
|
this.x = parseFloat(this.width) / 2;
|
this.y = parseFloat(this.height) / 2;
|
this.screen_width = parseFloat(this.screen_width) * this.zoom;
|
this.screen_height = parseFloat(this.screen_height) * this.zoom;
|
},
|
async mounted() {
|
console.log("main-container1,mounted");
|
const content = document.getElementById("content");
|
content.addEventListener("wheel", this.handleWheel);
|
//获取到此区域的全部信息
|
this.device_list = [];
|
if (this.code) {
|
// var re = await getDeviceList(this.code);
|
// console.log("re", re);
|
// this.device_list = re.switchDetialInfos || [];
|
// await this.init_data();
|
this.update_map();
|
}
|
|
getAreaTjData().then((res) => {
|
// console.log('areas',res.switchAreaInfo || [])
|
this.areas = res.switchAreaInfo || [];
|
});
|
|
// 根据屏幕初始化格子
|
this.initializeElements(); // 在组件加载时初始化 elements
|
// 初始化设备信息
|
this.handleBindElementsItems()
|
},
|
destroyed() {
|
const content = document.getElementById("content");
|
content.removeEventListener("wheel", this.handleWheel);
|
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);
|
},
|
async statusPort(info) {
|
//设置状态为正常
|
console.log("statusPort", info);
|
// return
|
var json = {
|
id: info.id,
|
operateType: 0,
|
networkPort: info.name,
|
};
|
this.$modal.loading("更新中");
|
|
const data = await statusPort(json);
|
|
this.$modal.closeLoading();
|
|
this.update_map();
|
},
|
async delPort(info) {
|
|
var json = {
|
id: info.id,
|
operateType: 4,
|
networkPort: info.name,
|
};
|
this.$modal.loading("删除中");
|
|
const data = await delport(json);
|
|
this.$modal.closeLoading();
|
|
// 根据屏幕初始化格子
|
this.initializeElements(); // 在组件加载时初始化 elements
|
// 初始化设备信息
|
this.handleBindElementsItems()
|
},
|
backToTop() {
|
if (!this.hideServe) {
|
this.hideServe = !this.hideServe;
|
return;
|
}
|
this.$router.push({ path: "/area-all" });
|
},
|
async update_map() {
|
this.$modal.loading("加载中");
|
var re = await getDeviceList(this.code);
|
this.device_list = re.switchDetialInfos || [];
|
await this.init_data();
|
this.$modal.closeLoading();
|
if (this.query_networkPort && this.bridge_infos && this.first_query_ip) {
|
this.first_query_ip = false
|
|
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()
|
}
|
}
|
}
|
}
|
}
|
}
|
},
|
click_item(id) {
|
this.current_show_id = id;
|
},
|
click_item_add(locInfo) {
|
console.log("this.$refs.equAddForm", this.$refs.equAddForm);
|
this.$refs.equAddForm && this.$refs.equAddForm.openform(locInfo);
|
},
|
async showServeInfo(info) {
|
|
//展示交换机全部端口
|
console.log("showServeInfo", info);
|
//弹出框展示全部端口,并且每个端口的情况
|
//获取一下信息
|
this.$modal.loading("加载中");
|
const res = await getDeviceList(this.code, info.cabinetName);
|
this.$modal.closeLoading();
|
console.log("serveinfo", res);
|
// this.activateSwitchPorts = res.switchDetialInfos || [];
|
this.activateSwitchPorts = {};
|
//分两行,每行24个
|
this.switchAllDetialInfos = res.switchAllDetialInfos || []
|
var activaePorts = {};
|
if (res.switchDetialInfos) {
|
for (var item of res.switchDetialInfos) {
|
if (item.port) activaePorts[item.port] = item;
|
}
|
}
|
console.log("activaePorts", activaePorts);
|
for (var i = 0; i <= 47; i++) {
|
var level = "" + parseInt(i / 24);
|
if (!this.activateSwitchPorts["" + level]) {
|
this.activateSwitchPorts["" + level] = [];
|
}
|
this.activateSwitchPorts["" + level].push({
|
index: "" + (i + 1),
|
name: "",
|
info: activaePorts["" + (i + 1)] || undefined,
|
});
|
}
|
// console.log("this.activateSwitchPorts", this.activateSwitchPorts);
|
this.dialog_activateSwitchPorts = true;
|
},
|
closeself() {
|
console.log("closeself parent");
|
this.chartclose = true;
|
},
|
update_status_indrag(result, currentid) {
|
this.status_indrag = result;
|
this.current_drag_index = currentid;
|
},
|
refresh_canvas() {
|
//根据缩放比,视觉角度,来做渲染?,或者说,最简单的,直接都展示出来,缩放下面的?然后超出的不展示即可?
|
},
|
handleMouseMove(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.clientX - this.mouse_offset_last.clientX;
|
var offsety = event.clientY - this.mouse_offset_last.clientY;
|
// console.log("offset0", offsetx, offsety);
|
var soffsetx = offsetx > 0 ? offsetx : -offsetx;
|
var soffsety = offsety > 0 ? offsety : -offsety;
|
if (soffsety >= soffsetx) {
|
offsetx = 0;
|
} else {
|
offsety = 0;
|
}
|
|
// console.log("offsetx", offsetx, offsety);
|
// this.tleft += offset * 0.1;
|
// this.cal_offset_x += offset;
|
// console.log('offset', event.offsetX - this.mouse_offset_last.offsetX)
|
if (event.target.id == "content") {
|
//让看板内部有偏移量
|
if (offsetx != 0) {
|
if (offsetx > 0) {
|
this.container_offset_left +=
|
this.base_move_offset * this.scale_container;
|
} else {
|
this.container_offset_left -=
|
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;
|
} else {
|
console.log("mul container_offset_top");
|
|
this.container_offset_top -=
|
this.base_move_offset * this.scale_container;
|
}
|
}
|
|
}
|
}
|
this.mouse_offset_last = event;
|
}
|
},
|
handleMouseUp(event) {
|
// console.log("handleMouseUp", event);
|
if (this.mouse_click) {
|
if (this.mouse_click.className == "equipment-item") {
|
//说明是转移视角的
|
//可能就是设备的
|
//直接修改坐标就行了
|
//计算鼠标偏移量,然后转换为屏幕坐标,再转换为显示单位坐标,同时弹出提示?是否要更改吧,更改就调用接口
|
if (
|
this.mouse_offset_last &&
|
(this.cal_offset_x || this.cal_offset_y)
|
) {
|
console.log("update?", this.tleft);
|
alert("是否要修改设备坐标");
|
}
|
} else {
|
}
|
}
|
|
this.mouse_click = undefined;
|
this.mouse_offset_last = undefined;
|
},
|
|
handleMouseDown(event) {
|
|
if (event.target.className.indexOf("equipment-item") >= 0) {
|
|
} else if (event.target.id == "content") {
|
this.mouse_click = event.target;
|
}
|
},
|
handleMouseLeave(event) {
|
|
this.mouse_click = undefined;
|
this.mouse_offset_last = undefined;
|
},
|
|
handleWheel(event) {
|
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_top =
|
this.container_offset_top /
|
(this.scale_container / (delta + this.scale_container));
|
|
this.scale_container += delta;
|
if (this.scale_container < 0.2) {
|
this.scale_container = 0.2;
|
}
|
if (this.scale_container <= 1) {
|
this.container_offset_left = 0;
|
this.container_offset_top = 0;
|
}
|
},
|
dragstart(e, index) {
|
console.log(e);
|
this.dragSource = index; // 记录拖拽的源元素
|
console.log("start", e);
|
console.log("拖拽事件开始", index)
|
console.log(this.elements[index])
|
},
|
// 拖拽完成事件
|
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;
|
|
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(() => {
|
});
|
},
|
|
/**两个元素交换位置 */
|
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);
|
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
|
// }
|
// console.log('name2ip',name2ip)
|
for (var item of arr) {
|
if (item.areaCellRow) {
|
for (var each of item.areaCellRow) {
|
each.datamap = {};
|
//需要遍历,然后设置进去
|
if (each.areaPosition) {
|
for (var cell of each.areaPosition) {
|
// var ip = name2ip[cell.networkPort] || ''
|
var tid = "";
|
var status = 0;
|
var cabinetName = "";
|
var switchName = "";
|
for (var itemvv of this.device_list) {
|
if (itemvv.networkPort == cell.networkPort) {
|
tid = itemvv.id;
|
cabinetName = itemvv.cabinetName || "";
|
status = itemvv.statusInt || 0;
|
switchName = itemvv.switchName || "";
|
break;
|
}
|
}
|
|
each.datamap["" + cell.networkPortRow] = {
|
name: cell.networkPort,
|
cabinetName: cabinetName,
|
id: tid,
|
status: status,
|
switchName: switchName,
|
};
|
}
|
}
|
|
each.width = each.dataRow || "";
|
// console.log('cell',cell)
|
}
|
}
|
|
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("bridge_infos", this.bridge_infos);
|
console.log(
|
"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"]
|
) {
|
this.bridge_infos[item.areaIndex]["pad"] =
|
currentareaconfig[item.areaIndex]["pad"];
|
}
|
|
}
|
},
|
|
startScrolling() {
|
this.stopScrolling();
|
const myDiv = document.getElementById("my_serve_info_list");
|
this.serve_timer = setInterval(() => {
|
if (myDiv) {
|
myDiv.scrollTo(0, this.serve_scroll_num);
|
this.serve_scroll_num++;
|
if (myDiv.scrollTop >= myDiv.scrollHeight - myDiv.clientHeight) {
|
this.serve_timer && clearInterval(this.serve_timer);
|
this.serve_timer = null;
|
setTimeout(() => {
|
this.serve_scroll_num = 0;
|
this.startScrolling();
|
}, 1500);
|
}
|
}
|
}, 20);
|
},
|
stopScrolling() {
|
this.serve_scroll_num = 0;
|
this.serve_timer && clearInterval(this.serve_timer);
|
},
|
async showServe(info) {
|
|
if (!this.hideServe) {
|
this.hideServe = !this.hideServe;
|
return;
|
}
|
this.$modal.loading();
|
this.serve_info = {};
|
this.serve_select = info;
|
console.log("serve_select", this.serve_select);
|
const { switchCabinet } = await getAreaServeInfo(this.code, info);
|
console.log("switchCabinet", switchCabinet);
|
if (switchCabinet && switchCabinet.length > 0) {
|
this.serve_info = switchCabinet[0];
|
}
|
|
this.hideServe = false;
|
|
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";
|
|
$width-screen1: 174.17rem;
|
|
.main-container {
|
/* position: fixed;
|
right: calc(5rem);
|
top: calc($height-header - 8rem);
|
left: calc((100% - $width-screen1 - 10rem - 18rem) / 2);
|
left: 0;
|
right: 0; */
|
/* background-color: rgba(209, 227, 247, 1); */
|
// overflow: hidden;
|
margin: 0 auto;
|
margin-bottom: 5rem;
|
|
.equipments-container {
|
background: #d3e3f3;
|
position: relative;
|
margin: 0 auto;
|
cursor: pointer;
|
max-width: 100%;
|
max-height: 100vh;
|
|
.equipment-item {
|
cursor: pointer;
|
position: absolute;
|
width: 5rem;
|
height: 5rem;
|
background-size: 100% 100%;
|
filter: drop-shadow(2px 2px 2px rgba(0, 0, 0, 0.2));
|
}
|
}
|
|
.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);
|
border-radius: 1rem;
|
position: fixed;
|
right: 3rem;
|
top: 50%;
|
transform: translate(0%, 50%);
|
cursor: pointer;
|
|
.img-button {
|
background-size: 100% 100%;
|
background-image: url("@/assets/area/chart-open.svg");
|
width: 2.6rem;
|
height: 2.6rem;
|
transform: translate(-50%, -50%);
|
left: 50%;
|
top: 50%;
|
position: absolute;
|
}
|
}
|
}
|
</style>
|
<style scoped lang="scss">
|
//7个设备
|
.equ-0 {
|
background-image: url("@/assets/equipment/arm.svg");
|
width: 9.6rem;
|
height: 9.6rem;
|
}
|
|
.equ-1 {
|
background-image: url("@/assets/equipment/pda.svg");
|
width: 4.1rem;
|
height: 6.1rem;
|
}
|
|
.equ-2 {
|
background-image: url("@/assets/equipment/pc.svg");
|
width: 15rem;
|
height: 12.6rem;
|
}
|
|
.equ-3 {
|
background-image: url("@/assets/equipment/print.svg");
|
width: 8.2rem;
|
height: 8.1rem;
|
}
|
|
.equ-4 {
|
background-image: url("@/assets/equipment/screen.svg");
|
width: 15.9rem;
|
height: 13.1rem;
|
}
|
|
.equ-5 {
|
background-image: url("@/assets/equipment/setting.svg");
|
width: 7.8rem;
|
height: 7.5rem;
|
}
|
|
.equ-6 {
|
background-image: url("@/assets/equipment/video.svg");
|
width: 12.7rem;
|
height: 9.4rem;
|
}
|
</style>
|
<style scoped lang="scss">
|
.back-button-left-bottom {
|
width: 10.6rem;
|
height: 3.9rem;
|
background: #6eb3ff;
|
border-radius: 0.4rem;
|
border: 0.2rem solid #278afa;
|
font-size: 1.6rem;
|
font-family: PingFangSC-Semibold, PingFang SC;
|
font-weight: 600;
|
color: #ffffff;
|
line-height: 3.9rem;
|
position: fixed;
|
left: 3rem;
|
bottom: 3.5rem;
|
cursor: pointer;
|
z-index: 99;
|
}
|
</style>
|
|
<!-- 交换机的端口 -->
|
<style scoped lang="scss">
|
.port-items {
|
display: flex;
|
margin-bottom: 8rem;
|
/* height: 2rem; */
|
width: fit-content;
|
|
.port-item {
|
background: #e9f4fd;
|
border-top: 5px solid #e9f4fd;
|
flex: 1;
|
margin: 0 auto;
|
min-width: 6rem;
|
max-width: 6rem;
|
/* max-width: 6rem; */
|
height: 1.6rem;
|
// background: #fff;
|
// box-shadow: 0rem -2rem 2.1rem 0rem #fff;
|
background-image: url("@/assets/area/space.svg");
|
background-size: 100% 100%;
|
position: relative;
|
|
.port-tip {
|
position: absolute;
|
bottom: -2.5rem;
|
height: 2.5rem;
|
font-size: 1.8rem;
|
font-family: PingFangSC-Semibold, PingFang SC;
|
font-weight: 600;
|
color: #265696;
|
line-height: 2.5rem;
|
text-align: center;
|
/* margin-bottom: 0.5rem; */
|
left: 0;
|
right: 0;
|
}
|
|
.space-text {
|
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;
|
top: -2.5rem;
|
position: absolute;
|
/* 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;
|
}
|
}
|
|
.port-item:nth-child(6n) {
|
margin-right: 3rem;
|
}
|
}
|
|
.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>
|