<template>
|
<div>
|
<dv-full-screen-container>
|
<self-header title="ITM Device Monitoring System"></self-header>
|
<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="serve-item" @click="showCabinetName">
|
<div class="serve-img"
|
v-for="(serverInfo, serverItemindex) in switchCabinets.switchCabinet" :key="serverItemindex"
|
>
|
<div class="cabinetNameDesc">{{ serverInfo.cabinetName }} </div>
|
<div class="each-item-container">
|
<div v-for="(serve, itemindex) in serverInfo.cabinetInfoStatic" @click="showServeInfo(serve)" :key="itemindex"
|
class="each-item"
|
|
>
|
<div class="desc">
|
<div class="title">{{ serve.cabinetName }}</div>
|
<div class="value">设备数量: {{ serve.normal }}</div>
|
<div class="tip-msg">
|
<div class="title">{{ serve.cabinetName }}</div>
|
<div class="desc">正常设备:<span class="f-n">{{ serve.normal || 0 }}</span></div>
|
<div class="desc">黄色预警:<span class="f-y">{{ serve.waring || 0 }}</span></div>
|
<div class="desc">红色预警:<span class="f-r">{{ serve.exception || 0 }}</span></div>
|
|
|
</div>
|
</div>
|
</div>
|
</div>
|
</div>
|
</div>
|
|
</div>
|
|
<!-- 显示图标的开关 -->
|
<div v-if="true && code && chartclose" class="chart-open" @click="chartclose = false">
|
<div class="img-button"></div>
|
</div>
|
|
<div class="back-button-left-bottom" @click="backToTop">返回</div>
|
|
</div>
|
</dv-full-screen-container>
|
</div>
|
</template>
|
<script>
|
import selfHeader from "@/components/header";
|
|
import {
|
getSwitchCabinetInfo,
|
} from "@/api/area";
|
|
import {mapdata} from "./map-data.js";
|
|
|
export default {
|
components: { selfHeader, },
|
props: {
|
item_show: false,
|
code: "",
|
query_networkPort: '',
|
},
|
//根据
|
//后端存储的是世界坐标,初次时候也是世界坐标,最小单位为0.01吧,这个间距或者大小,不考虑实际像素
|
//渲染时候,需要把 坐标,变为实际rem等像素坐标
|
//每个厂房大小不一样,先用一定的数代表吧.
|
|
data() {
|
return {
|
|
//如果显示服务器的话
|
hideServe: true,
|
|
html_base: 10,
|
zoom_main: 0.8,
|
width: "160",
|
height: "60",
|
//默认的视点
|
x: 0,
|
y: 0,
|
zoom: 1, //默认的缩放级别,应该保证可以容纳整个项目
|
scale_container: 0.9,
|
|
|
//实际的像素比,单位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轴位置
|
|
container_offset_x: 0,
|
container_offset_y: 0,
|
container_offset_left: 0,
|
container_offset_top: 0,
|
//服务器的
|
serve_timer: null,
|
serve_scroll_num: 0,
|
|
//图标的
|
chartclose: false,
|
current_show_id: "",
|
//新增的
|
switchCabinets:{
|
cabinetCount:0,
|
cabinetNames:[],
|
switchCabinet:[],
|
},
|
};
|
},
|
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() {
|
|
this.init_data()
|
this.chartclose = true;
|
|
console.log("main-container1,mounted");
|
const content = document.getElementById("content");
|
content.addEventListener("wheel", this.handleWheel);
|
|
|
},
|
destroyed() {
|
const content = document.getElementById("content");
|
content.removeEventListener("wheel", this.handleWheel);
|
this.stopScrolling();
|
},
|
methods: {
|
showCabinetName(){
|
alert(111)
|
},
|
toSwitchInfo(info) {
|
this.showServe(info);
|
},
|
backToTop() {
|
if (!this.hideServe) {
|
this.hideServe = !this.hideServe;
|
return;
|
}
|
this.$router.push({path: "/area-all"});
|
},
|
|
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);
|
},
|
|
closeself() {
|
console.log("closeself parent");
|
this.chartclose = true;
|
},
|
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;
|
}
|
|
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;
|
}
|
}
|
// 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;
|
}
|
},
|
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) {
|
// 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) {
|
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;
|
}
|
},
|
|
async init_data() {
|
this.$modal.loading();
|
this.switchCabinets= await getSwitchCabinetInfo();
|
console.log("机柜信息")
|
console.log(this.switchCabinets)
|
this.$modal.closeLoading();
|
|
},
|
|
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);
|
},
|
},
|
};
|
</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%;
|
min-height: 100vh;
|
overflow: auto;
|
|
.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));
|
}
|
}
|
|
.serve-item {
|
margin: 0 auto;
|
display: flex;
|
// width: fit-content;
|
|
flex-wrap:wrap;
|
justify-content: flex-start;
|
|
cursor: pointer;
|
|
.serve-img {
|
margin: 2rem;
|
background-image: url("../../assets/equipment/serve.svg");
|
background-image: url("../../assets/equipment/serve_v2.png");
|
background-size: 100% 100%;
|
width: 15rem;
|
// height: 35.3rem;
|
|
.cabinetNameDesc{
|
margin-top: 1rem;
|
font-weight: 800;
|
// margin-bottom: 0.8rem;
|
}
|
|
/* padding-left: 1rem; */
|
.each-item-container {
|
margin-top: 10rem;
|
margin-left: 1rem;
|
|
.each-item {
|
background-image: url("../../assets/equipment/serve_item.png");
|
width: 10.3rem;
|
height: 3.7rem;
|
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);
|
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>
|