Commit 1af7d19a authored by lei's avatar lei

fix:修复bug

parent f01a7aba
<template>
<div class="monitor-map">
<!-- 学校标记 -->
<span
v-for="(school, index) in schools"
:key="'school-' + index"
class="school-marker"
:style="{ left: school.x + 'px', top: school.y + 'px' }"
>
{{ school.name }}
</span>
<!-- 设备点位 -->
<div v-if="showEquipment">
<div
v-for="(equip, index) in equipments"
:key="'equip-' + index"
class="equipment-dot"
:class="{ warning: equip.isWarning }"
:style="{ left: equip.x + 'px', top: equip.y + 'px' }"
@click="handleEquipmentClick(equip)"
>
<div class="tooltip">
<p v-for="(monitor, i) in equip.monitors" :key="i">
{{ monitor.name }}
</p>
</div>
</div>
</div>
<!-- 摄像头点位 -->
<div v-if="showCamera">
<div
v-for="(camera, index) in cameras"
:key="'camera-' + index"
class="camera-dot"
:class="{ offline: !camera.status }"
:style="{ left: camera.x + 'px', top: camera.y + 'px' }"
@click="handleCameraClick(camera)"
/>
</div>
<!-- 切换按钮 -->
<div class="toggle-buttons">
<el-checkbox-group v-model="toggleList">
<el-checkbox label="camera">监控</el-checkbox>
<el-checkbox label="equipment">监测设备</el-checkbox>
</el-checkbox-group>
</div>
</div>
</template>
<script>
export default {
props: {
equipments: Array,
cameras: Array,
schools: Array,
},
data() {
return {
toggleList: ["camera", "equipment"],
};
},
computed: {
showCamera() {
return this.toggleList.includes("camera");
},
showEquipment() {
return this.toggleList.includes("equipment");
},
},
methods: {
handleEquipmentClick(equip) {
this.$emit("equipment-click", equip);
},
handleCameraClick(camera) {
this.$emit("camera-click", camera);
},
},
};
</script>
<style scoped>
/* 样式代码 */
</style>
<template>
<div class="real-time-list">
<vue-seamless-scroll :data="data" :class-option="classOption" class="warp">
<ul class="item">
<div
v-for="(item, index) in data"
:key="index"
:class="activeIndex === index ? 'active' : ''"
@click="handleItemClick(item, index)"
>
<li class="list-item">
<el-row :gutter="16">
<el-col :span="6">
<img :src="getIconPath(item.typeId)" class="icon" />
</el-col>
<el-col :span="10">
<p class="name">{{ item.tpName }}</p>
<p class="time">{{ item.time }}</p>
</el-col>
<el-col :span="8">
<p class="value">
{{ formatValue(item.value) }}{{ item.unit }}
</p>
</el-col>
</el-row>
</li>
</div>
</ul>
</vue-seamless-scroll>
</div>
</template>
<script>
export default {
props: {
data: Array,
activeIndex: Number,
},
data() {
return {
classOption: {
singleHeight: 110,
hoverStop: true,
autoPlay: true,
},
};
},
methods: {
getIconPath(typeId) {
return require(`@/assets/images/screen/hjjc/${typeId}.png`);
},
formatValue(value) {
return value;
},
handleItemClick(item, index) {
this.$emit("item-click", item, index);
},
},
};
</script>
<style scoped>
/* 样式代码 */
</style>
<template>
<div class="monitor-container">
<!-- 左侧实时数据列表 -->
<RealTimeDataList :data="realTimeData" @item-click="handleItemClick" />
<!-- 中间地图区域 -->
<MonitorMap
:equipments="equipments"
:cameras="cameras"
@camera-click="handleCameraClick"
/>
<!-- 右侧图表区域 -->
<div class="right-panel">
<HistoryChart title="环境监测设备" :data="envChartData" />
<HistoryChart title="视频监测设备" :data="videoChartData" />
</div>
<!-- 弹窗组件 -->
<DataDetailModal
v-if="showDetailModal"
:data="selectedData"
@close="closeModal"
/>
<VideoModal
v-if="showVideoModal"
:video="selectedVideo"
@close="closeVideoModal"
/>
</div>
</template>
<script>
// 导入组件
import RealTimeDataList from "./components/RealTimeDataList";
import MonitorMap from "./components/MonitorMap";
import HistoryChart from "./components/HistoryChart";
import DataDetailModal from "./components/DataDetailModal";
import VideoModal from "./components/VideoModal";
// 导入API
import {
fetchRealTimeData,
fetchEquipmentData,
fetchCameraData,
fetchChartData,
} from "@/api/monitor";
export default {
components: {
RealTimeDataList,
MonitorMap,
HistoryChart,
DataDetailModal,
VideoModal,
},
data() {
return {
realTimeData: [],
equipments: [],
cameras: [],
envChartData: {},
videoChartData: {},
selectedData: null,
selectedVideo: null,
showDetailModal: false,
showVideoModal: false,
};
},
async created() {
await this.loadAllData();
},
methods: {
async loadAllData() {
try {
const [realTime, equipments, cameras, charts] = await Promise.all([
fetchRealTimeData(),
fetchEquipmentData(),
fetchCameraData(),
fetchChartData(),
]);
this.realTimeData = realTime;
this.equipments = equipments;
this.cameras = cameras;
this.envChartData = charts.env;
this.videoChartData = charts.video;
} catch (error) {
console.error("数据加载失败:", error);
}
},
handleItemClick(item) {
this.selectedData = item;
this.showDetailModal = true;
},
handleCameraClick(camera) {
this.selectedVideo = camera;
this.showVideoModal = true;
},
closeModal() {
this.showDetailModal = false;
},
closeVideoModal() {
this.showVideoModal = false;
},
},
};
</script>
<style scoped>
.monitor-container {
display: flex;
height: 100vh;
}
.right-panel {
display: flex;
flex-direction: column;
width: 300px;
}
</style>
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
<div <div
class="sub-item" class="sub-item"
:class="showMenu == 1 ? 'active' : ''" :class="showMenu == 1 ? 'active' : ''"
key="rydw"
@click="changeMenu('rydw')" @click="changeMenu('rydw')"
> >
<p>人员定位</p> <p>人员定位</p>
...@@ -26,7 +27,7 @@ ...@@ -26,7 +27,7 @@
<div <div
class="sub-item" class="sub-item"
@click="changeMenu('hjjc')" @click="changeMenu('hjjc')"
key="" key="hjjc"
:class="showMenu == 2 ? 'active' : ''" :class="showMenu == 2 ? 'active' : ''"
> >
<p>监测监控</p> <p>监测监控</p>
...@@ -34,7 +35,7 @@ ...@@ -34,7 +35,7 @@
<div <div
class="sub-item" class="sub-item"
@click="changeMenu('psxt')" @click="changeMenu('psxt')"
key="" key="psxt"
:class="showMenu == 3 ? 'active' : ''" :class="showMenu == 3 ? 'active' : ''"
> >
<p>排水系统</p> <p>排水系统</p>
...@@ -42,9 +43,9 @@ ...@@ -42,9 +43,9 @@
</div> </div>
<div class="sub-header-mid"> <div class="sub-header-mid">
<div class="top-change"> <div class="top-change">
<span @click="changeMenu('home')">首页</span> <span @click="changeMenu('home')" key="home">首页</span>
<span @click="openVideo">企业宣传</span> <span @click="openVideo">企业宣传</span>
<span @click="changeMenu('tjfx')">系统分析</span> <span @click="changeMenu('tjfx')" key="tjfx">系统分析</span>
<span @click="goToSys">后台管理</span> <span @click="goToSys">后台管理</span>
</div> </div>
</div> </div>
...@@ -52,6 +53,7 @@ ...@@ -52,6 +53,7 @@
<div <div
class="sub-item" class="sub-item"
:class="showMenu == 4 ? 'active' : ''" :class="showMenu == 4 ? 'active' : ''"
key="tsj"
@click="changeMenu('tsj')" @click="changeMenu('tsj')"
> >
<p>提升机系统</p> <p>提升机系统</p>
...@@ -59,6 +61,7 @@ ...@@ -59,6 +61,7 @@
<div <div
class="sub-item" class="sub-item"
:class="showMenu == 5 ? 'active' : ''" :class="showMenu == 5 ? 'active' : ''"
key="tfxt"
@click="changeMenu('tfxt')" @click="changeMenu('tfxt')"
> >
<p>通风系统</p> <p>通风系统</p>
...@@ -66,6 +69,7 @@ ...@@ -66,6 +69,7 @@
<div <div
class="sub-item" class="sub-item"
:class="showMenu == 6 ? 'active' : ''" :class="showMenu == 6 ? 'active' : ''"
key="dlxt"
@click="changeMenu('dlxt')" @click="changeMenu('dlxt')"
> >
<p>电力系统</p> <p>电力系统</p>
......
<template>
<div>
<home
v-if="showMenu === 0"
style="position: absolute; top: 0; left: 0; right: 0; bottom: 0"
></home>
<!-- <psxt
v-if="showMenu === 3"
style="position: absolute; top: 0; left: 0; right: 0; bottom: 0"
></psxt> -->
<v-scale-screen
ref="scale-screen"
width="10390"
height="3117"
:fullScreen="false"
>
<!-- <dlxt
v-if="showMenu === 6"
style="position: absolute; top: 0; left: 0; right: 0; bottom: 0"
></dlxt> -->
<div class="container" :class="showMenu===0?'container0':''">
<!-- 头部 -->
<div class="header por">银洞坡金矿智能化综合管控平台</div>
<div class="sub-header">
<div class="sub-header-left">
<div
class="sub-item"
:class="showMenu == 1 ? 'active' : ''"
@click="changeMenu(1)"
>
<p>人员定位</p>
</div>
<div
class="sub-item"
@click="changeMenu(2)"
key=""
:class="showMenu == 2 ? 'active' : ''"
>
<p>环境监测</p>
</div>
<div
class="sub-item"
@click="changeMenu(3)"
key=""
:class="showMenu == 3 ? 'active' : ''"
>
<p>排水系统</p>
</div>
</div>
<div class="sub-header-mid">
<div class="top-change">
<span @click="changeMenu(0)">首页</span>
<span @click="openVideo">企业宣传</span>
<span @click="sysAnalysis">系统分析</span>
<span @click="goToSys">后台管理</span>
</div>
</div>
<div class="sub-header-right">
<div class="sub-item" :class="showMenu == 4 ? 'active' : ''" @click="changeMenu(4)"><p>提升机系统</p></div>
<div class="sub-item" :class="showMenu == 5 ? 'active' : ''" @click="changeMenu(5)"><p>风机系统</p></div>
<div class="sub-item" :class="showMenu == 6 ? 'active' : ''" @click="changeMenu(6)"><p>电力系统</p></div>
</div>
</div>
<!-- <rydw v-if="showMenu === 1" style="pointer-events: auto"></rydw>
<hjjc v-if="showMenu === 2" style="pointer-events: auto"></hjjc> -->
<!-- 底部 -->
<!-- <div class="footer">
</div> -->
</div>
</v-scale-screen>
</div>
</template>
<script>
// import * as echarts from "echarts";
// import { getScale } from "@/utils/tylerlcl";
import { listVideo } from "@/api/tyler/mainVideo";
import screenfull from "screenfull";
import rydw from "./items/rydw.vue";
import hjjc from "./items/hjjc.vue";
import psxt from "./items/psxt.vue";
import home from "./items/home.vue";
import dlxt from "./items/dlxt.vue";
export default {
name: "cockpit",
components: {
home,
rydw,
hjjc,
psxt,
dlxt,
},
data() {
return {
previewUrl: process.env.VUE_APP_API_TARGET,
showMenu: 0,
videoData:null,
};
},
mounted() {
this.getVideo()
if (screenfull && screenfull.enabled && !screenfull.isFullscreen) {
screenfull.request();
}
// this.areaCharts();
// this.alarm30();
},
methods: {
getVideo(){
this.videoData = null;
listVideo().then(res => {
this.videoData = this.previewUrl + res.data;
})
},
changeMenu(val) {
this.showMenu = val;
},
goToSys() {
var link = this.$router.resolve({
path: "/",
});
window.open(link.href);
return;
},
openVideo(){
window.open(this.videoData);
return;
},
sysAnalysis(){
},
},
};
</script>
<style lang="scss" scoped>
/* 标题 */
@font-face {
font-family: "ysbth";
src: url("~@/assets/font/syhtCN-Medium.ttf") format("truetype");
}
@font-face {
font-family: "number";
src: url("~@/assets/font/DS-Digital.ttf") format("truetype");
font-weight: normal;
font-style: normal;
}
.por {
position: relative;
}
.poa {
position: absolute;
}
.psxt-bg {
background: url("~@/assets/images/screen/psxt/bg.png") no-repeat center;
}
/* 基础容器 */
.container {
width: 100%;
height: 100%;
background: url("~@/assets/images/bigscreen/bg.png");
background-repeat: no-repeat;
background-position: center;
background-size: 100% 100%;
display: flex;
flex-direction: column;
padding: 0 240px;
// background-color: #08152a;
position: relative;
font-family: "SimHei";
pointer-events: none;
color: #fff;
}
.container0{
background: url("~@/assets/images/bigscreen/border.png");
background-repeat: no-repeat;
background-position: center;
background-size: 100% 100%;
}
/* 头部标题 */
.header {
// height: 80px;
text-align: center;
// margin-bottom: 20px;
// background: linear-gradient(90deg, rgba(0,72,143,0.8) 0%, rgba(0,36,71,0.6) 100%);
display: flex;
align-items: center;
justify-content: center;
// font-size: 2.5vw;
letter-spacing: 2px;
font-family: SimHei;
// font-weight: 500;
font-size: 120px;
font-weight: bold;
color: #ffffff;
line-height: 240px;
background: -webkit-gradient(
linear,
left top,
left bottom,
from(#ffffff),
color-stop(39.7216796875%, #f3f7fa),
to(#03a9ff)
);
background: linear-gradient(
180deg,
#ffffff 0%,
#f3f7fa 39.7216796875%,
#03a9ff 100%
);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
.sub-header {
display: flex;
justify-content: space-between;
padding: 0 60px;
// transform-style: preserve-3d;
perspective: 1000px;
// transform: translateZ(-10px);
pointer-events: auto;
}
.sub-header-left,
.sub-header-right {
display: flex;
justify-content: space-between;
width: 2000px;
margin-top: -150px;
.sub-item {
width: 484px;
height: auto;
background: url("~@/assets/images/bigscreen/button_normal.png") no-repeat center;
background-size: 100%;
display: flex;
justify-content: center;
align-items: center;
cursor: pointer;
&.active {
background: url("~@/assets/images/bigscreen/button_click.png") no-repeat center;
background-size: 100%;
}
p {
font-family: Source Han Sans SC;
font-weight: bold;
font-size: 68px;
color: #ffffff;
line-height: 167px;
background: linear-gradient(
180deg,
#ffffff 0%,
#f3f7fa 39.7216796875%,
#03a9ff 100%
);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
padding-bottom: 20px;
}
}
}
.sub-header-left {
transform: rotateZ(2deg);
}
.sub-header-right {
transform: rotateZ(-2deg);
}
.top-change {
width: 1967px;
height: 300px;
background: url("~@/assets/images/bigscreen/top_bg.png") no-repeat center;
margin: -130px auto 0;
display: flex;
justify-content: space-evenly;
align-items: center;
font-size: 56px;
color: #11e0ff;
span {
cursor: pointer;
text-indent: 1em;
position: relative;
margin-top: 130px;
display: block;
}
span:nth-child(1)::after {
content: "";
width: 46px;
height: 46px;
position: absolute;
background: url("~@/assets/images/bigscreen/icon1.png") no-repeat center;
background-size: 100%;
left: -4px;
top: 10px;
z-index: 20;
}
span:nth-child(2)::after {
content: "";
width: 46px;
height: 46px;
position: absolute;
background: url("~@/assets/images/bigscreen/icon2.png") no-repeat center;
left: -4px;
top: 10px;
z-index: 20;
}
span:nth-child(3)::after {
content: "";
width: 46px;
height: 46px;
position: absolute;
background: url("~@/assets/images/bigscreen/icon3.png") no-repeat center;
left: -4px;
top: 10px;
z-index: 20;
}
span:nth-child(4)::after {
content: "";
width: 46px;
height: 46px;
position: absolute;
background: url("~@/assets/images/bigscreen/icon4.png") no-repeat center;
left: -4px;
top: 10px;
z-index: 20;
}
}
::v-deep .screen-box {
pointer-events: none;
}
</style>
<template>
<div>
<!-- 主体内容 -->
<div class="main-content">
<!-- 左侧 -->
<div class="sidebar sidebar-left">
<div class="sidebar-item H917">
<div class="sub-title por"><span>环境监测实时数据 </span></div>
<div class="table-box">
<vue-seamless-scroll
ref="sssjControl"
:data="tableData1"
:class-option="classOption"
class="warp"
>
<ul class="item">
<div
:class="upWindowData.upWindowActive === i ? 'active' : ''"
style="cursor: pointer"
v-for="(item, i) in tableData1"
:key="i + 'aaa'"
@click="lookRealData(item, i)"
>
<li class="table-item">
<el-row :gutter="16">
<el-col :span="6" class="jz">
<img
class="img-class"
:src="
require(`@/assets/images/screen/hjjc/${item.typeId}.png`)
"
/>
</el-col>
<el-col :span="10">
<p class="device-name">{{ item.tpName }}</p>
<p class="device-time">{{ item.time }}</p>
</el-col>
<el-col :span="8">
<p class="device-value">
{{ item.value | capitalize }}{{ item.unit }}
</p>
</el-col>
</el-row>
</li>
</div>
</ul>
</vue-seamless-scroll>
</div>
</div>
</div>
<!-- 中间 -->
<div class="main-area">
<!--一中、二中。。。-->
<span class="main-example" style="left: 0px; top: 190px">一中</span>
<span class="main-example" style="left: 0px; top: 321px">二中</span>
<span class="main-example" style="left: 0px; top: 446px">三中</span>
<span class="main-example" style="left: 0px; top: 569px">四中</span>
<span class="main-example" style="left: 0px; top: 705px">五中</span>
<!-- 设备点位 -->
<div v-if="checkList.includes('2')">
<div
class="dot"
v-for="(item, i) in equipmentList"
:key="i + 'bbb'"
:class="item.isWarning == 1 ? 'active' : ''"
:style="{ left: item.x + 'px', top: item.y + 'px' }"
>
<div class="dot1" @click="">
<div class="tip-box">
<p
v-for="(iitem, l) in item.monitorPositionList"
:key="l + 'ccc'"
:class="iitem.isWarning == 1 ? 'active' : ''"
>
{{ iitem.equipmentName }}
<span></span>
</p>
</div>
</div>
</div>
</div>
<!--监控点位-->
<div v-if="checkList.includes('1')">
<div
class="camera-item"
v-for="(item, i) in cameraList"
:key="i + 'ddd'"
:class="item.status == 0 ? 'offline' : ''"
:style="{ left: item.x + 'px', top: item.y + 'px' }"
@click="lookVideo(item, i)"
></div>
</div>
<!-- 现实设备切换按钮 -->
<div class="toggle-button">
<el-checkbox-group v-model="checkList">
<el-checkbox label="1">监控</el-checkbox>
<el-checkbox label="2">监测设备</el-checkbox>
</el-checkbox-group>
</div>
</div>
<!-- 右侧 -->
<div class="sidebar sidebar-right">
<!-- 右上历史数据图组件 -->
<div class="sidebar-item H286 alert-analysis">
<div class="sub-title por">
<span>历史数据图</span>
</div>
<div class="sub-con histrybox">
<div class="histrubox_left">
<div class="echarts_title">
<img
src="../../../assets/images/screen/jianceshebei.png"
alt=""
class="img_class"
/>
<span>环境监测设备</span>
</div>
<div class="chart_bg"></div>
<div id="EchartsPieLeft" class="chart_box"></div>
<div class="chart_number">
<span>{{ deviceStatusNum.total }}</span>
<br />
<span>总数</span>
</div>
</div>
<div class="histrubox_right">
<div class="echarts_title">
<img
src="../../../assets/images/screen/shipingshebei.png"
alt=""
class="img_class"
/>
<span>视频监测设备</span>
</div>
<div class="chart_bg_right"></div>
<div id="EchartsPieRight" class="chart_box"></div>
<div class="chart_number_right">
<span>{{ deviceStatusNum.cameraTotal }}</span>
<br />
<span>总数</span>
</div>
</div>
</div>
</div>
<!-- 右中设备监测曲线图 -->
<div class="sidebar-item H286 alert-analysis">
<div class="sub-title por">
<span>历史数据图</span>
<span class="scroll-title">{{ rightTopLssjData.name }}</span>
</div>
<div class="sub-con">
<div class="sub-con">
<span
v-for="(item, i) in rightTopLssjData.list"
:key="i + 'aab'"
:class="i == rightTopLssjData.mark ? 'active' : ''"
>{{ item.name }}
<p class="subscript"></p>
</span>
</div>
<div class="left-chart" ref="sssj" id="sssj"></div>
</div>
</div>
<!-- 右下设备监测曲线图 -->
<div class="sidebar-item H286 alert-analysis">
<div class="sub-title por">
<span>历史数据图</span>
<span class="scroll-title">{{ rightCenterLssjData.name }}</span>
</div>
<div class="sub-con">
<div class="sub-con">
<span
v-for="(item, i) in rightCenterLssjData.list"
:key="i + 'abb'"
:class="i == rightCenterLssjData.mark ? 'active' : ''"
>{{ item.name }}
<p class="subscript"></p>
</span>
</div>
<div class="left-chart" ref="right" id="rclssj"></div>
</div>
</div>
</div>
<!-- 弹窗内容 -->
<transition name="el-fade-in">
<div v-show="upWindowData.upWindowVisible" class="up-window">
<p><span></span>{{ upWindowData.title }}</p>
<i class="el-icon-close close-button" @click="closeUpWindow"></i>
<p class="date-title">{{ upWindowData.date }}</p>
<div class="chart-box" id="chartBox"></div>
</div>
</transition>
<!--视频弹窗-->
<transition name="el-fade-in">
<div v-show="video.upWindowVisible" class="up-window video-window">
<p><span></span>{{ video.title }}</p>
<i class="el-icon-close close-button" @click="closeVideoUpWindow"></i>
<video width="800" id="player" controls></video>
</div>
</transition>
</div>
</div>
</template>
<script>
import * as echarts from "echarts";
import {
getRealData,
getRtData,
getDeviceStatus,
getDeviceData,
getRcData,
getDeviceStatusNum,
} from "@/api/tyler/hjjc";
import { listVideoTable } from "@/api/tyler/videoTable";
import ScrollTable from "@/components/Tyler/ScrollTable.vue";
import screenfull from "screenfull";
import vueSeamlessScroll from "vue-seamless-scroll";
import Highcharts from "highcharts/highcharts";
import highcharts3d from "highcharts/highcharts-3d";
highcharts3d(Highcharts);
export default {
name: "cockpit",
components: {
ScrollTable,
vueSeamlessScroll,
},
data() {
return {
// 设备实施数据弹窗
upWindowData: {
upWindowActive: "",
upWindowVisible: false,
title: "",
date: "2025-03-19",
},
// 左边列表数据
tableData1: [],
// 左侧滚动 参数
classOption: {
singleHeight: 110,
hoverStop: true,
autoPlay: true,
},
// 设备定位分类开关
checkList: ["2", "1"],
// 左侧实施数据列表
rightTopLssjData: {
list: [
{
name: "",
value: [
{
data: {
xData: {
data: [],
},
yData: {
data: [],
},
},
},
],
},
],
// 右上设备轮播下标
mark: 0,
// 右上设备轮播名称
name: "",
},
// 左侧实施数据列表
rightCenterLssjData: {
list: [
{
name: "",
value: [
{
data: {
xData: {
data: [],
},
yData: {
data: [],
},
},
},
],
},
],
// 右上设备轮播下标
mark: 0,
// 右上设备轮播名称
name: "",
},
// 中间图片数据列表
equipmentList: [
{
isWarning: 0, //是否报警
x: 85,
y: 233,
name: "一中避险硐室",
// 监测点
monitorPositionList: [
{
equipmentName: "一中避险硐室氧气", //设备名称
equipmentTy: "", //设备类型
isWarning: 0, //是否报警
},
{
equipmentName: "一中避险硐室一氧化碳", //设备名称
equipmentTy: "", //设备类型
isWarning: 0, //是否报警
},
],
},
],
//摄像头数据
cameraListPostion: [
{
status: 1, //是否在线
x: 50,
y: 150,
name: "一中码头门",
},
{
status: 1, //是否在线
x: 53,
y: 277,
name: "二中码头门",
},
{
status: 1, //是否在线
x: 82,
y: 289,
name: "二中水泵房",
},
{
status: 1, //是否在线
x: 113,
y: 297,
name: "二中避险硐室",
},
{
status: 1, //是否在线
x: 152,
y: 294,
name: "二中空压机房",
},
{
status: 1, //是否在线
x: 71,
y: 411,
name: "三中码头门",
},
],
cameraList: [],
// 视频弹窗
video: {
upWindowVisible: false,
title: "",
videoUrl: "",
},
player: null,
//highCharts配置
highChartsOption: {},
deviceStatusNum: {
//设备总数
total: 0,
//摄像头总数
cameraTotal: 0,
},
};
},
mounted() {
if (screenfull && screenfull.enabled && !screenfull.isFullscreen) {
screenfull.request();
}
// this.initEchartBox("right", this.salvProName, this.salvProValue, 28);
// this.initEchartBox("sssj", this.salvProName, this.salvProValue, 28);
getRtData().then((res) => {
this.rightTopLssjData.list = res.data || [];
this.rtPlayFun(this.rightTopLssjData);
});
getRcData().then((res) => {
this.rightCenterLssjData.list = res.data || [];
console.log(res);
this.rcPlayFun(this.rightCenterLssjData);
});
getDeviceStatus().then((res) => {
// this.equipmentList = res.data;
let dataXY = [
{
name: "三中码头门",
x: "50",
y: "406",
isWarning: 0,
monitorPositionList: [
{
equipmentName: "三中码头门风速",
equipmentTy: "风速",
isWarning: 0,
},
{
equipmentName: "三中码头门风速",
equipmentTy: "风速",
isWarning: 0,
},
],
},
{
name: "二中空压机房",
x: "258",
y: "299",
isWarning: 0,
monitorPositionList: [
{
equipmentName: "二中空压机房co",
equipmentTy: "一氧化碳500",
isWarning: 0,
},
{
equipmentName: "二中空压机房风速",
equipmentTy: "风速",
isWarning: 0,
},
],
},
{
name: "东风井",
x: "856",
y: "136",
isWarning: 0,
monitorPositionList: [
{
equipmentName: "东风井风速",
equipmentTy: "风速",
isWarning: 0,
},
{
equipmentName: "东风井开停",
equipmentTy: "开停",
isWarning: 0,
},
],
},
{
name: "二中避险硐室",
x: "75",
y: "288",
isWarning: 0,
monitorPositionList: [
{
equipmentName: "二中避险硐室co",
equipmentTy: "一氧化碳500",
isWarning: 0,
},
{
equipmentName: "二中避险硐室氧气",
equipmentTy: "氧气",
isWarning: 0,
},
],
},
{
name: "一中避险硐室",
x: "85",
y: "153",
isWarning: 0,
monitorPositionList: [
{
equipmentName: "一中避险硐室co",
equipmentTy: "一氧化碳500",
isWarning: 0,
},
{
equipmentName: "一中避险硐室氧气",
equipmentTy: "氧气",
isWarning: 0,
},
],
},
{
name: "五中避险硐室",
x: "102",
y: "677",
isWarning: 0,
monitorPositionList: [
{
equipmentName: "五中避险硐室co",
equipmentTy: "一氧化碳500",
isWarning: 0,
},
{
equipmentName: "五中避险硐室氧气",
equipmentTy: "氧气",
isWarning: 0,
},
],
},
{
name: "四中避险硐室",
x: "96",
y: "541",
isWarning: 0,
monitorPositionList: [
{
equipmentName: "四中避险硐室",
equipmentTy: "一氧化碳1000",
isWarning: 0,
},
{
equipmentName: "四中避险硐室",
equipmentTy: "氧气",
isWarning: 0,
},
],
},
{
name: "四中车场",
x: "53",
y: "527",
isWarning: 0,
monitorPositionList: [
{
equipmentName: "四中车场",
equipmentTy: "一氧化碳1000",
isWarning: 0,
},
],
},
{
name: "一中主运输巷",
x: "185",
y: "164",
isWarning: 0,
monitorPositionList: [
{
equipmentName: "一中主运输巷co",
equipmentTy: "一氧化碳500",
isWarning: 0,
},
{
equipmentName: "一中主运输巷风速",
equipmentTy: "风速",
isWarning: 0,
},
],
},
{
name: "二中主运输巷",
x: "187",
y: "296",
isWarning: 0,
monitorPositionList: [
{
equipmentName: "二中主运输巷CO",
equipmentTy: "一氧化碳1000",
isWarning: 0,
},
{
equipmentName: "二中主运输巷co",
equipmentTy: "一氧化碳500",
isWarning: 0,
},
{
equipmentName: "二中主运输巷风速",
equipmentTy: "风速",
isWarning: 0,
},
],
},
{
name: "二中中运输巷",
x: "316",
y: "303",
isWarning: 0,
monitorPositionList: [
{
equipmentName: "二中中运输巷风速",
equipmentTy: "风速",
isWarning: 0,
},
],
},
{
name: "三中避险硐室",
x: "93",
y: "411",
isWarning: 0,
monitorPositionList: [
{
equipmentName: "三中避险硐室co",
equipmentTy: "一氧化碳1000",
isWarning: 0,
},
{
equipmentName: "三中避险硐室氧气",
equipmentTy: "氧气",
isWarning: 0,
},
],
},
{
name: "五中车场",
x: "53",
y: "686",
isWarning: 0,
monitorPositionList: [
{
equipmentName: "五中车场一氧化碳",
equipmentTy: "一氧化碳1000",
isWarning: 0,
},
],
},
{
name: "一中风机",
x: "145",
y: "159",
isWarning: 0,
monitorPositionList: [
{
equipmentName: "一中风机",
equipmentTy: "一氧化碳1000",
isWarning: 0,
},
{
equipmentName: "一中风机氧气",
equipmentTy: "氧气",
isWarning: 0,
},
],
},
{
name: "一中西采区",
x: "341",
y: "192",
isWarning: 0,
monitorPositionList: [
{
equipmentName: "一中西采区CO",
equipmentTy: "一氧化碳1000",
isWarning: 0,
},
{
equipmentName: "一中西采区风速",
equipmentTy: "风速",
isWarning: 0,
},
{
equipmentName: "一中西采区风机",
equipmentTy: "开停",
isWarning: 0,
},
{
equipmentName: "一中西采区",
equipmentTy: "氧气",
isWarning: 0,
},
],
},
{
name: "三中运输巷",
x: "518",
y: "439",
isWarning: 0,
monitorPositionList: [
{
equipmentName: "三中运输巷CO",
equipmentTy: "一氧化碳1000",
isWarning: 0,
},
{
equipmentName: "三中运输巷风速",
equipmentTy: "风速",
isWarning: 0,
},
{
equipmentName: "三中运输巷风机",
equipmentTy: "开停",
isWarning: 0,
},
{
equipmentName: "三中运输巷氧气",
equipmentTy: "氧气",
isWarning: 0,
},
],
},
{
name: "三中西采",
x: "566",
y: "499",
isWarning: 0,
monitorPositionList: [
{
equipmentName: "三中西采",
equipmentTy: "一氧化碳1000",
isWarning: 0,
},
{
equipmentName: "三中西采",
equipmentTy: "风速",
isWarning: 0,
},
{
equipmentName: "三中西采",
equipmentTy: "氧气",
isWarning: 0,
},
],
},
{
name: "四中运输巷",
x: "206",
y: "559",
isWarning: 0,
monitorPositionList: [
{
equipmentName: "四中运输巷",
equipmentTy: "一氧化碳1000",
isWarning: 0,
},
{
equipmentName: "四中运输巷",
equipmentTy: "风速",
isWarning: 0,
},
{
equipmentName: "四中运输巷风机",
equipmentTy: "开停",
isWarning: 0,
},
{
equipmentName: "四中运输巷",
equipmentTy: "氧气",
isWarning: 0,
},
],
},
{
name: "五中运输巷",
x: "166",
y: "697",
isWarning: 0,
monitorPositionList: [
{
equipmentName: "五中运输巷",
equipmentTy: "一氧化碳1000",
isWarning: 0,
},
{
equipmentName: "五中运输巷",
equipmentTy: "风速",
isWarning: 0,
},
{
equipmentName: "五中运输巷风机",
equipmentTy: "开停",
isWarning: 0,
},
{
equipmentName: "五中运输巷",
equipmentTy: "氧气",
isWarning: 0,
},
],
},
{
name: "一中运输巷",
x: "367",
y: "168",
isWarning: 0,
monitorPositionList: [
{
equipmentName: "一中运输巷风机",
equipmentTy: "开停",
isWarning: 0,
},
],
},
{
name: "二中西采区",
x: "237",
y: "339",
isWarning: 0,
monitorPositionList: [
{
equipmentName: "二中西采区CO",
equipmentTy: "一氧化碳1000",
isWarning: 0,
},
{
equipmentName: "二中西采区风速",
equipmentTy: "风速",
isWarning: 0,
},
{
equipmentName: "二中西采区氧气",
equipmentTy: "氧气",
isWarning: 0,
},
],
},
{
name: "二中运输巷",
x: "415",
y: "311",
isWarning: 0,
monitorPositionList: [
{
equipmentName: "二中运输巷风机",
equipmentTy: "开停",
isWarning: 0,
},
],
},
];
if (res.data && res.data.length) {
// 使用接口数据为基础,合并本地坐标数据
this.equipmentList = res.data.map((apiItem) => {
// 在dataXY中查找同名设备
const localItem = dataXY.find((xy) => xy.name === apiItem.name);
// 合并坐标数据,保留接口返回的其他字段
return {
...apiItem,
x: localItem ? localItem.x : 0, // 默认值处理
y: localItem ? localItem.y : 0,
monitorPositionList: apiItem.monitorPositionList || [],
};
});
} else {
// 降级方案:使用本地数据
}
});
//初始化获取左侧环境监测实施数据
getRealData().then((res) => {
this.tableData1 = res.data.map((el) => {
return {
...el,
value: el.value,
};
});
});
//初始化highCharts
getDeviceStatusNum().then((res) => {
if (res.code == 200) {
this.deviceStatusNum = {
total: res.data[0].online + res.data[0].offline,
cameraTotal: res.data[1].online + res.data[1].offline,
};
this.getHighChartsData(res.data);
}
});
this.initvideoPlayer();
},
created() {
listVideoTable().then((res) => {
if (res.code == 200) {
let list = res.rows.map((el) => {
// 根据cameraName动态设置坐标
const camera = this.cameraListPostion.find(
(c) => c.name === el.cameraName
);
if (camera) {
el.x = camera.x || 0; // 使用cameraList中的placeX,如果没有则设为0
el.y = camera.y || 0; // 使用cameraList中的placeY,如果没有则设为0
}
return el;
});
this.cameraList = list;
// this.cameraList = this.cameraListPostion;
}
});
},
methods: {
initvideoPlayer() {
this.player = new WebRtcStreamer("player", "http://127.0.0.1:8000");
},
// videoPlayer(url) {
// this.player.connect(
// "rtsp://192.168.10.150:8604/EUrl/3IRr6GG?params=eyJwcm90b2NvbCI6InJ0c3AiLCJ1c2VySWQiOiJhcGkiLCJ0IjoxLCJhIjoiNWQ4MGYxZjg5N2ZkNGZjOGJkZDc2ZTVhY2NlNzVmN2R8MHwwfDF8b3Blbl9hcGkifQ=="
// );
// },
// 查看视频
lookVideo(item, i) {
this.video.upWindowVisible = true;
this.video.title = item.cameraName;
this.video.videoUrl = item.cameraUrl;
this.player.connect(this.video.videoUrl);
},
closeVideoUpWindow() {
this.video.upWindowVisible = false;
},
getHighChartsData(value = []) {
this.highChartsOption = {
chart: {
type: "pie", //饼图
options3d: {
enabled: true, //使用3d功能
alpha: 60, //延y轴向内的倾斜角度
beta: 0,
},
backgroundColor: "rgba(64, 158, 255, 0)", // 不显示背景色
// spacingTop: -200, // 增加顶部间距
},
legend: {
enabled: true,
align: "center",
verticalAlign: "middle", // 修正为底部对齐
layout: "vertical", // 水平布局
y: 60, // 下移图例
itemStyle: {
color: "#fff",
fontSize: "12px", // 缩小字体
},
labelFormatter: function () {
return `${this.name}: ${this.y}`; // 在图例中显示数据
},
},
title: {
text: "", //图表的标题文字
},
subtitle: {
text: "", //副标题文字
},
plotOptions: {
pie: {
size: "55%", // 缩小饼图尺寸
allowPointSelect: false, // 允许点击,
cursor: "pointer",
innerSize: "65%", //内圆半径,
showInLegend: false,
center: ["50%", "34%"], // 调整饼图中心位置
depth: 15, //3d饼图的厚度,
dataLabels: {
enabled: false, // 启用数据标签
},
},
},
credits: {
enabled: false,
},
series: [
{
type: "pie",
name: "设备统计",
showInLegend: true,
data: [
{
name: "正常设备",
y: value[0].online,
color: "RGBA(37, 160, 238, 1)",
}, // 高数据部分
{
name: "异常设备",
y: value[0].offline,
color: "RGBA(252, 183, 62, 1)",
}, // 低数据部分
],
startAngle: 0, //起始角度,
label: {
show: false,
position: "outside",
formatter: "{b}:{d}%",
normal: {
show: false,
fontSize: 40,
formatter: [" {a|{b}:{d}%}"].join("\n"),
rich: {
a: {
left: 20,
padding: [0, -140, 0, -180],
},
},
},
},
},
],
};
Highcharts.chart("EchartsPieLeft", this.highChartsOption);
this.highChartsOption.series[0].data = [
{ name: "在线", y: value[1].online, color: "#02CD9B" }, // 高数据部分
{ name: "离线", y: value[1].offline, color: "RGBA(252, 183, 62, 1)" }, // 低数据部分
];
Highcharts.chart("EchartsPieRight", this.highChartsOption);
},
// 辅助方法:获取字段值
getItemField(item, fieldKey) {
return item[this.fieldMap[fieldKey]] || "";
},
// 初始化eChartDOM
initEchartBox(id, xData = [], yData = [], mkData = 28, step = 4, grid) {
let maxData = yData.length ? Math.ceil(Math.max(...yData)) : 0;
let minData = yData.length ? Math.floor(Math.min(...yData)) : 0; // 添加向下取整
let myChart = null;
myChart = echarts.init(document.getElementById(id));
let option = {
grid: grid,
xAxis: {
show: true,
type: "category",
boundaryGap: false,
data: xData,
axisLabel: {
show: true,
interval: step,
textStyle: {
color: "#FFFFFF", //更改坐标轴文字颜色
fontSize: 16, //更改坐标轴文字大小
},
},
axisTick: {
alignWithLabel: true,
},
splitLine: {
//网格线
lineStyle: {
type: "dashed", //设置网格线类型 dotted:虚线 solid:实线
opacity: 0.5,
},
show: true, //隐藏或显示
},
},
yAxis: {
type: "value",
max: mkData > maxData ? mkData : maxData,
min: minData,
boundaryGap: false,
axisTick: {
alignWithLabel: true,
},
axisLabel: {
show: true,
textStyle: {
color: "#FFFFFF", //更改坐标轴文字颜色
fontSize: 16, //更改坐标轴文字大小
},
},
splitLine: {
//网格线
lineStyle: {
type: "dashed", //设置网格线类型 dotted:虚线 solid:实线
opacity: 0.5,
},
show: true, //隐藏或显示
},
},
series: [
{
type: "line",
stack: "Total",
smooth: 0.2,
lineStyle: {
width: 2,
color: "#35B1F3",
},
markLine: {
data: [
{
name: "警戒线",
yAxis: mkData,
label: {
show: false,
},
},
],
symbol: ["none", "none"],
lineStyle: {
color: "red",
width: 2,
},
},
showSymbol: false,
areaStyle: {
opacity: 0.8,
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{
offset: 0,
color: "rgb(55, 184, 251,0.5)",
},
{
offset: 1,
color: "rgb(55, 184, 251,0.1)",
},
]),
},
emphasis: {
focus: "series",
},
data: yData,
},
],
};
myChart.setOption(option);
setTimeout(() => {
myChart.resize();
}, 600);
this.$on("hook:deactivated", () => {
if (myChart != null && myChart != "" && myChart != undefined) {
myChart.dispose();
}
myChart = null;
});
},
// 轮播eChart
// 更改数据达到轮播效果
rtPlayFun(data) {
// 启动定时器,每隔 15 秒执行一次
let i = 0;
let l = 0;
let timer = null;
let grid = {
left: "4%",
right: "5%",
bottom: "4%",
top: "7%",
containLabel: true,
};
if (!timer) {
// 页面进来的时候要触发一次
this.rightTopLssjData.mark = 0;
this.rightTopLssjData.name = data.list[0].value[0].name;
this.initEchartBox(
"sssj",
data.list[0].value[0].value.xData.data,
data.list[0].value[0].value.yData.data,
data.list[0].value[0].value.yData.alarm,
4,
grid
);
}
timer = setInterval(() => {
if (i < data.list.length) {
if (
Array.isArray(data.list[i].value) &&
l < data.list[i].value.length
) {
this.rightTopLssjData.mark = i;
this.rightTopLssjData.name = data.list[i].value[l].name;
this.initEchartBox(
"sssj",
data.list[i].value[l].value.xData.data,
data.list[i].value[l].value.yData.data,
data.list[i].value[l].value.yData.alarm,
4,
grid
);
l++;
} else {
// 需要l重置,否则进不去判断i错乱
l = 0;
i++;
}
} else {
i = 0;
l = 0;
}
}, 15000);
this.$on("hook:activated", () => {
if (timer === null) {
// 避免重复开启定时器
timer = setInterval(() => {
if (i < data.list.length) {
if (
Array.isArray(data.list[i].value) &&
l < data.list[i].value.length
) {
this.rightTopLssjData.mark = i;
this.rightTopLssjData.name = data.list[i].value[l].tpName;
this.initEchartBox(
"sssj",
data.list[i].value[l].data.xData.data,
data.list[i].value[l].data.yData.data,
data.list[i].value[l].data.yData.alarm,
4,
grid
);
l++;
} else {
l = 0;
i++;
}
} else {
i = 0;
l = 0;
}
}, 15000);
}
});
this.$on("hook:deactivated", () => {
clearInterval(timer);
timer = null;
});
},
// 更改数据达到轮播效果
rcPlayFun(data) {
// 启动定时器,每隔 3 秒执行一次
let i = 0;
let l = 0;
let timer = null;
let grid = {
left: "4%",
right: "5%",
bottom: "4%",
top: "7%",
containLabel: true,
};
if (!timer) {
this.rightCenterLssjData.mark = i;
this.rightCenterLssjData.name = data.list[i].value[l].name;
this.initEchartBox(
"rclssj",
data.list[i].value[l].value.xData.data,
data.list[i].value[l].value.yData.data,
data.list[i].value[l].value.yData.alarm,
4,
grid
);
}
timer = setInterval(() => {
if (i < data.list.length) {
if (
Array.isArray(data.list[i].value) &&
l < data.list[i].value.length
) {
this.rightCenterLssjData.mark = i;
this.rightCenterLssjData.name = data.list[i].value[l].name;
this.initEchartBox(
"rclssj",
data.list[i].value[l].value.xData.data,
data.list[i].value[l].value.yData.data,
data.list[i].value[l].value.yData.alarm,
4,
grid
);
l++;
} else {
l = 0;
i++;
}
} else {
i = 0;
l = 0;
}
}, 15000);
this.$on("hook:activated", () => {
if (timer === null) {
// 避免重复开启定时器
timer = setInterval(() => {
if (i < data.list.length) {
if (
Array.isArray(data.list[i].value) &&
l < data.list[i].value.length
) {
this.rightCenterLssjData.mark = i;
this.rightCenterLssjData.name = data.list[i].value[l].tpName;
this.initEchartBox(
"rclssj",
data.list[i].value[l].value.xData.data,
data.list[i].value[l].value.yData.data,
data.list[i].value[l].value.yData.alarm,
4,
grid
);
l++;
} else {
l = 0;
i++;
}
} else {
i = 0;
l = 0;
}
}, 15000);
}
});
this.$on("hook:deactivated", () => {
clearInterval(timer);
timer = null;
});
},
//自动滚动
autoScroll() {
const divData = this.$refs.scroll_List3;
// 拿到表格中承载数据的div元素
divData.scrollTop += 1;
if (
Math.round(divData.clientHeight + divData.scrollTop) + 1 >=
divData.scrollHeight
) {
// 重置table距离顶部距离
divData.scrollTop = 0;
}
this.scrolltimer3 = window.requestAnimationFrame(
this.autoScroll.bind(this)
);
},
// 查看设备24H实时数据
lookRealData(item, i) {
let grid = {
left: 0,
right: "1.7%",
bottom: "4%",
top: "7%",
containLabel: true,
};
let xData = [];
let yData = [];
getDeviceData({ id: item.id }).then((res) => {
if (res.code == 200) {
this.upWindowData.upWindowActive = i;
this.upWindowData.upWindowVisible = true;
this.upWindowData.title = item.tpName;
this.upWindowData.date = res.data.day;
this.classOption.autoPlay = false;
let threshold = 0;
res.data.envScreenEditDto.forEach((i) => {
xData.push(i.time);
yData.push(i.value);
});
threshold = res.data.threshold || 0;
this.initEchartBox("chartBox", xData, yData, threshold, 0, grid);
} else {
this.$message.error("数据请求失败!");
}
});
},
// 关闭弹窗
closeUpWindow() {
this.upWindowData.upWindowActive = "";
this.upWindowData.upWindowVisible = false;
this.classOption.autoPlay = true;
this.$refs.sssjControl._startMove();
},
goToSys() {
var link = this.$router.resolve({
path: "/",
});
window.open(link.href);
return;
},
// 左侧 鼠标滚动代码
handleScroll(e) {
// 改变组件内部 yPos 的值,这样html的translate(0, yPos)就会随之改变
// e.deltaY是滚动的距离
this.$refs.sssjControl.yPos = this.$refs.sssjControl.yPos - e.deltaY;
// 如果是正数 说明是往上滚
if (this.$refs.sssjControl.yPos > 0) {
this.$refs.sssjControl.yPos = 0;
return;
}
// 如果yPos超过内部实际高度的一半则重新到顶部滚动
// 一半的原因是因为组件实际上创建了两个dom,以达到无缝衔接的效果
if (
Math.abs(this.$refs.sssjControl.yPos) >
this.$refs.sssjControl.realBoxHeight / 2
) {
this.$refs.sssjControl.yPos = 0;
}
},
},
filters: {
capitalize: function (value) {
if (value === null || value === undefined) return "--";
console.log(value);
if (value == "" || value == "") {
return value;
}
const parsedValue = Number(value);
if (isNaN(parsedValue)) return "--";
// 整数判断
if (Number.isInteger(parsedValue)) {
return parsedValue.toFixed(1);
}
// 小数保留两位
return parsedValue.toFixed(1);
},
},
watch: {
tableData1: {
handler() {
this.$nextTick(() => {
this.$refs.sssjControl && this.$refs.sssjControl.reset(); // 添加存在性判断
});
},
immediate: true,
},
},
};
</script>
<style lang="scss" scoped>
.por {
position: relative;
}
.sidebar-left {
transform-origin: left center;
transform: scaleX(1) perspective(610px) rotateY(5deg);
}
.sidebar-right {
transform-origin: center right;
transform: scaleX(1) perspective(610px) rotateY(-5deg);
}
/* 主体内容 */
.main-content {
display: flex;
justify-content: space-between;
padding: 0 30px;
padding-top: 160px;
background: url("~@/assets/images/screen/bg12.png");
color: #fff;
}
.histrybox {
width: 100%;
height: 100%;
display: flex;
/**均分2部分 */
.histrubox_left {
width: 50%;
height: calc(100% - 46px);
.echarts_title {
height: 25px;
text-align: center;
span {
color: rgba(42, 207, 255, 1);
font-weight: 400;
font-size: 16px;
color: #2acfff;
}
}
}
.histrubox_right {
width: 50%;
height: calc(100% - 46px);
.echarts_title {
height: 25px;
text-align: center;
span {
color: rgba(42, 207, 255, 1);
font-weight: 400;
font-size: 16px;
color: #2acfff;
}
}
}
.chart_box {
width: 100%;
height: calc(100% - 25px);
}
.img_class {
width: 29px;
height: 25px;
display: inline-block;
line-height: 25px;
margin-right: 12px;
margin-bottom: -7px;
}
.chart_bg {
position: absolute;
width: 140px;
height: 150px;
background-image: url("~@/assets/images/screen/chart.png");
background-repeat: no-repeat;
background-position: cover;
background-size: 100% 100%;
// -webkit-transform: rotateX(65deg);
transform: rotateX(53deg);
left: 45px;
top: 89px;
}
.chart_bg_right {
position: absolute;
width: 140px;
height: 150px;
background-image: url("~@/assets/images/screen/chart.png");
background-repeat: no-repeat;
background-position: cover;
background-size: 100% 100%;
// -webkit-transform: rotateX(65deg);
transform: rotateX(53deg);
left: 275px;
top: 89px;
}
.chart_number {
position: absolute;
width: 100px;
height: 100px;
top: 109px;
left: 66px;
text-align: center;
span:nth-child(1) {
font-size: 30px;
font-weight: 400;
}
}
.chart_number_right {
position: absolute;
width: 100px;
height: 100px;
top: 109px;
left: 296px;
text-align: center;
span:nth-child(1) {
font-size: 30px;
font-weight: 400;
}
}
}
/* 左右侧边栏 */
.sidebar {
width: 460px;
border-radius: 8px;
flex: 1;
// display: flex;
// flex-direction: column;
// display: grid;
grid-template-rows: repeat(3, 1fr);
gap: 2px;
margin-top: -10px;
}
.H917 {
height: 917px;
}
.H286 {
height: 286px;
}
.sidebar-item {
width: 100%;
// height: 286px;
margin-bottom: 30px;
background: linear-gradient(
180deg,
rgba(1, 33, 58, 0.2) 0%,
rgba(8, 132, 233, 0.2) 100%
);
position: relative;
&::before {
content: "";
width: 460px;
height: 4px;
position: absolute;
background: url("~@/assets/images/screen/bottom.png") no-repeat center;
left: 0;
bottom: 0;
right: 0;
z-index: 20;
}
.sub-title {
width: 100%;
height: 46px;
background: url("~@/assets/images/screen/title1.png") no-repeat center;
font-weight: bold;
font-family: "fangsong";
span {
position: absolute;
top: -10px;
left: 30px;
font-size: 22px;
}
.scroll-title {
position: absolute;
top: -7px;
left: 157px;
font-weight: 800;
font-size: 18px;
color: #ffc62e;
}
}
.table-box {
height: 866px;
width: calc(100% - 4px);
.table-item {
height: 110px;
width: calc(100% - 46px);
margin: 0 auto;
border-bottom: 2px dashed rgba(100, 194, 255, 0.3);
padding-top: 9px;
.img-class {
display: block;
width: 85px;
height: 85px;
}
.device-name {
width: 100%;
font-weight: 400;
font-size: 18px;
color: #63c2ff;
font-family: Source Han Sans SC;
height: 15px;
}
.device-time {
font-weight: 400;
font-size: 16px;
color: #b4d5ea;
font-family: Source Han Sans SC;
}
.device-value {
font-family: Source Han Sans SC;
font-weight: 500;
font-size: 28px;
color: #ffffff;
background: linear-gradient(
0deg,
#3cbffa 0%,
#ffffff 56.005859375%,
#e2f6ff 100%
);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
width: 100%;
text-align: center;
}
}
.warp {
width: 100%;
height: 100%;
overflow: hidden;
font-family: "fangzhengyaoti";
ul {
list-style: none;
margin: 0 auto;
.active {
// width: 100%;
background: RGBA(2, 87, 149, 1);
}
}
}
}
.jz {
display: flex;
align-items: center;
justify-content: center;
}
}
/* 中间主区域 */
.main-area {
width: calc(100% - 920px);
background: url("~@/assets/images/screen/bg3.png") no-repeat center;
background-size: contain;
background-position-y: 10px;
text-align: center;
position: relative;
pointer-events: auto;
z-index: 999;
.main-example {
font-size: 18px;
color: #2ed5ff;
line-height: 36px;
font-weight: bold;
position: absolute;
font-family: "fangsong";
}
.dot {
width: 42px;
height: 70px;
position: absolute;
top: 100px;
left: 500px;
background: url("~@/assets/images/screen/hjjc/icon8.png") no-repeat center;
.dot1 {
position: relative;
.tip-box {
width: 216px;
background: linear-gradient(0deg, #062451 0%, #09162d 100%);
box-shadow: 0px 15px 11px 2px rgba(0, 20, 39, 0.31);
border-radius: 4px;
border: 1px solid #11b9ff;
position: absolute;
bottom: 10px;
left: -81px;
padding: 9px 14px 14px 14px;
z-index: 999;
display: none;
p {
font-family: Source Han Sans SC;
font-weight: 400;
font-size: 16px;
color: #1cd2ff;
margin: 5px 0 0 0;
text-align: left;
span {
display: none;
}
&.active {
color: rgba(255, 43, 58, 1);
span {
display: inline-block;
width: 16px;
height: 16px;
background: url("~@/assets/images/screen/hjjc/icon10.png")
no-repeat center;
margin-bottom: -3px;
}
}
}
}
}
&:hover {
background: url("~@/assets/images/screen/hjjc/icon8_hover.png") no-repeat
center;
.tip-box {
display: block;
}
}
&.active {
background: url("~@/assets/images/screen/hjjc/icon9.png") no-repeat center;
&:hover {
background: url("~@/assets/images/screen/hjjc/icon9_hover.png")
no-repeat center;
}
}
}
.camera-item {
width: 42px;
height: 70px;
position: absolute;
top: 100px;
left: 500px;
background: url("~@/assets/images/screen/hjjc/icon_normal.png") no-repeat
center;
cursor: pointer;
&:hover {
background: url("~@/assets/images/screen/hjjc/icon_hover.png") no-repeat
center;
}
&.offline {
background: url("~@/assets/images/screen/hjjc/icon_click.png") no-repeat
center;
}
}
.toggle-button {
width: 120px;
height: 90px;
background: RGBA(8, 27, 58, 1);
position: absolute;
bottom: 58px;
right: 0px;
.el-checkbox-group {
width: 100%;
height: 100%;
.el-checkbox {
margin-top: 16px;
color: #fdfeff;
font-size: 16px;
font-weight: 500;
font-family: "fangzhengyaoti";
}
}
}
}
/* 实时分布图区域 */
.distribution-map {
height: 300px;
background: rgba(8, 28, 49, 0.8);
border-radius: 8px;
}
.sub-con {
.sub-con {
height: 2em;
width: 100%;
// display: flex;
// justify-content: space-around;
// align-items: center;
font-family: "fangzhengyaoti";
span {
float: left;
margin-left: 25px;
min-width: 63px;
height: 2em;
font-size: 16px;
line-height: 16px;
font-weight: 500;
color: rgba(179, 240, 255, 1);
text-align: center;
}
.active {
color: rgba(46, 213, 255, 1);
.subscript {
height: 19px;
width: 100%;
margin-top: 3px;
background: url("~@/assets/images/screen/hjjc/icon7.png") no-repeat
center;
}
}
}
}
.left-chart {
width: 100%;
height: 12em;
}
.sub-con-scroll-table {
width: 95%;
margin: 0 auto;
height: 83%;
overflow: hidden;
}
.custom-header {
width: 100%;
display: grid;
grid-template-columns: 1fr 1fr 1fr 2fr;
text-align: center;
color: #2ed5ff;
}
.custom-item {
width: 100%;
display: grid;
grid-template-columns: 1fr 1fr 1fr 2fr;
text-align: center;
}
.custom-header2 {
width: 100%;
display: grid;
grid-template-columns: 1.5fr 2.2fr 1.3fr;
text-align: center;
color: #2ed5ff;
height: 36px;
line-height: 36px;
color: #2ed5ff;
font-size: 16px;
font-weight: 500;
background: linear-gradient(
0deg,
rgba(61, 98, 147, 0.35) 0%,
rgba(61, 98, 147, 0.03) 100%
);
}
.warp {
height: calc(100% - 36px);
overflow: hidden;
.item {
padding-left: 0px;
margin-bottom: 0px;
margin-top: 0px;
}
.custom-item2 {
width: 100%;
height: 36px;
display: grid;
grid-template-columns: 1.5fr 2.2fr 1.3fr;
text-align: center;
background: linear-gradient(
0deg,
rgba(61, 98, 147, 0.35) 0%,
rgba(61, 98, 147, 0.03) 100%
);
margin-top: 11px;
}
.custom-item-content2 {
font-family: Source Han Sans SC;
font-size: 16px;
line-height: 36px;
color: #bbd7ea;
}
}
.sub-con-r {
width: 100%;
display: flex;
justify-content: space-evenly;
align-items: center;
height: calc(100% - 70px);
.sub-con-r-left {
width: 127px;
height: 161px;
background: url("~@/assets/images/screen/icon3.png") no-repeat center;
background-size: 100%;
}
.sub-con-r-right {
width: 250px;
display: flex;
flex-direction: column;
// gap: 10px;
p {
display: grid;
grid-template-columns: 4fr 4fr 1fr;
font-size: 18px;
line-height: 24px;
color: #bbd7ea;
background-color: rgba(61, 98, 147, 0.2);
padding: 10px 10px;
text-align: justify;
box-sizing: border-box;
span:nth-child(2) {
color: rgba(187, 215, 234, 0.2);
}
span:nth-child(3) {
font-weight: bold;
font-size: 24px;
color: #bbd7ea;
background: linear-gradient(0deg, #47c5ff 0%, #fdfeff 100%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
}
}
}
.up-window {
position: absolute;
top: 50%;
left: 50%;
width: 1360px;
height: 480px;
transform: translate(-50%, -50%);
background: url("~@/assets/images/screen/hjjc/popup.png") no-repeat;
background-size: 1377px 501px;
box-shadow: 0px 15px 11px 2px rgba(0, 20, 39, 0.31);
padding: 28px 37px;
z-index: 999;
&.video-window {
width: 900px;
height: 562px;
background: #062451;
p {
width: 820px;
}
}
p {
width: 1271px;
height: 37px;
margin: 0px;
background: url("~@/assets/images/screen/hjjc/title-popup.png") no-repeat
center;
background-size: 100%;
font-weight: 500;
font-size: 22px;
color: #ffffff;
height: 37px;
background-position-y: 9px;
span {
width: 27px;
display: inline-block;
}
}
.close-button {
font-size: 30px;
position: absolute;
top: 16px;
right: 16px;
cursor: pointer;
&:hover {
-webkit-transform: rotate(360deg);
transform: rotate(360deg);
-webkit-transition: -webkit-transform 1s linear;
transition: transform 1s linear;
}
}
.date-title {
height: 18px;
font-weight: 500;
font-size: 22px;
color: #15f1ff;
background: none;
margin-left: 56px;
margin-top: 5px;
}
.chart-box {
width: 100%;
height: 355px;
}
}
</style>
// 设备位置配置
export const EQUIPMENT_POSITIONS = [
{
name: '一中避险硐室',
x: '85',
y: '153',
monitorPositionList: [
{ equipmentName: '一中避险硐室co', equipmentTy: '一氧化碳500', isWarning: 0 },
{ equipmentName: '一中避险硐室氧气', equipmentTy: '氧气', isWarning: 0 }
]
},
{
name: '三中码头门',
x: '50',
y: '406',
isWarning: 0,
monitorPositionList: [
{ equipmentName: '三中码头门风速', equipmentTy: '风速', isWarning: 0 },
{ equipmentName: '三中码头门风速', equipmentTy: '风速', isWarning: 0 }
]
},
{
name: '二中空压机房',
x: '258',
y: '299',
isWarning: 0,
monitorPositionList: [
{ equipmentName: '二中空压机房co', equipmentTy: '一氧化碳500', isWarning: 0 },
{ equipmentName: '二中空压机房风速', equipmentTy: '风速', isWarning: 0 }
]
},
{
name: '东风井',
x: '856',
y: '136',
isWarning: 0,
monitorPositionList: [
{ equipmentName: '东风井风速', equipmentTy: '风速', isWarning: 0 },
{ equipmentName: '东风井开停', equipmentTy: '开停', isWarning: 0 }
]
},
{
name: '二中避险硐室',
x: '75',
y: '288',
isWarning: 0,
monitorPositionList: [
{ equipmentName: '二中避险硐室co', equipmentTy: '一氧化碳500', isWarning: 0 },
{ equipmentName: '二中避险硐室氧气', equipmentTy: '氧气', isWarning: 0 }
]
},
{
name: '五中避险硐室',
x: '102',
y: '677',
isWarning: 0,
monitorPositionList: [
{ equipmentName: '五中避险硐室co', equipmentTy: '一氧化碳500', isWarning: 0 },
{ equipmentName: '五中避险硐室氧气', equipmentTy: '氧气', isWarning: 0 }
]
},
{
name: '四中避险硐室',
x: '96',
y: '541',
isWarning: 0,
monitorPositionList: [
{ equipmentName: '四中避险硐室', equipmentTy: '一氧化碳1000', isWarning: 0 },
{ equipmentName: '四中避险硐室', equipmentTy: '氧气', isWarning: 0 }
]
},
{
name: '四中车场',
x: '53',
y: '527',
isWarning: 0,
monitorPositionList: [
{ equipmentName: '四中车场', equipmentTy: '一氧化碳1000', isWarning: 0 }
]
},
{
name: '一中主运输巷',
x: '185',
y: '164',
isWarning: 0,
monitorPositionList: [
{ equipmentName: '一中主运输巷co', equipmentTy: '一氧化碳500', isWarning: 0 },
{ equipmentName: '一中主运输巷风速', equipmentTy: '风速', isWarning: 0 }
]
},
{
name: '二中主运输巷',
x: '187',
y: '296',
isWarning: 0,
monitorPositionList: [
{ equipmentName: '二中主运输巷CO', equipmentTy: '一氧化碳1000', isWarning: 0 },
{ equipmentName: '二中主运输巷co', equipmentTy: '一氧化碳500', isWarning: 0 },
{ equipmentName: '二中主运输巷风速', equipmentTy: '风速', isWarning: 0 }
]
},
{
name: '二中中运输巷',
x: '316',
y: '303',
isWarning: 0,
monitorPositionList: [
{ equipmentName: '二中中运输巷风速', equipmentTy: '风速', isWarning: 0 }
]
},
{
name: '三中避险硐室',
x: '93',
y: '411',
isWarning: 0,
monitorPositionList: [
{ equipmentName: '三中避险硐室co', equipmentTy: '一氧化碳1000', isWarning: 0 },
{ equipmentName: '三中避险硐室氧气', equipmentTy: '氧气', isWarning: 0 }
]
},
{
name: '五中车场',
x: '53',
y: '686',
isWarning: 0,
monitorPositionList: [
{ equipmentName: '五中车场一氧化碳', equipmentTy: '一氧化碳1000', isWarning: 0 }
]
},
{
name: '一中风机',
x: '145',
y: '159',
isWarning: 0,
monitorPositionList: [
{ equipmentName: '一中风机', equipmentTy: '一氧化碳1000', isWarning: 0 },
{ equipmentName: '一中风机氧气', equipmentTy: '氧气', isWarning: 0 }
]
},
{
name: '一中西采区',
x: '341',
y: '192',
isWarning: 0,
monitorPositionList: [
{ equipmentName: '一中西采区CO', equipmentTy: '一氧化碳1000', isWarning: 0 },
{ equipmentName: '一中西采区风速', equipmentTy: '风速', isWarning: 0 },
{ equipmentName: '一中西采区风机', equipmentTy: '开停', isWarning: 0 },
{ equipmentName: '一中西采区', equipmentTy: '氧气', isWarning: 0 }
]
},
{
name: '三中运输巷',
x: '518',
y: '439',
isWarning: 0,
monitorPositionList: [
{ equipmentName: '三中运输巷CO', equipmentTy: '一氧化碳1000', isWarning: 0 },
{ equipmentName: '三中运输巷风速', equipmentTy: '风速', isWarning: 0 },
{ equipmentName: '三中运输巷风机', equipmentTy: '开停', isWarning: 0 },
{ equipmentName: '三中运输巷氧气', equipmentTy: '氧气', isWarning: 0 }
]
},
{
name: '三中西采',
x: '566',
y: '499',
isWarning: 0,
monitorPositionList: [
{ equipmentName: '三中西采', equipmentTy: '一氧化碳1000', isWarning: 0 },
{ equipmentName: '三中西采', equipmentTy: '风速', isWarning: 0 },
{ equipmentName: '三中西采', equipmentTy: '氧气', isWarning: 0 }
]
},
{
name: '四中运输巷',
x: '206',
y: '559',
isWarning: 0,
monitorPositionList: [
{ equipmentName: '四中运输巷', equipmentTy: '一氧化碳1000', isWarning: 0 },
{ equipmentName: '四中运输巷', equipmentTy: '风速', isWarning: 0 },
{ equipmentName: '四中运输巷风机', equipmentTy: '开停', isWarning: 0 },
{ equipmentName: '四中运输巷', equipmentTy: '氧气', isWarning: 0 }
]
},
{
name: '五中运输巷',
x: '166',
y: '697',
isWarning: 0,
monitorPositionList: [
{ equipmentName: '五中运输巷', equipmentTy: '一氧化碳1000', isWarning: 0 },
{ equipmentName: '五中运输巷', equipmentTy: '风速', isWarning: 0 },
{ equipmentName: '五中运输巷风机', equipmentTy: '开停', isWarning: 0 },
{ equipmentName: '五中运输巷', equipmentTy: '氧气', isWarning: 0 }
]
},
{
name: '一中运输巷',
x: '367',
y: '168',
isWarning: 0,
monitorPositionList: [
{ equipmentName: '一中运输巷风机', equipmentTy: '开停', isWarning: 0 }
]
},
{
name: '二中西采区',
x: '237',
y: '339',
isWarning: 0,
monitorPositionList: [
{ equipmentName: '二中西采区CO', equipmentTy: '一氧化碳1000', isWarning: 0 },
{ equipmentName: '二中西采区风速', equipmentTy: '风速', isWarning: 0 },
{ equipmentName: '二中西采区氧气', equipmentTy: '氧气', isWarning: 0 }
]
},
{
name: '二中运输巷',
x: '415',
y: '311',
isWarning: 0,
monitorPositionList: [
{ equipmentName: '二中运输巷风机', equipmentTy: '开停', isWarning: 0 }
]
}
];
// 摄像头位置配置
export const CAMERA_POSITIONS = [
{ status: 1, x: 50, y: 150, name: '一中码头门' },
{ status: 1, x: 53, y: 277, name: '二中码头门' },
{ status: 1, x: 82, y: 289, name: '二中水泵房' },
{ status: 1, x: 113, y: 297, name: '二中避险硐室' },
{ status: 1, x: 152, y: 294, name: '二中空压机房' },
{ status: 1, x: 71, y: 411, name: '三中码头门' }
];
\ No newline at end of file
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
:class="upWindowData.upWindowActive === i ? 'active' : ''" :class="upWindowData.upWindowActive === i ? 'active' : ''"
style="cursor: pointer" style="cursor: pointer"
v-for="(item, i) in tableData1" v-for="(item, i) in tableData1"
:key="i" :key="i + 'aaa'"
@click="lookRealData(item, i)" @click="lookRealData(item, i)"
> >
<li class="table-item"> <li class="table-item">
...@@ -57,10 +57,11 @@ ...@@ -57,10 +57,11 @@
<span class="main-example" style="left: 0px; top: 569px">四中</span> <span class="main-example" style="left: 0px; top: 569px">四中</span>
<span class="main-example" style="left: 0px; top: 705px">五中</span> <span class="main-example" style="left: 0px; top: 705px">五中</span>
<!-- 设备点位 --> <!-- 设备点位 -->
<div v-if="checkList.includes('2')">
<div <div
class="dot" class="dot"
v-for="(item, i) in equipmentList" v-for="(item, i) in filteredEquipmentList"
:key="i" :key="i + 'bbb'"
:class="item.isWarning == 1 ? 'active' : ''" :class="item.isWarning == 1 ? 'active' : ''"
:style="{ left: item.x + 'px', top: item.y + 'px' }" :style="{ left: item.x + 'px', top: item.y + 'px' }"
> >
...@@ -68,7 +69,7 @@ ...@@ -68,7 +69,7 @@
<div class="tip-box"> <div class="tip-box">
<p <p
v-for="(iitem, l) in item.monitorPositionList" v-for="(iitem, l) in item.monitorPositionList"
:key="l" :key="l + 'ccc'"
:class="iitem.isWarning == 1 ? 'active' : ''" :class="iitem.isWarning == 1 ? 'active' : ''"
> >
{{ iitem.equipmentName }} {{ iitem.equipmentName }}
...@@ -77,13 +78,19 @@ ...@@ -77,13 +78,19 @@
</div> </div>
</div> </div>
</div> </div>
</div>
<!--监控点位-->
<div v-if="checkList.includes('1')">
<div <div
class="camera-item" class="camera-item"
v-for="(item, i) in cameraList" v-for="(item, i) in filteredCameraList"
:key="i" :key="i + 'ddd'"
:class="item.status == 0 ? 'offline' : ''" :class="item.status == 0 ? 'offline' : ''"
:style="{ left: item.x + 'px', top: item.y + 'px' }" :style="{ left: item.x + 'px', top: item.y + 'px' }"
@click="lookVideo(item, i)"
></div> ></div>
</div>
<!-- 现实设备切换按钮 --> <!-- 现实设备切换按钮 -->
<div class="toggle-button"> <div class="toggle-button">
<el-checkbox-group v-model="checkList"> <el-checkbox-group v-model="checkList">
...@@ -146,7 +153,7 @@ ...@@ -146,7 +153,7 @@
<div class="sub-con"> <div class="sub-con">
<span <span
v-for="(item, i) in rightTopLssjData.list" v-for="(item, i) in rightTopLssjData.list"
:key="i" :key="i + 'aab'"
:class="i == rightTopLssjData.mark ? 'active' : ''" :class="i == rightTopLssjData.mark ? 'active' : ''"
>{{ item.name }} >{{ item.name }}
<p class="subscript"></p> <p class="subscript"></p>
...@@ -165,7 +172,7 @@ ...@@ -165,7 +172,7 @@
<div class="sub-con"> <div class="sub-con">
<span <span
v-for="(item, i) in rightCenterLssjData.list" v-for="(item, i) in rightCenterLssjData.list"
:key="i" :key="i + 'abb'"
:class="i == rightCenterLssjData.mark ? 'active' : ''" :class="i == rightCenterLssjData.mark ? 'active' : ''"
>{{ item.name }} >{{ item.name }}
<p class="subscript"></p> <p class="subscript"></p>
...@@ -184,6 +191,14 @@ ...@@ -184,6 +191,14 @@
<div class="chart-box" id="chartBox"></div> <div class="chart-box" id="chartBox"></div>
</div> </div>
</transition> </transition>
<!--视频弹窗-->
<transition name="el-fade-in">
<div v-show="video.upWindowVisible" class="up-window video-window">
<p><span></span>{{ video.title }}</p>
<i class="el-icon-close close-button" @click="closeVideoUpWindow"></i>
<video width="800" id="player" controls></video>
</div>
</transition>
</div> </div>
</div> </div>
</template> </template>
...@@ -197,12 +212,15 @@ import { ...@@ -197,12 +212,15 @@ import {
getRcData, getRcData,
getDeviceStatusNum, getDeviceStatusNum,
} from "@/api/tyler/hjjc"; } from "@/api/tyler/hjjc";
import { listVideoTable } from "@/api/tyler/videoTable";
import ScrollTable from "@/components/Tyler/ScrollTable.vue"; import ScrollTable from "@/components/Tyler/ScrollTable.vue";
import screenfull from "screenfull"; import screenfull from "screenfull";
import vueSeamlessScroll from "vue-seamless-scroll"; import vueSeamlessScroll from "vue-seamless-scroll";
import Highcharts from "highcharts/highcharts"; import Highcharts from "highcharts/highcharts";
import highcharts3d from "highcharts/highcharts-3d"; import highcharts3d from "highcharts/highcharts-3d";
import { EQUIPMENT_POSITIONS, CAMERA_POSITIONS } from "./hjjc-config";
highcharts3d(Highcharts); highcharts3d(Highcharts);
export default { export default {
name: "cockpit", name: "cockpit",
components: { components: {
...@@ -227,8 +245,8 @@ export default { ...@@ -227,8 +245,8 @@ export default {
autoPlay: true, autoPlay: true,
}, },
// 设备定位分类开关 // 设备定位分类开关
checkList: ["2"], checkList: ["2", "1"],
// 左侧实施数据列表 // 右侧上部分历史数据
rightTopLssjData: { rightTopLssjData: {
list: [ list: [
{ {
...@@ -247,12 +265,10 @@ export default { ...@@ -247,12 +265,10 @@ export default {
], ],
}, },
], ],
// 右上设备轮播下标
mark: 0, mark: 0,
// 右上设备轮播名称
name: "", name: "",
}, },
// 左侧实施数据列表 // 右侧中间历史数据
rightCenterLssjData: { rightCenterLssjData: {
list: [ list: [
{ {
...@@ -271,613 +287,193 @@ export default { ...@@ -271,613 +287,193 @@ export default {
], ],
}, },
], ],
// 右上设备轮播下标
mark: 0, mark: 0,
// 右上设备轮播名称
name: "", name: "",
}, },
// 设备列表
// 中间图片数据列表 equipmentList: [],
equipmentList: [
{
isWarning: 0, //是否报警
x: 85,
y: 233,
name: "一中避险硐室",
// 监测点
monitorPositionList: [
{
equipmentName: "一中避险硐室氧气", //设备名称
equipmentTy: "", //设备类型
isWarning: 0, //是否报警
},
{
equipmentName: "一中避险硐室一氧化碳", //设备名称
equipmentTy: "", //设备类型
isWarning: 0, //是否报警
},
],
},
],
//摄像头数据 //摄像头数据
cameraList: [ cameraList: [],
{ // 视频弹窗
status: 1, //是否在线 video: {
x: 50, upWindowVisible: false,
y: 150, title: "",
name: "一中码头门", videoUrl: "",
},
{
status: 1, //是否在线
x: 70,
y: 277,
name: "二中水泵房",
},
{
status: 1, //是否在线
x: 113,
y: 297,
name: "二中避险硐室",
},
{
status: 1, //是否在线
x: 152,
y: 294,
name: "二中空压机",
},
{
status: 1, //是否在线
x: 71,
y: 411,
name: "三中码头门",
}, },
], player: null,
//highCharts配置 //highCharts配置
highChartsOption: {}, highChartsOption: {},
deviceStatusNum: { deviceStatusNum: {
//设备总数
total: 0, total: 0,
//摄像头总数
cameraTotal: 0, cameraTotal: 0,
}, },
// 定时器管理
timers: {},
// ECharts实例管理
chartInstances: {},
}; };
}, },
computed: {
// 优化:计算属性替代v-if+v-for
filteredEquipmentList() {
return this.equipmentList.filter((item) => this.checkList.includes("2"));
},
filteredCameraList() {
return this.cameraList.filter((item) => this.checkList.includes("1"));
},
},
mounted() { mounted() {
if (screenfull && screenfull.enabled && !screenfull.isFullscreen) { if (screenfull && screenfull.enabled && !screenfull.isFullscreen) {
screenfull.request(); screenfull.request();
} }
// this.initEchartBox("right", this.salvProName, this.salvProValue, 28); this.initPageData();
// this.initEchartBox("sssj", this.salvProName, this.salvProValue, 28); this.initvideoPlayer();
getRtData().then((res) => {
this.rightTopLssjData.list = res.data || [];
this.rtPlayFun(this.rightTopLssjData);
});
getRcData().then((res) => {
this.rightCenterLssjData.list = res.data || [];
console.log(res);
this.rcPlayFun(this.rightCenterLssjData);
});
getDeviceStatus().then((res) => {
// this.equipmentList = res.data;
let dataXY = [
{
name: "三中码头门",
x: "50",
y: "406",
isWarning: 0,
monitorPositionList: [
{
equipmentName: "三中码头门风速",
equipmentTy: "风速",
isWarning: 0,
},
{
equipmentName: "三中码头门风速",
equipmentTy: "风速",
isWarning: 0,
},
],
},
{
name: "二中空压机房",
x: "258",
y: "299",
isWarning: 0,
monitorPositionList: [
{
equipmentName: "二中空压机房co",
equipmentTy: "一氧化碳500",
isWarning: 0,
},
{
equipmentName: "二中空压机房风速",
equipmentTy: "风速",
isWarning: 0,
},
],
},
{
name: "东风井",
x: "856",
y: "136",
isWarning: 0,
monitorPositionList: [
{
equipmentName: "东风井风速",
equipmentTy: "风速",
isWarning: 0,
},
{
equipmentName: "东风井开停",
equipmentTy: "开停",
isWarning: 0,
},
],
},
{
name: "二中避险硐室",
x: "75",
y: "288",
isWarning: 0,
monitorPositionList: [
{
equipmentName: "二中避险硐室co",
equipmentTy: "一氧化碳500",
isWarning: 0,
},
{
equipmentName: "二中避险硐室氧气",
equipmentTy: "氧气",
isWarning: 0,
},
],
},
{
name: "一中避险硐室",
x: "85",
y: "153",
isWarning: 0,
monitorPositionList: [
{
equipmentName: "一中避险硐室co",
equipmentTy: "一氧化碳500",
isWarning: 0,
},
{
equipmentName: "一中避险硐室氧气",
equipmentTy: "氧气",
isWarning: 0,
},
],
},
{
name: "五中避险硐室",
x: "102",
y: "677",
isWarning: 0,
monitorPositionList: [
{
equipmentName: "五中避险硐室co",
equipmentTy: "一氧化碳500",
isWarning: 0,
},
{
equipmentName: "五中避险硐室氧气",
equipmentTy: "氧气",
isWarning: 0,
},
],
},
{
name: "四中避险硐室",
x: "96",
y: "541",
isWarning: 0,
monitorPositionList: [
{
equipmentName: "四中避险硐室",
equipmentTy: "一氧化碳1000",
isWarning: 0,
},
{
equipmentName: "四中避险硐室",
equipmentTy: "氧气",
isWarning: 0,
},
],
},
{
name: "四中车场",
x: "53",
y: "527",
isWarning: 0,
monitorPositionList: [
{
equipmentName: "四中车场",
equipmentTy: "一氧化碳1000",
isWarning: 0,
},
],
},
{
name: "一中主运输巷",
x: "185",
y: "164",
isWarning: 0,
monitorPositionList: [
{
equipmentName: "一中主运输巷co",
equipmentTy: "一氧化碳500",
isWarning: 0,
},
{
equipmentName: "一中主运输巷风速",
equipmentTy: "风速",
isWarning: 0,
},
],
},
{
name: "二中主运输巷",
x: "187",
y: "296",
isWarning: 0,
monitorPositionList: [
{
equipmentName: "二中主运输巷CO",
equipmentTy: "一氧化碳1000",
isWarning: 0,
},
{
equipmentName: "二中主运输巷co",
equipmentTy: "一氧化碳500",
isWarning: 0,
},
{
equipmentName: "二中主运输巷风速",
equipmentTy: "风速",
isWarning: 0,
},
],
},
{
name: "二中中运输巷",
x: "316",
y: "303",
isWarning: 0,
monitorPositionList: [
{
equipmentName: "二中中运输巷风速",
equipmentTy: "风速",
isWarning: 0,
},
],
},
{
name: "三中避险硐室",
x: "93",
y: "411",
isWarning: 0,
monitorPositionList: [
{
equipmentName: "三中避险硐室co",
equipmentTy: "一氧化碳1000",
isWarning: 0,
},
{
equipmentName: "三中避险硐室氧气",
equipmentTy: "氧气",
isWarning: 0,
},
],
}, },
{ created() {
name: "五中车场", listVideoTable().then((res) => {
x: "53", if (res.code === 200) {
y: "686", this.cameraList = res.rows.map((el) => {
isWarning: 0, const camera = CAMERA_POSITIONS.find((c) => c.name === el.cameraName);
monitorPositionList: [
{
equipmentName: "五中车场一氧化碳",
equipmentTy: "一氧化碳1000",
isWarning: 0,
},
],
},
{
name: "一中风机",
x: "145",
y: "159",
isWarning: 0,
monitorPositionList: [
{
equipmentName: "一中风机",
equipmentTy: "一氧化碳1000",
isWarning: 0,
},
{
equipmentName: "一中风机氧气",
equipmentTy: "氧气",
isWarning: 0,
},
],
},
{
name: "一中西采区",
x: "341",
y: "192",
isWarning: 0,
monitorPositionList: [
{
equipmentName: "一中西采区CO",
equipmentTy: "一氧化碳1000",
isWarning: 0,
},
{
equipmentName: "一中西采区风速",
equipmentTy: "风速",
isWarning: 0,
},
{
equipmentName: "一中西采区风机",
equipmentTy: "开停",
isWarning: 0,
},
{
equipmentName: "一中西采区",
equipmentTy: "氧气",
isWarning: 0,
},
],
},
{
name: "三中运输巷",
x: "518",
y: "439",
isWarning: 0,
monitorPositionList: [
{
equipmentName: "三中运输巷CO",
equipmentTy: "一氧化碳1000",
isWarning: 0,
},
{
equipmentName: "三中运输巷风速",
equipmentTy: "风速",
isWarning: 0,
},
{
equipmentName: "三中运输巷风机",
equipmentTy: "开停",
isWarning: 0,
},
{
equipmentName: "三中运输巷氧气",
equipmentTy: "氧气",
isWarning: 0,
},
],
},
{
name: "三中西采",
x: "566",
y: "499",
isWarning: 0,
monitorPositionList: [
{
equipmentName: "三中西采",
equipmentTy: "一氧化碳1000",
isWarning: 0,
},
{
equipmentName: "三中西采",
equipmentTy: "风速",
isWarning: 0,
},
{
equipmentName: "三中西采",
equipmentTy: "氧气",
isWarning: 0,
},
],
},
{
name: "四中运输巷",
x: "206",
y: "559",
isWarning: 0,
monitorPositionList: [
{
equipmentName: "四中运输巷",
equipmentTy: "一氧化碳1000",
isWarning: 0,
},
{
equipmentName: "四中运输巷",
equipmentTy: "风速",
isWarning: 0,
},
{
equipmentName: "四中运输巷风机",
equipmentTy: "开停",
isWarning: 0,
},
{
equipmentName: "四中运输巷",
equipmentTy: "氧气",
isWarning: 0,
},
],
},
{
name: "五中运输巷",
x: "166",
y: "697",
isWarning: 0,
monitorPositionList: [
{
equipmentName: "五中运输巷",
equipmentTy: "一氧化碳1000",
isWarning: 0,
},
{
equipmentName: "五中运输巷",
equipmentTy: "风速",
isWarning: 0,
},
{
equipmentName: "五中运输巷风机",
equipmentTy: "开停",
isWarning: 0,
},
{
equipmentName: "五中运输巷",
equipmentTy: "氧气",
isWarning: 0,
},
],
},
{
name: "一中运输巷",
x: "367",
y: "168",
isWarning: 0,
monitorPositionList: [
{
equipmentName: "一中运输巷风机",
equipmentTy: "开停",
isWarning: 0,
},
],
},
{
name: "二中西采区",
x: "237",
y: "339",
isWarning: 0,
monitorPositionList: [
{
equipmentName: "二中西采区CO",
equipmentTy: "一氧化碳1000",
isWarning: 0,
},
{
equipmentName: "二中西采区风速",
equipmentTy: "风速",
isWarning: 0,
},
{
equipmentName: "二中西采区氧气",
equipmentTy: "氧气",
isWarning: 0,
},
],
},
{
name: "二中运输巷",
x: "415",
y: "311",
isWarning: 0,
monitorPositionList: [
{
equipmentName: "二中运输巷风机",
equipmentTy: "开停",
isWarning: 0,
},
],
},
];
if (res.data && res.data.length) {
// 使用接口数据为基础,合并本地坐标数据
this.equipmentList = res.data.map((apiItem) => {
// 在dataXY中查找同名设备
const localItem = dataXY.find((xy) => xy.name === apiItem.name);
// 合并坐标数据,保留接口返回的其他字段
return {
...apiItem,
x: localItem ? localItem.x : 0, // 默认值处理
y: localItem ? localItem.y : 0,
monitorPositionList: apiItem.monitorPositionList || [],
};
});
} else {
// 降级方案:使用本地数据
}
});
//初始化获取左侧环境监测实施数据
getRealData().then((res) => {
this.tableData1 = res.data.map((el) => {
return { return {
...el, ...el,
value: el.value, x: camera?.x || 0,
y: camera?.y || 0,
}; };
}); });
}
}); });
//初始化highCharts },
getDeviceStatusNum().then((res) => { beforeDestroy() {
if (res.code == 200) { // 清理所有定时器
Object.values(this.timers).forEach((timer) => clearInterval(timer));
// 销毁所有图表实例
Object.values(this.chartInstances).forEach((instance) =>
instance.dispose()
);
// 清理播放器
if (this.player) {
this.player.disconnect();
this.player = null;
}
},
methods: {
// API请求优化:串行处理+错误处理
async initPageData() {
try {
// 并行请求关键数据
const [rtDataRes, rcDataRes, deviceStatusRes] = await Promise.all([
getRtData(),
getRcData(),
getDeviceStatus(),
]);
// 处理历史数据
this.rightTopLssjData.list = rtDataRes.data || [];
this.rtPlayFun(this.rightTopLssjData);
this.rightCenterLssjData.list = rcDataRes.data || [];
this.rcPlayFun(this.rightCenterLssjData);
// 处理设备状态
this.handleDeviceStatus(deviceStatusRes.data);
// 串行请求次要数据
await this.initRealData();
await this.initDeviceStatusNum();
} catch (error) {
console.error("页面初始化失败:", error);
this.$message.error("数据加载失败,请刷新页面重试");
}
},
async initRealData() {
const res = await getRealData();
this.tableData1 = res.data.map((el) => ({ ...el, value: el.value }));
},
async initDeviceStatusNum() {
const res = await getDeviceStatusNum();
if (res.code === 200) {
this.deviceStatusNum = { this.deviceStatusNum = {
total: res.data[0].online + res.data[0].offline, total: res.data[0].online + res.data[0].offline,
cameraTotal: res.data[1].online + res.data[1].offline, cameraTotal: res.data[1].online + res.data[1].offline,
}; };
this.getHighChartsData(res.data); this.getHighChartsData(res.data);
} }
},
handleDeviceStatus(apiData) {
if (apiData && apiData.length) {
this.equipmentList = apiData.map((apiItem) => {
const localItem = EQUIPMENT_POSITIONS.find(
(xy) => xy.name === apiItem.name
);
return {
...apiItem,
x: localItem?.x || 0,
y: localItem?.y || 0,
monitorPositionList: apiItem.monitorPositionList || [],
};
}); });
}
}, },
created() {},
methods: { initvideoPlayer() {
this.player = new WebRtcStreamer("player", "http://127.0.0.1:8000");
},
// 查看视频
lookVideo(item, i) {
this.video.upWindowVisible = true;
this.video.title = item.cameraName;
this.video.videoUrl = item.cameraUrl;
this.player.connect(this.video.videoUrl);
},
closeVideoUpWindow() {
this.video.upWindowVisible = false;
},
getHighChartsData(value = []) { getHighChartsData(value = []) {
this.highChartsOption = { this.highChartsOption = {
chart: { chart: {
type: "pie", //饼图 type: "pie",
options3d: { options3d: {
enabled: true, //使用3d功能 enabled: true,
alpha: 60, //延y轴向内的倾斜角度 alpha: 60,
beta: 0, beta: 0,
}, },
backgroundColor: "rgba(64, 158, 255, 0)", // 不显示背景色 backgroundColor: "rgba(64, 158, 255, 0)",
// spacingTop: -200, // 增加顶部间距
}, },
legend: { legend: {
enabled: true, enabled: true,
align: "center", align: "center",
verticalAlign: "middle", // 修正为底部对齐 verticalAlign: "middle",
layout: "vertical", // 水平布局 layout: "vertical",
y: 60, // 下移图例 y: 60,
itemStyle: { itemStyle: {
color: "#fff", color: "#fff",
fontSize: "12px", // 缩小字体 fontSize: "12px",
}, },
labelFormatter: function () { labelFormatter: function () {
return `${this.name}: ${this.y}`; // 在图例中显示数据 return `${this.name}: ${this.y}`;
},
}, },
title: {
text: "", //图表的标题文字
},
subtitle: {
text: "", //副标题文字
}, },
title: { text: "" },
subtitle: { text: "" },
plotOptions: { plotOptions: {
pie: { pie: {
size: "55%", // 缩小饼图尺寸 size: "55%",
allowPointSelect: false, // 允许点击, allowPointSelect: false,
cursor: "pointer", cursor: "pointer",
innerSize: "65%", //内圆半径, innerSize: "65%",
showInLegend: false, showInLegend: false,
center: ["50%", "34%"], // 调整饼图中心位置 center: ["50%", "34%"],
depth: 15, //3d饼图的厚度, depth: 15,
dataLabels: { dataLabels: { enabled: false },
enabled: false, // 启用数据标签
},
}, },
}, },
credits: { credits: { enabled: false },
enabled: false,
},
series: [ series: [
{ {
type: "pie", type: "pie",
...@@ -888,51 +484,37 @@ export default { ...@@ -888,51 +484,37 @@ export default {
name: "正常设备", name: "正常设备",
y: value[0].online, y: value[0].online,
color: "RGBA(37, 160, 238, 1)", color: "RGBA(37, 160, 238, 1)",
}, // 高数据部分 },
{ {
name: "异常设备", name: "异常设备",
y: value[0].offline, y: value[0].offline,
color: "RGBA(252, 183, 62, 1)", color: "RGBA(252, 183, 62, 1)",
}, // 低数据部分
],
startAngle: 0, //起始角度,
label: {
show: false,
position: "outside",
formatter: "{b}:{d}%",
normal: {
show: false,
fontSize: 40,
formatter: [" {a|{b}:{d}%}"].join("\n"),
rich: {
a: {
left: 20,
padding: [0, -140, 0, -180],
},
},
},
}, },
],
startAngle: 0,
label: { show: false },
}, },
], ],
}; };
Highcharts.chart("EchartsPieLeft", this.highChartsOption); Highcharts.chart("EchartsPieLeft", this.highChartsOption);
this.highChartsOption.series[0].data = [ this.highChartsOption.series[0].data = [
{ name: "在线", y: value[1].online, color: "#02CD9B" }, // 高数据部分 { name: "在线", y: value[1].online, color: "#02CD9B" },
{ name: "离线", y: value[1].offline, color: "RGBA(252, 183, 62, 1)" }, // 低数据部分 { name: "离线", y: value[1].offline, color: "RGBA(252, 183, 62, 1)" },
]; ];
Highcharts.chart("EchartsPieRight", this.highChartsOption); Highcharts.chart("EchartsPieRight", this.highChartsOption);
}, },
// 辅助方法:获取字段值
getItemField(item, fieldKey) {
return item[this.fieldMap[fieldKey]] || "";
},
// 初始化eChartDOM
initEchartBox(id, xData = [], yData = [], mkData = 28, step = 4, grid) { initEchartBox(id, xData = [], yData = [], mkData = 28, step = 4, grid) {
// 销毁旧实例
if (this.chartInstances[id]) {
this.chartInstances[id].dispose();
}
let myChart = echarts.init(document.getElementById(id));
let maxData = yData.length ? Math.ceil(Math.max(...yData)) : 0; let maxData = yData.length ? Math.ceil(Math.max(...yData)) : 0;
let minData = yData.length ? Math.floor(Math.min(...yData)) : 0; // 添加向下取整 let minData = yData.length ? Math.floor(Math.min(...yData)) : 0;
let myChart = null;
myChart = echarts.init(document.getElementById(id));
let option = { let option = {
grid: grid, grid: grid,
xAxis: { xAxis: {
...@@ -943,21 +525,12 @@ export default { ...@@ -943,21 +525,12 @@ export default {
axisLabel: { axisLabel: {
show: true, show: true,
interval: step, interval: step,
textStyle: { textStyle: { color: "#FFFFFF", fontSize: 16 },
color: "#FFFFFF", //更改坐标轴文字颜色
fontSize: 16, //更改坐标轴文字大小
},
},
axisTick: {
alignWithLabel: true,
}, },
axisTick: { alignWithLabel: true },
splitLine: { splitLine: {
//网格线 lineStyle: { type: "dashed", opacity: 0.5 },
lineStyle: { show: true,
type: "dashed", //设置网格线类型 dotted:虚线 solid:实线
opacity: 0.5,
},
show: true, //隐藏或显示
}, },
}, },
yAxis: { yAxis: {
...@@ -965,23 +538,14 @@ export default { ...@@ -965,23 +538,14 @@ export default {
max: mkData > maxData ? mkData : maxData, max: mkData > maxData ? mkData : maxData,
min: minData, min: minData,
boundaryGap: false, boundaryGap: false,
axisTick: { axisTick: { alignWithLabel: true },
alignWithLabel: true,
},
axisLabel: { axisLabel: {
show: true, show: true,
textStyle: { textStyle: { color: "#FFFFFF", fontSize: 16 },
color: "#FFFFFF", //更改坐标轴文字颜色
fontSize: 16, //更改坐标轴文字大小
},
}, },
splitLine: { splitLine: {
//网格线 lineStyle: { type: "dashed", opacity: 0.5 },
lineStyle: { show: true,
type: "dashed", //设置网格线类型 dotted:虚线 solid:实线
opacity: 0.5,
},
show: true, //隐藏或显示
}, },
}, },
series: [ series: [
...@@ -989,104 +553,71 @@ export default { ...@@ -989,104 +553,71 @@ export default {
type: "line", type: "line",
stack: "Total", stack: "Total",
smooth: 0.2, smooth: 0.2,
lineStyle: { lineStyle: { width: 2, color: "#35B1F3" },
width: 2,
color: "#35B1F3",
},
markLine: { markLine: {
data: [ data: [
{ {
name: "警戒线", name: "警戒线",
yAxis: mkData, yAxis: mkData,
label: { label: { show: false },
show: false,
},
}, },
], ],
symbol: ["none", "none"], symbol: ["none", "none"],
lineStyle: { lineStyle: { color: "red", width: 2 },
color: "red",
width: 2,
},
}, },
showSymbol: false, showSymbol: false,
areaStyle: { areaStyle: {
opacity: 0.8, opacity: 0.8,
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [ color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{ { offset: 0, color: "rgb(55, 184, 251,0.5)" },
offset: 0, { offset: 1, color: "rgb(55, 184, 251,0.1)" },
color: "rgb(55, 184, 251,0.5)",
},
{
offset: 1,
color: "rgb(55, 184, 251,0.1)",
},
]), ]),
}, },
emphasis: { emphasis: { focus: "series" },
focus: "series",
},
data: yData, data: yData,
}, },
], ],
}; };
myChart.setOption(option); myChart.setOption(option);
setTimeout(() => { setTimeout(() => myChart.resize(), 600);
myChart.resize();
}, 600); // 保存实例引用
this.chartInstances[id] = myChart;
this.$on("hook:deactivated", () => { this.$on("hook:deactivated", () => {
if (myChart != null && myChart != "" && myChart != undefined) { if (myChart && myChart !== "" && myChart !== undefined) {
myChart.dispose(); myChart.dispose();
} }
myChart = null; myChart = null;
}); });
}, },
// 轮播eChart
// 更改数据达到轮播效果 // 右上图表轮播
rtPlayFun(data) { rtPlayFun(data) {
// 启动定时器,每隔 15 秒执行一次 this.clearTimer("rtPlayTimer");
let i = 0; let i = 0,
let l = 0; l = 0;
let timer = null; const grid = {
let grid = {
left: "4%", left: "4%",
right: "5%", right: "5%",
bottom: "4%", bottom: "4%",
top: "7%", top: "7%",
containLabel: true, containLabel: true,
}; };
if (!timer) {
// 页面进来的时候要触发一次 // 初始化首次渲染
this.rightTopLssjData.mark = 0; this.updateRtChart(0, 0);
this.rightTopLssjData.name = data.list[0].value[0].name;
this.initEchartBox( this.timers.rtPlayTimer = setInterval(() => {
"sssj",
data.list[0].value[0].value.xData.data,
data.list[0].value[0].value.yData.data,
data.list[0].value[0].value.yData.alarm,
4,
grid
);
}
timer = setInterval(() => {
if (i < data.list.length) { if (i < data.list.length) {
if ( if (
Array.isArray(data.list[i].value) && Array.isArray(data.list[i].value) &&
l < data.list[i].value.length l < data.list[i].value.length
) { ) {
this.rightTopLssjData.mark = i; this.updateRtChart(i, l);
this.rightTopLssjData.name = data.list[i].value[l].name;
this.initEchartBox(
"sssj",
data.list[i].value[l].value.xData.data,
data.list[i].value[l].value.yData.data,
data.list[i].value[l].value.yData.alarm,
4,
grid
);
l++; l++;
} else { } else {
// 需要l重置,否则进不去判断i错乱
l = 0; l = 0;
i++; i++;
} }
...@@ -1095,58 +626,35 @@ export default { ...@@ -1095,58 +626,35 @@ export default {
l = 0; l = 0;
} }
}, 15000); }, 15000);
},
this.$on("hook:activated", () => { updateRtChart(i, l) {
if (timer === null) { const data = this.rightTopLssjData.list;
// 避免重复开启定时器
timer = setInterval(() => {
if (i < data.list.length) {
if (
Array.isArray(data.list[i].value) &&
l < data.list[i].value.length
) {
this.rightTopLssjData.mark = i; this.rightTopLssjData.mark = i;
this.rightTopLssjData.name = data.list[i].value[l].tpName; this.rightTopLssjData.name = data[i].value[l].name;
this.initEchartBox( this.initEchartBox(
"sssj", "sssj",
data.list[i].value[l].data.xData.data, data[i].value[l].value.xData.data,
data.list[i].value[l].data.yData.data, data[i].value[l].value.yData.data,
data.list[i].value[l].data.yData.alarm, data[i].value[l].value.yData.alarm,
4, 4,
grid { left: "4%", right: "5%", bottom: "4%", top: "7%", containLabel: true }
); );
l++;
} else {
l = 0;
i++;
}
} else {
i = 0;
l = 0;
}
}, 15000);
}
});
this.$on("hook:deactivated", () => {
clearInterval(timer);
timer = null;
});
}, },
// 更改数据达到轮播效果
// 右中图表轮播
rcPlayFun(data) { rcPlayFun(data) {
// 启动定时器,每隔 3 秒执行一次 this.clearTimer("rcPlayTimer");
let i = 0; let i = 0,
let l = 0; l = 0;
let timer = null; const grid = {
let grid = {
left: "4%", left: "4%",
right: "5%", right: "5%",
bottom: "4%", bottom: "4%",
top: "7%", top: "7%",
containLabel: true, containLabel: true,
}; };
if (!timer) {
this.rightCenterLssjData.mark = i; this.rightCenterLssjData.mark = i;
this.rightCenterLssjData.name = data.list[i].value[l].name; this.rightCenterLssjData.name = data.list[i].value[l].name;
this.initEchartBox( this.initEchartBox(
...@@ -1157,8 +665,8 @@ export default { ...@@ -1157,8 +665,8 @@ export default {
4, 4,
grid grid
); );
}
timer = setInterval(() => { this.timers.rcPlayTimer = setInterval(() => {
if (i < data.list.length) { if (i < data.list.length) {
if ( if (
Array.isArray(data.list[i].value) && Array.isArray(data.list[i].value) &&
...@@ -1184,60 +692,16 @@ export default { ...@@ -1184,60 +692,16 @@ export default {
l = 0; l = 0;
} }
}, 15000); }, 15000);
this.$on("hook:activated", () => {
if (timer === null) {
// 避免重复开启定时器
timer = setInterval(() => {
if (i < data.list.length) {
if (
Array.isArray(data.list[i].value) &&
l < data.list[i].value.length
) {
this.rightCenterLssjData.mark = i;
this.rightCenterLssjData.name = data.list[i].value[l].tpName;
this.initEchartBox(
"rclssj",
data.list[i].value[l].value.xData.data,
data.list[i].value[l].value.yData.data,
data.list[i].value[l].value.yData.alarm,
4,
grid
);
l++;
} else {
l = 0;
i++;
}
} else {
i = 0;
l = 0;
}
}, 15000);
}
});
this.$on("hook:deactivated", () => {
clearInterval(timer);
timer = null;
});
}, },
//自动滚动
autoScroll() {
const divData = this.$refs.scroll_List3;
// 拿到表格中承载数据的div元素
divData.scrollTop += 1;
if (
Math.round(divData.clientHeight + divData.scrollTop) + 1 >=
divData.scrollHeight
) {
// 重置table距离顶部距离
divData.scrollTop = 0; // 清除定时器
clearTimer(timerName) {
if (this.timers[timerName]) {
clearInterval(this.timers[timerName]);
this.timers[timerName] = null;
} }
this.scrolltimer3 = window.requestAnimationFrame(
this.autoScroll.bind(this)
);
}, },
// 查看设备24H实时数据 // 查看设备24H实时数据
lookRealData(item, i) { lookRealData(item, i) {
let grid = { let grid = {
...@@ -1251,7 +715,7 @@ export default { ...@@ -1251,7 +715,7 @@ export default {
let xData = []; let xData = [];
let yData = []; let yData = [];
getDeviceData({ id: item.id }).then((res) => { getDeviceData({ id: item.id }).then((res) => {
if (res.code == 200) { if (res.code === 200) {
this.upWindowData.upWindowActive = i; this.upWindowData.upWindowActive = i;
this.upWindowData.upWindowVisible = true; this.upWindowData.upWindowVisible = true;
this.upWindowData.title = item.tpName; this.upWindowData.title = item.tpName;
...@@ -1269,32 +733,26 @@ export default { ...@@ -1269,32 +733,26 @@ export default {
} }
}); });
}, },
// 关闭弹窗
closeUpWindow() { closeUpWindow() {
this.upWindowData.upWindowActive = ""; this.upWindowData.upWindowActive = "";
this.upWindowData.upWindowVisible = false; this.upWindowData.upWindowVisible = false;
this.classOption.autoPlay = true; this.classOption.autoPlay = true;
this.$refs.sssjControl._startMove(); this.$refs.sssjControl._startMove();
}, },
goToSys() { goToSys() {
var link = this.$router.resolve({ var link = this.$router.resolve({ path: "/" });
path: "/",
});
window.open(link.href); window.open(link.href);
return; return;
}, },
// 左侧 鼠标滚动代码
handleScroll(e) { handleScroll(e) {
// 改变组件内部 yPos 的值,这样html的translate(0, yPos)就会随之改变
// e.deltaY是滚动的距离
this.$refs.sssjControl.yPos = this.$refs.sssjControl.yPos - e.deltaY; this.$refs.sssjControl.yPos = this.$refs.sssjControl.yPos - e.deltaY;
// 如果是正数 说明是往上滚
if (this.$refs.sssjControl.yPos > 0) { if (this.$refs.sssjControl.yPos > 0) {
this.$refs.sssjControl.yPos = 0; this.$refs.sssjControl.yPos = 0;
return; return;
} }
// 如果yPos超过内部实际高度的一半则重新到顶部滚动
// 一半的原因是因为组件实际上创建了两个dom,以达到无缝衔接的效果
if ( if (
Math.abs(this.$refs.sssjControl.yPos) > Math.abs(this.$refs.sssjControl.yPos) >
this.$refs.sssjControl.realBoxHeight / 2 this.$refs.sssjControl.realBoxHeight / 2
...@@ -1304,80 +762,85 @@ export default { ...@@ -1304,80 +762,85 @@ export default {
}, },
}, },
filters: { filters: {
capitalize: function (value) { capitalize(value) {
if (value === null || value === undefined) return "--"; if (value === null || value === undefined) return "--";
console.log(value); if (value === "" || value === "") {
if (value == "" || value == "") {
return value; return value;
} }
const parsedValue = Number(value); const parsedValue = Number(value);
if (isNaN(parsedValue)) return "--"; return isNaN(parsedValue) ? "--" : parsedValue.toFixed(1);
// 整数判断
if (Number.isInteger(parsedValue)) {
return parsedValue.toFixed(1);
}
// 小数保留两位
return parsedValue.toFixed(1);
},
},
watch: {
tableData1: {
handler() {
this.$nextTick(() => {
this.$refs.sssjControl && this.$refs.sssjControl.reset(); // 添加存在性判断
});
},
immediate: true,
}, },
}, },
}; };
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
// 变量定义
$primary-color: #2ed5ff;
$bg-color: rgba(1, 33, 58, 0.2);
$border-radius: 8px;
$spacing: 16px;
// Mixin定义
@mixin sidebar-item {
width: 100%;
margin-bottom: $spacing;
background: linear-gradient(
180deg,
$bg-color 0%,
rgba(8, 132, 233, 0.2) 100%
);
position: relative;
border-radius: $border-radius;
&::before {
content: "";
width: 460px;
height: 4px;
position: absolute;
background: url("~@/assets/images/screen/title1.png") no-repeat center;
left: 0;
bottom: 0;
right: 0;
z-index: 20;
}
}
.por { .por {
position: relative; position: relative;
} }
.sidebar-left { .sidebar-left {
transform-origin: left center; transform-origin: left center;
transform: scaleX(1) perspective(610px) rotateY(5deg); transform: scaleX(1) perspective(610px) rotateY(5deg);
} }
.sidebar-right { .sidebar-right {
transform-origin: center right; transform-origin: center right;
transform: scaleX(1) perspective(610px) rotateY(-5deg); transform: scaleX(1) perspective(610px) rotateY(-5deg);
} }
/* 主体内容 */ /* 主体内容 */
.main-content { .main-content {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
padding: 0 30px; padding: 0 $spacing;
padding-top: 160px; padding-top: 16vh;
background: url("~@/assets/images/screen/bg12.png"); background: url("~@/assets/images/screen/bg12.png");
color: #fff; color: #fff;
min-height: 100vh;
box-sizing: border-box;
} }
.histrybox { .histrybox {
width: 100%; width: 100%;
height: 100%; height: 100%;
display: flex; display: flex;
/**均分2部分 */
.histrubox_left {
width: 50%;
height: calc(100% - 46px);
.echarts_title {
height: 25px;
text-align: center;
span { .histrubox_left,
color: rgba(42, 207, 255, 1);
font-weight: 400;
font-size: 16px;
color: #2acfff;
}
}
}
.histrubox_right { .histrubox_right {
width: 50%; width: 50%;
height: calc(100% - 46px); height: calc(100% - 46px);
.echarts_title { .echarts_title {
height: 25px; height: 25px;
text-align: center; text-align: center;
...@@ -1386,14 +849,16 @@ export default { ...@@ -1386,14 +849,16 @@ export default {
color: rgba(42, 207, 255, 1); color: rgba(42, 207, 255, 1);
font-weight: 400; font-weight: 400;
font-size: 16px; font-size: 16px;
color: #2acfff; color: $primary-color;
} }
} }
} }
.chart_box { .chart_box {
width: 100%; width: 100%;
height: calc(100% - 25px); height: calc(100% - 25px);
} }
.img_class { .img_class {
width: 29px; width: 29px;
height: 25px; height: 25px;
...@@ -1402,7 +867,9 @@ export default { ...@@ -1402,7 +867,9 @@ export default {
margin-right: 12px; margin-right: 12px;
margin-bottom: -7px; margin-bottom: -7px;
} }
.chart_bg {
.chart_bg,
.chart_bg_right {
position: absolute; position: absolute;
width: 140px; width: 140px;
height: 150px; height: 150px;
...@@ -1410,102 +877,73 @@ export default { ...@@ -1410,102 +877,73 @@ export default {
background-repeat: no-repeat; background-repeat: no-repeat;
background-position: cover; background-position: cover;
background-size: 100% 100%; background-size: 100% 100%;
// -webkit-transform: rotateX(65deg);
transform: rotateX(53deg); transform: rotateX(53deg);
left: 45px;
top: 89px; top: 89px;
} }
.chart_bg {
left: 45px;
}
.chart_bg_right { .chart_bg_right {
position: absolute;
width: 140px;
height: 150px;
background-image: url("~@/assets/images/screen/chart.png");
background-repeat: no-repeat;
background-position: cover;
background-size: 100% 100%;
// -webkit-transform: rotateX(65deg);
transform: rotateX(53deg);
left: 275px; left: 275px;
top: 89px;
} }
.chart_number {
.chart_number,
.chart_number_right {
position: absolute; position: absolute;
width: 100px; width: 100px;
height: 100px; height: 100px;
top: 109px; top: 109px;
left: 66px;
text-align: center; text-align: center;
span:nth-child(1) { span:nth-child(1) {
font-size: 30px; font-size: 30px;
font-weight: 400; font-weight: 400;
} }
} }
.chart_number {
left: 66px;
}
.chart_number_right { .chart_number_right {
position: absolute;
width: 100px;
height: 100px;
top: 109px;
left: 296px; left: 296px;
text-align: center;
span:nth-child(1) {
font-size: 30px;
font-weight: 400;
}
} }
} }
/* 左右侧边栏 */ /* 左右侧边栏 */
.sidebar { .sidebar {
width: 460px; width: 460px;
border-radius: 8px; border-radius: $border-radius;
flex: 1; flex: 1;
// display: flex;
// flex-direction: column;
// display: grid;
grid-template-rows: repeat(3, 1fr); grid-template-rows: repeat(3, 1fr);
gap: 2px; gap: 2px;
margin-top: -10px; margin-top: -10px;
} }
.H917 { .H917 {
height: 917px; height: 917px;
} }
.H286 { .H286 {
height: 286px; height: 286px;
} }
.sidebar-item { .sidebar-item {
width: 100%; @include sidebar-item;
// height: 286px;
margin-bottom: 30px;
background: linear-gradient(
180deg,
rgba(1, 33, 58, 0.2) 0%,
rgba(8, 132, 233, 0.2) 100%
);
position: relative;
&::before {
content: "";
width: 460px;
height: 4px;
position: absolute;
background: url("~@/assets/images/screen/bottom.png") no-repeat center;
left: 0;
bottom: 0;
right: 0;
z-index: 20;
}
.sub-title { .sub-title {
width: 100%; width: 100%;
height: 46px; height: 46px;
background: url("~@/assets/images/screen/title1.png") no-repeat center; background: url("~@/assets/images/screen/title1.png") no-repeat center;
font-weight: bold; font-weight: bold;
font-family: "fangsong"; font-family: "fangsong";
span { span {
position: absolute; position: absolute;
top: -10px; top: -10px;
left: 30px; left: 30px;
font-size: 22px; font-size: 22px;
} }
.scroll-title { .scroll-title {
position: absolute; position: absolute;
top: -7px; top: -7px;
...@@ -1515,34 +953,38 @@ export default { ...@@ -1515,34 +953,38 @@ export default {
color: #ffc62e; color: #ffc62e;
} }
} }
.table-box { .table-box {
height: 866px; height: 866px;
width: calc(100% - 4px); width: calc(100% - 4px);
.table-item { .table-item {
height: 110px; height: 110px;
width: calc(100% - 46px); width: calc(100% - 46px);
margin: 0 auto; margin: 0 auto;
border-bottom: 2px dashed rgba(100, 194, 255, 0.3); border-bottom: 2px dashed rgba(100, 194, 255, 0.3);
padding-top: 9px; padding-top: 9px;
.img-class { .img-class {
display: block; display: block;
width: 85px; width: 85px;
height: 85px; height: 85px;
} }
.device-name { .device-name {
width: 100%; width: 100%;
font-weight: 400;
font-size: 18px; font-size: 18px;
color: #63c2ff; color: #63c2ff;
font-family: Source Han Sans SC; font-family: Source Han Sans SC;
height: 15px;
} }
.device-time { .device-time {
font-weight: 400; font-weight: 400;
font-size: 16px; font-size: 16px;
color: #b4d5ea; color: #b4d5ea;
font-family: Source Han Sans SC; font-family: Source Han Sans SC;
} }
.device-value { .device-value {
font-family: Source Han Sans SC; font-family: Source Han Sans SC;
font-weight: 500; font-weight: 500;
...@@ -1560,26 +1002,29 @@ export default { ...@@ -1560,26 +1002,29 @@ export default {
text-align: center; text-align: center;
} }
} }
.warp { .warp {
width: 100%; width: 100%;
height: 100%; height: 100%;
overflow: hidden; overflow: hidden;
font-family: "fangzhengyaoti"; font-family: "fangzhengyaoti";
ul { ul {
list-style: none; list-style: none;
margin: 0 auto; margin: 0 auto;
}
.active { .active {
// width: 100%;
background: RGBA(2, 87, 149, 1); background: RGBA(2, 87, 149, 1);
} }
} }
} }
} }
.jz {
.jz {
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
}
} }
/* 中间主区域 */ /* 中间主区域 */
...@@ -1592,14 +1037,16 @@ export default { ...@@ -1592,14 +1037,16 @@ export default {
position: relative; position: relative;
pointer-events: auto; pointer-events: auto;
z-index: 999; z-index: 999;
.main-example { .main-example {
font-size: 18px; font-size: 18px;
color: #2ed5ff; color: $primary-color;
line-height: 36px; line-height: 36px;
font-weight: bold; font-weight: bold;
position: absolute; position: absolute;
font-family: "fangsong"; font-family: "fangsong";
} }
.dot { .dot {
width: 42px; width: 42px;
height: 70px; height: 70px;
...@@ -1607,8 +1054,10 @@ export default { ...@@ -1607,8 +1054,10 @@ export default {
top: 100px; top: 100px;
left: 500px; left: 500px;
background: url("~@/assets/images/screen/hjjc/icon8.png") no-repeat center; background: url("~@/assets/images/screen/hjjc/icon8.png") no-repeat center;
.dot1 { .dot1 {
position: relative; position: relative;
.tip-box { .tip-box {
width: 216px; width: 216px;
background: linear-gradient(0deg, #062451 0%, #09162d 100%); background: linear-gradient(0deg, #062451 0%, #09162d 100%);
...@@ -1621,6 +1070,7 @@ export default { ...@@ -1621,6 +1070,7 @@ export default {
padding: 9px 14px 14px 14px; padding: 9px 14px 14px 14px;
z-index: 999; z-index: 999;
display: none; display: none;
p { p {
font-family: Source Han Sans SC; font-family: Source Han Sans SC;
font-weight: 400; font-weight: 400;
...@@ -1628,32 +1078,38 @@ export default { ...@@ -1628,32 +1078,38 @@ export default {
color: #1cd2ff; color: #1cd2ff;
margin: 5px 0 0 0; margin: 5px 0 0 0;
text-align: left; text-align: left;
span { span {
display: none; display: none;
width: 16px;
height: 16px;
background: url("~@/assets/images/screen/hjjc/icon10.png") no-repeat
center;
margin-bottom: -3px;
} }
&.active { &.active {
color: rgba(255, 43, 58, 1); color: rgba(255, 43, 58, 1);
span { span {
display: inline-block; display: inline-block;
width: 16px;
height: 16px;
background: url("~@/assets/images/screen/hjjc/icon10.png")
no-repeat center;
margin-bottom: -3px;
} }
} }
} }
} }
} }
&:hover { &:hover {
background: url("~@/assets/images/screen/hjjc/icon8_hover.png") no-repeat background: url("~@/assets/images/screen/hjjc/icon8_hover.png") no-repeat
center; center;
.tip-box { .tip-box {
display: block; display: block;
} }
} }
&.active { &.active {
background: url("~@/assets/images/screen/hjjc/icon9.png") no-repeat center; background: url("~@/assets/images/screen/hjjc/icon9.png") no-repeat center;
&:hover { &:hover {
background: url("~@/assets/images/screen/hjjc/icon9_hover.png") background: url("~@/assets/images/screen/hjjc/icon9_hover.png")
no-repeat center; no-repeat center;
...@@ -1670,15 +1126,18 @@ export default { ...@@ -1670,15 +1126,18 @@ export default {
background: url("~@/assets/images/screen/hjjc/icon_normal.png") no-repeat background: url("~@/assets/images/screen/hjjc/icon_normal.png") no-repeat
center; center;
cursor: pointer; cursor: pointer;
&:hover { &:hover {
background: url("~@/assets/images/screen/hjjc/icon_hover.png") no-repeat background: url("~@/assets/images/screen/hjjc/icon_hover.png") no-repeat
center; center;
} }
&.offline { &.offline {
background: url("~@/assets/images/screen/hjjc/icon_click.png") no-repeat background: url("~@/assets/images/screen/hjjc/icon_click.png") no-repeat
center; center;
} }
} }
.toggle-button { .toggle-button {
width: 120px; width: 120px;
height: 90px; height: 90px;
...@@ -1686,9 +1145,11 @@ export default { ...@@ -1686,9 +1145,11 @@ export default {
position: absolute; position: absolute;
bottom: 58px; bottom: 58px;
right: 0px; right: 0px;
.el-checkbox-group { .el-checkbox-group {
width: 100%; width: 100%;
height: 100%; height: 100%;
.el-checkbox { .el-checkbox {
margin-top: 16px; margin-top: 16px;
color: #fdfeff; color: #fdfeff;
...@@ -1704,17 +1165,15 @@ export default { ...@@ -1704,17 +1165,15 @@ export default {
.distribution-map { .distribution-map {
height: 300px; height: 300px;
background: rgba(8, 28, 49, 0.8); background: rgba(8, 28, 49, 0.8);
border-radius: 8px; border-radius: $border-radius;
} }
.sub-con { .sub-con {
.sub-con { .sub-con {
height: 2em; height: 2em;
width: 100%; width: 100%;
// display: flex;
// justify-content: space-around;
// align-items: center;
font-family: "fangzhengyaoti"; font-family: "fangzhengyaoti";
span { span {
float: left; float: left;
margin-left: 25px; margin-left: 25px;
...@@ -1725,51 +1184,56 @@ export default { ...@@ -1725,51 +1184,56 @@ export default {
font-weight: 500; font-weight: 500;
color: rgba(179, 240, 255, 1); color: rgba(179, 240, 255, 1);
text-align: center; text-align: center;
}
.active { &.active {
color: rgba(46, 213, 255, 1); color: rgba(46, 213, 255, 1);
.subscript { .subscript {
height: 19px; height: 19px;
width: 100%; width: 100%;
margin-top: 3px;
background: url("~@/assets/images/screen/hjjc/icon7.png") no-repeat background: url("~@/assets/images/screen/hjjc/icon7.png") no-repeat
center; center;
} }
} }
} }
}
} }
.left-chart { .left-chart {
width: 100%; width: 100%;
height: 12em; height: 12em;
} }
.sub-con-scroll-table { .sub-con-scroll-table {
width: 95%; width: 95%;
margin: 0 auto; margin: 0 auto;
height: 83%; height: 83%;
overflow: hidden; overflow: hidden;
} }
.custom-header { .custom-header {
width: 100%; width: 100%;
display: grid; display: grid;
grid-template-columns: 1fr 1fr 1fr 2fr; grid-template-columns: 1fr 1fr 1fr 2fr;
text-align: center; text-align: center;
color: #2ed5ff; color: $primary-color;
} }
.custom-item { .custom-item {
width: 100%; width: 100%;
display: grid; display: grid;
grid-template-columns: 1fr 1fr 1fr 2fr; grid-template-columns: 1fr 1fr 1fr 2fr;
text-align: center; text-align: center;
} }
.custom-header2 { .custom-header2 {
width: 100%; width: 100%;
display: grid; display: grid;
grid-template-columns: 1.5fr 2.2fr 1.3fr; grid-template-columns: 1.5fr 2.2fr 1.3fr;
text-align: center; text-align: center;
color: #2ed5ff; color: $primary-color;
height: 36px; height: 36px;
line-height: 36px; line-height: 36px;
color: #2ed5ff;
font-size: 16px; font-size: 16px;
font-weight: 500; font-weight: 500;
background: linear-gradient( background: linear-gradient(
...@@ -1778,14 +1242,17 @@ export default { ...@@ -1778,14 +1242,17 @@ export default {
rgba(61, 98, 147, 0.03) 100% rgba(61, 98, 147, 0.03) 100%
); );
} }
.warp { .warp {
height: calc(100% - 36px); height: calc(100% - 36px);
overflow: hidden; overflow: hidden;
.item { .item {
padding-left: 0px; padding-left: 0px;
margin-bottom: 0px; margin-bottom: 0px;
margin-top: 0px; margin-top: 0px;
} }
.custom-item2 { .custom-item2 {
width: 100%; width: 100%;
height: 36px; height: 36px;
...@@ -1799,6 +1266,7 @@ export default { ...@@ -1799,6 +1266,7 @@ export default {
); );
margin-top: 11px; margin-top: 11px;
} }
.custom-item-content2 { .custom-item-content2 {
font-family: Source Han Sans SC; font-family: Source Han Sans SC;
font-size: 16px; font-size: 16px;
...@@ -1813,17 +1281,19 @@ export default { ...@@ -1813,17 +1281,19 @@ export default {
justify-content: space-evenly; justify-content: space-evenly;
align-items: center; align-items: center;
height: calc(100% - 70px); height: calc(100% - 70px);
.sub-con-r-left { .sub-con-r-left {
width: 127px; width: 127px;
height: 161px; height: 161px;
background: url("~@/assets/images/screen/icon3.png") no-repeat center; background: url("~@/assets/images/screen/icon3.png") no-repeat center;
background-size: 100%; background-size: 100%;
} }
.sub-con-r-right { .sub-con-r-right {
width: 250px; width: 250px;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
// gap: 10px;
p { p {
display: grid; display: grid;
grid-template-columns: 4fr 4fr 1fr; grid-template-columns: 4fr 4fr 1fr;
...@@ -1834,9 +1304,11 @@ export default { ...@@ -1834,9 +1304,11 @@ export default {
padding: 10px 10px; padding: 10px 10px;
text-align: justify; text-align: justify;
box-sizing: border-box; box-sizing: border-box;
span:nth-child(2) { span:nth-child(2) {
color: rgba(187, 215, 234, 0.2); color: rgba(187, 215, 234, 0.2);
} }
span:nth-child(3) { span:nth-child(3) {
font-weight: bold; font-weight: bold;
font-size: 24px; font-size: 24px;
...@@ -1848,6 +1320,7 @@ export default { ...@@ -1848,6 +1320,7 @@ export default {
} }
} }
} }
.up-window { .up-window {
position: absolute; position: absolute;
top: 50%; top: 50%;
...@@ -1860,6 +1333,17 @@ export default { ...@@ -1860,6 +1333,17 @@ export default {
box-shadow: 0px 15px 11px 2px rgba(0, 20, 39, 0.31); box-shadow: 0px 15px 11px 2px rgba(0, 20, 39, 0.31);
padding: 28px 37px; padding: 28px 37px;
z-index: 999; z-index: 999;
&.video-window {
width: 900px;
height: 562px;
background: #062451;
p {
width: 820px;
}
}
p { p {
width: 1271px; width: 1271px;
height: 37px; height: 37px;
...@@ -1872,24 +1356,26 @@ export default { ...@@ -1872,24 +1356,26 @@ export default {
color: #ffffff; color: #ffffff;
height: 37px; height: 37px;
background-position-y: 9px; background-position-y: 9px;
span { span {
width: 27px; width: 27px;
display: inline-block; display: inline-block;
} }
} }
.close-button { .close-button {
font-size: 30px; font-size: 30px;
position: absolute; position: absolute;
top: 16px; top: 16px;
right: 16px; right: 16px;
cursor: pointer; cursor: pointer;
transition: transform 0.3s ease;
&:hover { &:hover {
-webkit-transform: rotate(360deg);
transform: rotate(360deg); transform: rotate(360deg);
-webkit-transition: -webkit-transform 1s linear;
transition: transform 1s linear;
} }
} }
.date-title { .date-title {
height: 18px; height: 18px;
font-weight: 500; font-weight: 500;
...@@ -1899,6 +1385,7 @@ export default { ...@@ -1899,6 +1385,7 @@ export default {
margin-left: 56px; margin-left: 56px;
margin-top: 5px; margin-top: 5px;
} }
.chart-box { .chart-box {
width: 100%; width: 100%;
height: 355px; height: 355px;
......
...@@ -99,6 +99,9 @@ export default { ...@@ -99,6 +99,9 @@ export default {
// 加载3D Tileset // 加载3D Tileset
Cesium.Cesium3DTileset.fromUrl("/terra_b3dms_yd/tileset.json", { Cesium.Cesium3DTileset.fromUrl("/terra_b3dms_yd/tileset.json", {
// Cesium.Cesium3DTileset.fromUrl(
// "http://localhost/terra_b3dms_yd/tileset.json",
// {
maximumScreenSpaceError: 1, maximumScreenSpaceError: 1,
pickable: true, pickable: true,
}) })
...@@ -136,6 +139,19 @@ export default { ...@@ -136,6 +139,19 @@ export default {
.then(() => { .then(() => {
// 添加标记点 // 添加标记点
this.addMarkers(); this.addMarkers();
// 设置初始视角
this.viewer.camera.flyTo({
destination: Cesium.Cartesian3.fromDegrees(
113.43050560273339, // 经度
32.542908886167876, // 纬度
200 // 高度(米),数值越小视角越近
),
orientation: {
heading: Cesium.Math.toRadians(0), // 朝向角度
pitch: Cesium.Math.toRadians(-45), // 俯仰角度
roll: 0.0,
},
});
}) })
.catch((error) => { .catch((error) => {
console.error("模型加载失败:", error); console.error("模型加载失败:", error);
......
<template> <template>
<div class="main-content"> <div class="main-content">
<div class="content"> <div class="content">
<!--一中23线风机dom--> <!--一中23线风机dom-->
<div <div
class="fengji" class="fengji"
v-for="(item, index) in fengjiList" v-for="(item, index) in fengjiList"
:key="index + 'fengji' + item.deviceId" :key="index + 'fengji' + item.deviceId"
v-show="item.deviceName == '一中23线风机'" v-show="item.deviceName == '一中23线风机'"
style="top: 74px; left: 96px" style="top: 74px; left: 96px"
> >
<div class="fengji-title">一中23线风机</div> <div class="fengji-title">一中23线风机</div>
<div class="fengji-content"> <div class="fengji-content">
<img <img
src="../../../assets/images/screen/tfxt/device1.png" src="../../../assets/images/screen/tfxt/device1.png"
...@@ -88,15 +88,15 @@ ...@@ -88,15 +88,15 @@
<div class="arrow-psition" style="top: 132px; left: 1398px"> <div class="arrow-psition" style="top: 132px; left: 1398px">
<div class="fengji-arrow"></div> <div class="fengji-arrow"></div>
</div> </div>
<!--一中扇风机dom--> <!--一中扇风机dom-->
<div <div
class="fengji" class="fengji"
v-for="(item, index) in fengjiList" v-for="(item, index) in fengjiList"
:key="index + 'yizhong' + item.deviceId" :key="index + 'yizhong' + item.deviceId"
v-show="item.deviceName == '一中扇风机'" v-show="item.deviceName == '一中扇风机'"
style="left: 760px; top: 74px" style="left: 760px; top: 74px"
> >
<div class="fengji-title">一中扇风机</div> <div class="fengji-title">一中扇风机</div>
<div class="fengji-content"> <div class="fengji-content">
<img <img
src="../../../assets/images/screen/tfxt/device1.png" src="../../../assets/images/screen/tfxt/device1.png"
...@@ -152,15 +152,15 @@ ...@@ -152,15 +152,15 @@
<p>气体温度:{{ item.gasTemperature }}</p> <p>气体温度:{{ item.gasTemperature }}</p>
</div> </div>
</div> </div>
<!--东风井风机dom--> <!--东风井风机dom-->
<div <div
class="fengji" class="fengji"
v-for="(item, index) in fengjiList" v-for="(item, index) in fengjiList"
:key="index + 'dongfeng1' + item.deviceId" :key="index + 'dongfeng1' + item.deviceId"
v-show="item.deviceName == '东风井风机'" v-show="item.deviceName == '东风井风机'"
style="right: 80px; top: 74px" style="right: 80px; top: 74px"
> >
<div class="fengji-title" style="margin-left: 50px">东风井风机</div> <div class="fengji-title" style="margin-left: 50px">东风井风机</div>
<div class="fengji-content"> <div class="fengji-content">
<div class="fengji-control"> <div class="fengji-control">
<div <div
...@@ -279,15 +279,15 @@ ...@@ -279,15 +279,15 @@
<p>流速:0m³/s</p> <p>流速:0m³/s</p>
</div> </div>
</div> </div>
<!--二中扇风机dom--> <!--二中扇风机dom-->
<div <div
class="fengji" class="fengji"
v-for="(item, index) in fengjiList" v-for="(item, index) in fengjiList"
:key="index + 'erzhong' + item.deviceId" :key="index + 'erzhong' + item.deviceId"
v-show="item.deviceName == '二中扇风机'" v-show="item.deviceName == '二中扇风机'"
style="left: 1160px; top: 247px" style="left: 1160px; top: 247px"
> >
<div class="fengji-title" style="margin-left: 50px">二中扇风机</div> <div class="fengji-title" style="margin-left: 50px">二中扇风机</div>
<div class="fengji-content"> <div class="fengji-content">
<div class="fengji-control"> <div class="fengji-control">
<div <div
...@@ -353,15 +353,15 @@ ...@@ -353,15 +353,15 @@
<div class="arrow-psition bevel" style="top: 282px; left: 1490px"> <div class="arrow-psition bevel" style="top: 282px; left: 1490px">
<div class="fengji-arrow"></div> <div class="fengji-arrow"></div>
</div> </div>
<!--三中扇风机dom--> <!--三中扇风机dom-->
<div <div
class="fengji" class="fengji"
v-for="(item, index) in fengjiList" v-for="(item, index) in fengjiList"
:key="index + 'sanzhong' + item.deviceId" :key="index + 'sanzhong' + item.deviceId"
v-show="item.deviceName == '三中扇风机'" v-show="item.deviceName == '三中扇风机'"
style="left: 660px; top: 415px" style="left: 660px; top: 415px"
> >
<div class="fengji-title">三中扇风机</div> <div class="fengji-title">三中扇风机</div>
<div class="fengji-content"> <div class="fengji-content">
<img <img
src="../../../assets/images/screen/tfxt/device1.png" src="../../../assets/images/screen/tfxt/device1.png"
...@@ -400,15 +400,15 @@ ...@@ -400,15 +400,15 @@
<p>设定频率:{{ item.setFrequency | decimalFilter }}HZ</p> <p>设定频率:{{ item.setFrequency | decimalFilter }}HZ</p>
</div> </div>
</div> </div>
<!--四中扇风机dom--> <!--四中扇风机dom-->
<div <div
class="fengji" class="fengji"
v-for="(item, index) in fengjiList" v-for="(item, index) in fengjiList"
:key="index + 'sizhong' + item.deviceId" :key="index + 'sizhong' + item.deviceId"
v-show="item.deviceName == '四中扇风机'" v-show="item.deviceName == '四中扇风机'"
style="left: 1190px; top: 583px" style="left: 1190px; top: 583px"
> >
<div class="fengji-title" style="margin-left: 50px">四中扇风机</div> <div class="fengji-title" style="margin-left: 50px">四中扇风机</div>
<div class="fengji-content"> <div class="fengji-content">
<div class="fengji-control"> <div class="fengji-control">
<div <div
...@@ -471,15 +471,15 @@ ...@@ -471,15 +471,15 @@
<div class="arrow-psition bevel" style="top: 642px; left: 1068px"> <div class="arrow-psition bevel" style="top: 642px; left: 1068px">
<div class="fengji-arrow"></div> <div class="fengji-arrow"></div>
</div> </div>
<!--五中扇风机dom--> <!--五中扇风机dom-->
<div <div
class="fengji" class="fengji"
v-for="(item, index) in fengjiList" v-for="(item, index) in fengjiList"
:key="index + 'wuzhong' + item.deviceId" :key="index + 'wuzhong' + item.deviceId"
v-show="item.deviceName == '五中扇风机'" v-show="item.deviceName == '五中扇风机'"
style="left: 400px; top: 750px" style="left: 400px; top: 750px"
> >
<div class="fengji-title">五中扇风机</div> <div class="fengji-title">五中扇风机</div>
<div class="fengji-content"> <div class="fengji-content">
<img <img
src="../../../assets/images/screen/tfxt/device1.png" src="../../../assets/images/screen/tfxt/device1.png"
......
...@@ -215,11 +215,11 @@ ...@@ -215,11 +215,11 @@
></span> ></span>
<span <span
class="custom-item-content custom-item-content1" class="custom-item-content custom-item-content1"
v-text="item.maintainUserName" v-text="item.maintainState"
></span> ></span>
<span <span
class="custom-item-content custom-item-content1" class="custom-item-content custom-item-content1"
v-text="item.maintainState" v-text="item.maintainUserName"
></span> ></span>
<span <span
class="custom-item-content custom-item-content1" class="custom-item-content custom-item-content1"
...@@ -749,12 +749,18 @@ export default { ...@@ -749,12 +749,18 @@ export default {
//当月电力能耗情况chart //当月电力能耗情况chart
monthlyPowerChart() { monthlyPowerChart() {
let myChart = echarts.init(document.getElementById("monthlyPower")); let myChart = echarts.init(document.getElementById("monthlyPower"));
//最大值处理
let maxValue = this.monthlyPowerData.reduce((max, item) => {
return item.value > max ? item.value : max;
}, 0);
this.monthlyPowerData.sort((a, b) => a.value - b.value);
let option = { let option = {
polar: { polar: {
radius: [30, "90%"], radius: [30, "90%"],
}, },
angleAxis: { angleAxis: {
max: 5555551, max: maxValue,
startAngle: 90, startAngle: 90,
show: false, // 显示坐标轴 show: false, // 显示坐标轴
}, },
...@@ -789,7 +795,7 @@ export default { ...@@ -789,7 +795,7 @@ export default {
type: "bar", type: "bar",
coordinateSystem: "polar", coordinateSystem: "polar",
stack: "a", stack: "a",
data: this.monthlyPowerData.map(() => 5555555), // 每个项总长度10 data: this.monthlyPowerData.map(() => maxValue), // 每个项总长度10
itemStyle: { itemStyle: {
color: "RGBA(28, 57, 92, 0.3)", color: "RGBA(28, 57, 92, 0.3)",
}, },
......
...@@ -44,6 +44,14 @@ ...@@ -44,6 +44,14 @@
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery" <el-button icon="el-icon-refresh" size="mini" @click="resetQuery"
>重置</el-button >重置</el-button
> >
<el-button
icon="el-icon-download"
size="mini"
type="primary"
plain
@click="exportData"
>导出</el-button
>
</el-form-item> </el-form-item>
</el-form> </el-form>
...@@ -151,6 +159,14 @@ export default { ...@@ -151,6 +159,14 @@ export default {
this.getList(); this.getList();
}, },
methods: { methods: {
/** 导出按钮操作 */
exportData() {
this.download(
"/business/pump/history/export ",
{},
`水泵运行历史数据_${new Date().getTime()}.xlsx`
);
},
/** 查询水泵历史信息列表 */ /** 查询水泵历史信息列表 */
getList() { getList() {
this.loading = true; this.loading = true;
......
...@@ -44,6 +44,14 @@ ...@@ -44,6 +44,14 @@
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery" <el-button icon="el-icon-refresh" size="mini" @click="resetQuery"
>重置</el-button >重置</el-button
> >
<el-button
icon="el-icon-download"
size="mini"
type="primary"
plain
@click="exportData"
>导出</el-button
>
</el-form-item> </el-form-item>
</el-form> </el-form>
...@@ -213,6 +221,14 @@ export default { ...@@ -213,6 +221,14 @@ export default {
this.getList(); this.getList();
}, },
methods: { methods: {
/** 导出按钮操作 */
exportData() {
this.download(
"/business/pump/history/export ",
{},
`风机运行历史数据_${new Date().getTime()}.xlsx`
);
},
/** 查询风机基本信息列表 */ /** 查询风机基本信息列表 */
getList() { getList() {
this.loading = true; this.loading = true;
......
...@@ -250,7 +250,7 @@ export default { ...@@ -250,7 +250,7 @@ export default {
this.download( this.download(
"/business/history/export", "/business/history/export",
{}, {},
`2502_${new Date().getTime()}.xlsx` `监测监控设备历史数据_${new Date().getTime()}.xlsx`
); );
}, },
}, },
......
<template> <template>
<div class="app-container"> <div class="app-container">
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px"> <el-form
:model="queryParams"
ref="queryForm"
size="small"
:inline="true"
v-show="showSearch"
label-width="68px"
>
<el-form-item label="" prop="substationName"> <el-form-item label="" prop="substationName">
<el-select v-model="queryParams.substationName" placeholder="变电站名称" clearable @change="substationNameChange"> <el-select
v-model="queryParams.substationName"
placeholder="变电站名称"
clearable
@change="substationNameChange"
>
<el-option <el-option
v-for="item in SubstationNameList" v-for="item in SubstationNameList"
:key="item.value" :key="item.value"
...@@ -11,8 +23,16 @@ ...@@ -11,8 +23,16 @@
/> />
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="" prop="eleboxName" v-if="queryParams.substationName"> <el-form-item
<el-select v-model="queryParams.eleboxName" placeholder="电箱名称" @change="eleboxNameChange"> label=""
prop="eleboxName"
v-if="queryParams.substationName"
>
<el-select
v-model="queryParams.eleboxName"
placeholder="电箱名称"
@change="eleboxNameChange"
>
<el-option <el-option
v-for="item in EleboxNameList" v-for="item in EleboxNameList"
:key="item.value" :key="item.value"
...@@ -20,10 +40,17 @@ ...@@ -20,10 +40,17 @@
:value="item.value" :value="item.value"
/> />
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="" prop="eleboxParameter" v-if="queryParams.eleboxName"> <el-form-item
<el-select v-model="queryParams.eleboxParameter" placeholder="电箱参数" multiple> label=""
prop="eleboxParameter"
v-if="queryParams.eleboxName"
>
<el-select
v-model="queryParams.eleboxParameter"
placeholder="电箱参数"
multiple
>
<el-option <el-option
v-for="item in EleboxParameterList" v-for="item in EleboxParameterList"
:key="item.value" :key="item.value"
...@@ -31,7 +58,6 @@ ...@@ -31,7 +58,6 @@
:value="item.value" :value="item.value"
/> />
</el-select> </el-select>
</el-form-item> </el-form-item>
<!-- <el-form-item label="" prop="parameterData"> <!-- <el-form-item label="" prop="parameterData">
<el-input <el-input
...@@ -42,48 +68,84 @@ ...@@ -42,48 +68,84 @@
/> />
</el-form-item> --> </el-form-item> -->
<el-form-item label=""> <el-form-item label="">
<el-date-picker v-model="dateRange" style="width: 240px" value-format="yyyy-MM-dd" type="daterange" range-separator="-" start-placeholder="开始日期" end-placeholder="结束日期"></el-date-picker> <el-date-picker
v-model="dateRange"
style="width: 240px"
value-format="yyyy-MM-dd"
type="daterange"
range-separator="-"
start-placeholder="开始日期"
end-placeholder="结束日期"
></el-date-picker>
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button> <el-button
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button> type="primary"
icon="el-icon-search"
size="mini"
@click="handleQuery"
>搜索</el-button
>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery"
>重置</el-button
>
<el-button
icon="el-icon-download"
size="mini"
type="primary"
plain
@click="handleExport"
>导出</el-button
>
</el-form-item> </el-form-item>
</el-form> </el-form>
<el-table
v-loading="loading"
<el-table v-loading="loading" :data="dataList" @selection-change="handleSelectionChange"> :data="dataList"
@selection-change="handleSelectionChange"
>
<el-table-column type="selection" width="55" align="center" /> <el-table-column type="selection" width="55" align="center" />
<el-table-column label="变电站名称" align="center" prop="substationName" /> <el-table-column
label="变电站名称"
align="center"
prop="substationName"
/>
<el-table-column label="电箱名称" align="center" prop="eleboxName" /> <el-table-column label="电箱名称" align="center" prop="eleboxName" />
<el-table-column label="电箱参数" align="center" prop="eleboxParameter" /> <el-table-column label="电箱参数" align="center" prop="eleboxParameter" />
<el-table-column label="参数值" align="center" prop="parameterData" /> <el-table-column label="参数值" align="center" prop="parameterData" />
<el-table-column label="数值单位" align="center" prop="dataUnits" /> <el-table-column label="数值单位" align="center" prop="dataUnits" />
<el-table-column label="记录时间" align="center" prop="logTime" width="180"> <el-table-column
label="记录时间"
align="center"
prop="logTime"
width="180"
>
<template slot-scope="scope"> <template slot-scope="scope">
<span>{{ parseTime(scope.row.logTime) }}</span> <span>{{ parseTime(scope.row.logTime) }}</span>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
<pagination <pagination
v-show="total>0" v-show="total > 0"
:total="total" :total="total"
:page.sync="queryParams.pageNum" :page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize" :limit.sync="queryParams.pageSize"
@pagination="getList" @pagination="getList"
/> />
</div> </div>
</template> </template>
<script> <script>
import {eleListData} from "@/api/tyler/power"; import { eleListData } from "@/api/tyler/power";
import {eleGetSubstationName,eleGetEleboxName,eleGetEleboxParameter} from "@/api/tyler/common"; import {
eleGetSubstationName,
eleGetEleboxName,
eleGetEleboxParameter,
} from "@/api/tyler/common";
export default { export default {
name: "Data", name: "Data",
data() { data() {
return { return {
...@@ -118,13 +180,13 @@ ...@@ -118,13 +180,13 @@
eleboxParameter: null, eleboxParameter: null,
parameterData: null, parameterData: null,
dataUnits: null, dataUnits: null,
logTime: null logTime: null,
}, },
// 表单参数 // 表单参数
form: {}, form: {},
SubstationNameList:[], SubstationNameList: [],
EleboxNameList:[], EleboxNameList: [],
EleboxParameterList:[], EleboxParameterList: [],
}; };
}, },
created() { created() {
...@@ -133,42 +195,49 @@ ...@@ -133,42 +195,49 @@
}, },
methods: { methods: {
//获取电站名称 //获取电站名称
getCommonSubstationName(){ getCommonSubstationName() {
eleGetSubstationName().then(res=>{ eleGetSubstationName().then((res) => {
this.SubstationNameList = res.data this.SubstationNameList = res.data;
}) });
}, },
//选择电站名称 //选择电站名称
substationNameChange(){ substationNameChange() {
this.getCommonEleboxName(); this.getCommonEleboxName();
this.queryParams.eleboxName = null; this.queryParams.eleboxName = null;
this.queryParams.eleboxParameter = null; this.queryParams.eleboxParameter = null;
}, },
//获取电箱名称 //获取电箱名称
getCommonEleboxName(){ getCommonEleboxName() {
eleGetEleboxName({substationName:this.queryParams.substationName}).then(res=>{ eleGetEleboxName({
this.EleboxNameList = res.data substationName: this.queryParams.substationName,
}) }).then((res) => {
this.EleboxNameList = res.data;
});
}, },
//选择电箱名称 //选择电箱名称
eleboxNameChange(){ eleboxNameChange() {
this.getCommonEleboxParameter(); this.getCommonEleboxParameter();
this.queryParams.eleboxParameter = null; this.queryParams.eleboxParameter = null;
}, },
//获取电箱参数名称 //获取电箱参数名称
getCommonEleboxParameter(){ getCommonEleboxParameter() {
eleGetEleboxParameter({substationName:this.queryParams.substationName,eleboxName:this.queryParams.eleboxName}).then(res=>{ eleGetEleboxParameter({
this.EleboxParameterList = res.data substationName: this.queryParams.substationName,
}) eleboxName: this.queryParams.eleboxName,
}).then((res) => {
this.EleboxParameterList = res.data;
});
}, },
/** 查询电力系统-历史数据列表 */ /** 查询电力系统-历史数据列表 */
getList() { getList() {
this.loading = true; this.loading = true;
eleListData(this.addDateRange(this.queryParams, this.dateRange)).then(response => { eleListData(this.addDateRange(this.queryParams, this.dateRange)).then(
(response) => {
this.dataList = response.rows; this.dataList = response.rows;
this.total = response.total; this.total = response.total;
this.loading = false; this.loading = false;
}); }
);
}, },
// 取消按钮 // 取消按钮
cancel() { cancel() {
...@@ -184,7 +253,7 @@ ...@@ -184,7 +253,7 @@
eleboxParameter: null, eleboxParameter: null,
parameterData: null, parameterData: null,
dataUnits: null, dataUnits: null,
logTime: null logTime: null,
}; };
this.resetForm("form"); this.resetForm("form");
}, },
...@@ -201,9 +270,9 @@ ...@@ -201,9 +270,9 @@
}, },
// 多选框选中数据 // 多选框选中数据
handleSelectionChange(selection) { handleSelectionChange(selection) {
this.ids = selection.map(item => item.id) this.ids = selection.map((item) => item.id);
this.single = selection.length!==1 this.single = selection.length !== 1;
this.multiple = !selection.length this.multiple = !selection.length;
}, },
/** 新增按钮操作 */ /** 新增按钮操作 */
handleAdd() { handleAdd() {
...@@ -214,8 +283,8 @@ ...@@ -214,8 +283,8 @@
/** 修改按钮操作 */ /** 修改按钮操作 */
handleUpdate(row) { handleUpdate(row) {
this.reset(); this.reset();
const id = row.id || this.ids const id = row.id || this.ids;
getData(id).then(response => { getData(id).then((response) => {
this.form = response.data; this.form = response.data;
this.open = true; this.open = true;
this.title = "修改电力系统-历史数据"; this.title = "修改电力系统-历史数据";
...@@ -223,16 +292,16 @@ ...@@ -223,16 +292,16 @@
}, },
/** 提交按钮 */ /** 提交按钮 */
submitForm() { submitForm() {
this.$refs["form"].validate(valid => { this.$refs["form"].validate((valid) => {
if (valid) { if (valid) {
if (this.form.id != null) { if (this.form.id != null) {
updateData(this.form).then(response => { updateData(this.form).then((response) => {
this.$modal.msgSuccess("修改成功"); this.$modal.msgSuccess("修改成功");
this.open = false; this.open = false;
this.getList(); this.getList();
}); });
} else { } else {
addData(this.form).then(response => { addData(this.form).then((response) => {
this.$modal.msgSuccess("新增成功"); this.$modal.msgSuccess("新增成功");
this.open = false; this.open = false;
this.getList(); this.getList();
...@@ -244,19 +313,25 @@ ...@@ -244,19 +313,25 @@
/** 删除按钮操作 */ /** 删除按钮操作 */
handleDelete(row) { handleDelete(row) {
const ids = row.id || this.ids; const ids = row.id || this.ids;
this.$modal.confirm('是否确认删除电力系统-历史数据编号为"' + ids + '"的数据项?').then(function() { this.$modal
.confirm('是否确认删除电力系统-历史数据编号为"' + ids + '"的数据项?')
.then(function () {
return delData(ids); return delData(ids);
}).then(() => { })
.then(() => {
this.getList(); this.getList();
this.$modal.msgSuccess("删除成功"); this.$modal.msgSuccess("删除成功");
}).catch(() => {}); })
.catch(() => {});
}, },
/** 导出按钮操作 */ /** 导出按钮操作 */
handleExport() { handleExport() {
this.download('business/data/export', { this.download(
...this.queryParams "/business/ele/export",
}, `data_${new Date().getTime()}.xlsx`) {},
} `电力设备历史记录_${new Date().getTime()}.xlsx`
} );
},
},
}; };
</script> </script>
...@@ -2,44 +2,59 @@ ...@@ -2,44 +2,59 @@
<div class=""> <div class="">
<el-card class="box-card"> <el-card class="box-card">
<div slot="header" class="clearfix"> <div slot="header" class="clearfix">
<span>{{ selectedRow ? selectedRow.partName : '名称' }}</span> <span>{{ selectedRow ? selectedRow.partName : "名称" }}</span>
<el-button style="float: right; padding: 3px 0" type="text" @click="handleAdd">添加摄像头</el-button> <el-button
style="float: right; padding: 3px 0"
type="text"
@click="handleAdd"
>添加摄像头</el-button
>
</div> </div>
<!-- 在这里可以添加其他逻辑,根据 selectedRow 渲染内容 --> <!-- 在这里可以添加其他逻辑,根据 selectedRow 渲染内容 -->
<el-table v-loading="loading" :data="tableList" @selection-change="handleSelectionChange"> <el-table
v-loading="loading"
:data="tableList"
@selection-change="handleSelectionChange"
>
<!-- <el-table-column type="selection" width="55" align="center" /> --> <!-- <el-table-column type="selection" width="55" align="center" /> -->
<el-table-column label="序号" align="center" type="index" width="50"/> <el-table-column label="序号" align="center" type="index" width="50" />
<el-table-column label="摄像头名称" align="center" prop="cameraName" /> <el-table-column label="摄像头名称" align="center" prop="cameraName" />
<el-table-column label="摄像头编码" align="center" prop="cameraNum" /> <!-- <el-table-column label="摄像头编码" align="center" prop="cameraNum" /> -->
<el-table-column label="摄像头通道编号" align="center" prop="cameraPassNum" /> <!-- <el-table-column label="摄像头通道编号" align="center" prop="cameraPassNum" /> -->
<!-- <el-table-column label="摄像头ip" align="center" prop="cameraIp" /> --> <!-- <el-table-column label="摄像头ip" align="center" prop="cameraIp" /> -->
<el-table-column label="摄像头url" align="center" prop="cameraUrl" /> <el-table-column label="摄像头url" align="center" prop="cameraUrl" />
<el-table-column label="状态" align="center" prop="status"> <!-- <el-table-column label="状态" align="center" prop="status">
<template slot-scope="scope"> <template slot-scope="scope">
<el-tag v-if="scope.row.status==1">正常</el-tag> <el-tag v-if="scope.row.status==1">正常</el-tag>
<el-tag v-else type="warning">异常</el-tag> <el-tag v-else type="warning">异常</el-tag>
</template> </template>
</el-table-column> </el-table-column> -->
<el-table-column label="操作" align="center" class-name="small-padding fixed-width"> <el-table-column
label="操作"
align="center"
class-name="small-padding fixed-width"
>
<template slot-scope="scope"> <template slot-scope="scope">
<el-button <el-button
size="mini" size="mini"
type="text" type="text"
icon="el-icon-edit" icon="el-icon-edit"
@click="handleUpdate(scope.row)" @click="handleUpdate(scope.row)"
>修改</el-button> >修改</el-button
>
<el-button <el-button
size="mini" size="mini"
type="text" type="text"
icon="el-icon-delete" icon="el-icon-delete"
@click="handleDelete(scope.row)" @click="handleDelete(scope.row)"
>删除</el-button> >删除</el-button
>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
<pagination <pagination
v-show="total>0" v-show="total > 0"
:total="total" :total="total"
:page.sync="queryParams.pageNum" :page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize" :limit.sync="queryParams.pageSize"
...@@ -56,7 +71,10 @@ ...@@ -56,7 +71,10 @@
<el-input v-model="form.cameraNum" placeholder="请输入摄像头编码" /> <el-input v-model="form.cameraNum" placeholder="请输入摄像头编码" />
</el-form-item> </el-form-item>
<el-form-item label="通道编号" prop="cameraPassNum"> <el-form-item label="通道编号" prop="cameraPassNum">
<el-input v-model="form.cameraPassNum" placeholder="请输入摄像头通道编号" /> <el-input
v-model="form.cameraPassNum"
placeholder="请输入摄像头通道编号"
/>
</el-form-item> </el-form-item>
<!-- <el-form-item label="摄像头ip" prop="cameraIp"> <!-- <el-form-item label="摄像头ip" prop="cameraIp">
<el-input v-model="form.cameraIp" placeholder="请输入摄像头ip" /> <el-input v-model="form.cameraIp" placeholder="请输入摄像头ip" />
...@@ -64,9 +82,6 @@ ...@@ -64,9 +82,6 @@
<el-form-item label="摄像头url" prop="cameraUrl"> <el-form-item label="摄像头url" prop="cameraUrl">
<el-input v-model="form.cameraUrl" placeholder="请输入摄像头url" /> <el-input v-model="form.cameraUrl" placeholder="请输入摄像头url" />
</el-form-item> </el-form-item>
</el-form> </el-form>
<div slot="footer" class="dialog-footer"> <div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitForm">确 定</el-button> <el-button type="primary" @click="submitForm">确 定</el-button>
...@@ -77,7 +92,13 @@ ...@@ -77,7 +92,13 @@
</template> </template>
<script> <script>
import {getVideoTable, listVideoTable, addVideoTable, updateVideoTable, delVideoTable } from "@/api/tyler/videoTable"; import {
getVideoTable,
listVideoTable,
addVideoTable,
updateVideoTable,
delVideoTable,
} from "@/api/tyler/videoTable";
export default { export default {
name: "videoRight", name: "videoRight",
props: { props: {
...@@ -119,20 +140,17 @@ export default { ...@@ -119,20 +140,17 @@ export default {
cameraUrl: null, cameraUrl: null,
partId: null, partId: null,
cameraWeizhi: null, cameraWeizhi: null,
flag: null flag: null,
}, },
// 表单参数 // 表单参数
form: {}, form: {},
// 表单校验 // 表单校验
rules: { rules: {
id: [ id: [{ required: true, message: "不能为空", trigger: "blur" }],
{ required: true, message: "不能为空", trigger: "blur" } },
],
}
}; };
}, },
created() { created() {
// this.getList(); // this.getList();
}, },
watch: { watch: {
...@@ -141,7 +159,7 @@ export default { ...@@ -141,7 +159,7 @@ export default {
immediate: true, // 立即执行 immediate: true, // 立即执行
handler(newVal) { handler(newVal) {
if (newVal) { if (newVal) {
this.queryParams.partId = newVal.id this.queryParams.partId = newVal.id;
this.getList(); this.getList();
} }
}, },
...@@ -151,7 +169,7 @@ export default { ...@@ -151,7 +169,7 @@ export default {
/** 查询摄像头列表 */ /** 查询摄像头列表 */
getList() { getList() {
this.loading = true; this.loading = true;
listVideoTable(this.queryParams).then(response => { listVideoTable(this.queryParams).then((response) => {
this.tableList = response.rows; this.tableList = response.rows;
this.total = response.total; this.total = response.total;
this.loading = false; this.loading = false;
...@@ -174,7 +192,7 @@ export default { ...@@ -174,7 +192,7 @@ export default {
partId: null, partId: null,
remark: null, remark: null,
cameraWeizhi: null, cameraWeizhi: null,
flag: null flag: null,
}; };
this.resetForm("form"); this.resetForm("form");
}, },
...@@ -190,22 +208,22 @@ export default { ...@@ -190,22 +208,22 @@ export default {
}, },
// 多选框选中数据 // 多选框选中数据
handleSelectionChange(selection) { handleSelectionChange(selection) {
this.ids = selection.map(item => item.id) this.ids = selection.map((item) => item.id);
this.single = selection.length!==1 this.single = selection.length !== 1;
this.multiple = !selection.length this.multiple = !selection.length;
}, },
/** 新增按钮操作 */ /** 新增按钮操作 */
handleAdd() { handleAdd() {
this.reset(); this.reset();
this.open = true; this.open = true;
this.form.partId = this.selectedRow.id this.form.partId = this.selectedRow.id;
this.title = "添加摄像头"; this.title = "添加摄像头";
}, },
/** 修改按钮操作 */ /** 修改按钮操作 */
handleUpdate(row) { handleUpdate(row) {
this.reset(); this.reset();
const id = row.id || this.ids const id = row.id || this.ids;
getVideoTable(id).then(response => { getVideoTable(id).then((response) => {
this.form = response.data; this.form = response.data;
this.open = true; this.open = true;
this.title = "修改摄像头"; this.title = "修改摄像头";
...@@ -213,16 +231,16 @@ export default { ...@@ -213,16 +231,16 @@ export default {
}, },
/** 提交按钮 */ /** 提交按钮 */
submitForm() { submitForm() {
this.$refs["form"].validate(valid => { this.$refs["form"].validate((valid) => {
if (valid) { if (valid) {
if (this.form.id != null) { if (this.form.id != null) {
updateVideoTable(this.form).then(response => { updateVideoTable(this.form).then((response) => {
this.$modal.msgSuccess("修改成功"); this.$modal.msgSuccess("修改成功");
this.open = false; this.open = false;
this.getList(); this.getList();
}); });
} else { } else {
addVideoTable(this.form).then(response => { addVideoTable(this.form).then((response) => {
this.$modal.msgSuccess("新增成功"); this.$modal.msgSuccess("新增成功");
this.open = false; this.open = false;
this.getList(); this.getList();
...@@ -234,14 +252,17 @@ export default { ...@@ -234,14 +252,17 @@ export default {
/** 删除按钮操作 */ /** 删除按钮操作 */
handleDelete(row) { handleDelete(row) {
const ids = row.id || this.ids; const ids = row.id || this.ids;
this.$modal.confirm('是否确认删除?').then(function() { this.$modal
.confirm("是否确认删除?")
.then(function () {
return delVideoTable(ids); return delVideoTable(ids);
}).then(() => { })
.then(() => {
this.getList(); this.getList();
this.$modal.msgSuccess("删除成功"); this.$modal.msgSuccess("删除成功");
}).catch(() => {}); })
.catch(() => {});
}, },
}, },
}; };
</script> </script>
<template> <template>
<div class="app-container"> <div class="app-container">
<el-row :gutter="20"> <el-row :gutter="20">
<splitpanes :horizontal="this.$store.getters.device === 'mobile'" class="default-theme"> <splitpanes
:horizontal="this.$store.getters.device === 'mobile'"
class="default-theme"
>
<!--部门数据--> <!--部门数据-->
<pane size="16"> <pane size="16">
<el-col> <el-col>
<div class="head-container"> <div class="head-container">
<el-input v-model="deptName" placeholder="请输入部门名称" clearable size="small" prefix-icon="el-icon-search" style="margin-bottom: 20px" /> <el-input
v-model="deptName"
placeholder="请输入部门名称"
clearable
size="small"
prefix-icon="el-icon-search"
style="margin-bottom: 20px"
/>
</div> </div>
<div class="head-container"> <div class="head-container">
<el-tree <el-tree
...@@ -26,16 +36,45 @@ ...@@ -26,16 +36,45 @@
<!--用户数据--> <!--用户数据-->
<pane size="84"> <pane size="84">
<el-col> <el-col>
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px"> <el-form
<el-form-item label="用户名称" prop="userName"> :model="queryParams"
<el-input v-model="queryParams.userName" placeholder="请输入用户名称" clearable style="width: 240px" @keyup.enter.native="handleQuery" /> ref="queryForm"
size="small"
:inline="true"
v-show="showSearch"
label-width="68px"
>
<el-form-item label="账号" prop="userName">
<el-input
v-model="queryParams.userName"
placeholder="请输入用户名称"
clearable
style="width: 240px"
@keyup.enter.native="handleQuery"
/>
</el-form-item> </el-form-item>
<el-form-item label="手机号码" prop="phonenumber"> <el-form-item label="手机号码" prop="phonenumber">
<el-input v-model="queryParams.phonenumber" placeholder="请输入手机号码" clearable style="width: 240px" @keyup.enter.native="handleQuery" /> <el-input
v-model="queryParams.phonenumber"
placeholder="请输入手机号码"
clearable
style="width: 240px"
@keyup.enter.native="handleQuery"
/>
</el-form-item> </el-form-item>
<el-form-item label="状态" prop="status"> <el-form-item label="状态" prop="status">
<el-select v-model="queryParams.status" placeholder="用户状态" clearable style="width: 240px"> <el-select
<el-option v-for="dict in dict.type.sys_normal_disable" :key="dict.value" :label="dict.label" :value="dict.value" /> v-model="queryParams.status"
placeholder="用户状态"
clearable
style="width: 240px"
>
<el-option
v-for="dict in dict.type.sys_normal_disable"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="创建时间"> <el-form-item label="创建时间">
...@@ -50,67 +89,218 @@ ...@@ -50,67 +89,218 @@
></el-date-picker> ></el-date-picker>
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button> <el-button
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button> type="primary"
icon="el-icon-search"
size="mini"
@click="handleQuery"
>搜索</el-button
>
<el-button
icon="el-icon-refresh"
size="mini"
@click="resetQuery"
>重置</el-button
>
</el-form-item> </el-form-item>
</el-form> </el-form>
<el-row :gutter="10" class="mb8"> <el-row :gutter="10" class="mb8">
<el-col :span="1.5"> <el-col :span="1.5">
<el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAdd" v-hasPermi="['system:user:add']">新增</el-button> <el-button
type="primary"
plain
icon="el-icon-plus"
size="mini"
@click="handleAdd"
v-hasPermi="['system:user:add']"
>新增</el-button
>
</el-col> </el-col>
<el-col :span="1.5"> <el-col :span="1.5">
<el-button type="success" plain icon="el-icon-edit" size="mini" :disabled="single" @click="handleUpdate" v-hasPermi="['system:user:edit']" <el-button
type="success"
plain
icon="el-icon-edit"
size="mini"
:disabled="single"
@click="handleUpdate"
v-hasPermi="['system:user:edit']"
>修改</el-button >修改</el-button
> >
</el-col> </el-col>
<el-col :span="1.5"> <el-col :span="1.5">
<el-button type="danger" plain icon="el-icon-delete" size="mini" :disabled="multiple" @click="handleDelete" v-hasPermi="['system:user:remove']" <el-button
type="danger"
plain
icon="el-icon-delete"
size="mini"
:disabled="multiple"
@click="handleDelete"
v-hasPermi="['system:user:remove']"
>删除</el-button >删除</el-button
> >
</el-col> </el-col>
<el-col :span="1.5"> <el-col :span="1.5">
<el-button type="info" plain icon="el-icon-upload2" size="mini" @click="handleImport" v-hasPermi="['system:user:import']">导入</el-button> <el-button
type="info"
plain
icon="el-icon-upload2"
size="mini"
@click="handleImport"
v-hasPermi="['system:user:import']"
>导入</el-button
>
</el-col> </el-col>
<el-col :span="1.5"> <el-col :span="1.5">
<el-button type="warning" plain icon="el-icon-download" size="mini" @click="handleExport" v-hasPermi="['system:user:export']">导出</el-button> <el-button
type="warning"
plain
icon="el-icon-download"
size="mini"
@click="handleExport"
v-hasPermi="['system:user:export']"
>导出</el-button
>
</el-col> </el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList" :columns="columns"></right-toolbar> <right-toolbar
:showSearch.sync="showSearch"
@queryTable="getList"
:columns="columns"
></right-toolbar>
</el-row> </el-row>
<el-table v-loading="loading" :data="userList" @selection-change="handleSelectionChange"> <el-table
v-loading="loading"
:data="userList"
@selection-change="handleSelectionChange"
>
<el-table-column type="selection" width="50" align="center" /> <el-table-column type="selection" width="50" align="center" />
<el-table-column label="用户编号" align="center" key="userId" prop="userId" v-if="columns[0].visible" /> <el-table-column
<el-table-column label="账号" align="center" key="userName" prop="userName" v-if="columns[1].visible" :show-overflow-tooltip="true" /> label="用户编号"
<el-table-column label="姓名" align="center" key="nickName" prop="nickName" v-if="columns[2].visible" :show-overflow-tooltip="true" /> align="center"
<el-table-column label="部门" align="center" key="deptName" prop="dept.deptName" v-if="columns[3].visible" :show-overflow-tooltip="true" /> key="userId"
<el-table-column label="手机号码" align="center" key="phonenumber" prop="phonenumber" v-if="columns[4].visible" width="120" /> prop="userId"
<el-table-column label="状态" align="center" key="status" v-if="columns[5].visible"> v-if="columns[0].visible"
/>
<el-table-column
label="账号"
align="center"
key="userName"
prop="userName"
v-if="columns[1].visible"
:show-overflow-tooltip="true"
/>
<el-table-column
label="姓名"
align="center"
key="nickName"
prop="nickName"
v-if="columns[2].visible"
:show-overflow-tooltip="true"
/>
<el-table-column
label="部门"
align="center"
key="deptName"
prop="dept.deptName"
v-if="columns[3].visible"
:show-overflow-tooltip="true"
/>
<el-table-column
label="手机号码"
align="center"
key="phonenumber"
prop="phonenumber"
v-if="columns[4].visible"
width="120"
/>
<el-table-column
label="状态"
align="center"
key="status"
v-if="columns[5].visible"
>
<template slot-scope="scope"> <template slot-scope="scope">
<el-switch v-model="scope.row.status" active-value="0" inactive-value="1" @change="handleStatusChange(scope.row)"></el-switch> <el-switch
v-model="scope.row.status"
active-value="0"
inactive-value="1"
@change="handleStatusChange(scope.row)"
></el-switch>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="创建时间" align="center" prop="createTime" v-if="columns[6].visible" width="160"> <el-table-column
label="创建时间"
align="center"
prop="createTime"
v-if="columns[6].visible"
width="160"
>
<template slot-scope="scope"> <template slot-scope="scope">
<span>{{ parseTime(scope.row.createTime) }}</span> <span>{{ parseTime(scope.row.createTime) }}</span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="操作" align="center" width="160" class-name="small-padding fixed-width"> <el-table-column
label="操作"
align="center"
width="160"
class-name="small-padding fixed-width"
>
<template slot-scope="scope" v-if="scope.row.userId !== 1"> <template slot-scope="scope" v-if="scope.row.userId !== 1">
<el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)" v-hasPermi="['system:user:edit']">修改</el-button> <el-button
<el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)" v-hasPermi="['system:user:remove']">删除</el-button> size="mini"
<el-dropdown size="mini" @command="(command) => handleCommand(command, scope.row)" v-hasPermi="['system:user:resetPwd', 'system:user:edit']"> type="text"
<el-button size="mini" type="text" icon="el-icon-d-arrow-right">更多</el-button> icon="el-icon-edit"
@click="handleUpdate(scope.row)"
v-hasPermi="['system:user:edit']"
>修改</el-button
>
<el-button
size="mini"
type="text"
icon="el-icon-delete"
@click="handleDelete(scope.row)"
v-hasPermi="['system:user:remove']"
>删除</el-button
>
<el-dropdown
size="mini"
@command="(command) => handleCommand(command, scope.row)"
v-hasPermi="['system:user:resetPwd', 'system:user:edit']"
>
<el-button
size="mini"
type="text"
icon="el-icon-d-arrow-right"
>更多</el-button
>
<el-dropdown-menu slot="dropdown"> <el-dropdown-menu slot="dropdown">
<el-dropdown-item command="handleResetPwd" icon="el-icon-key" v-hasPermi="['system:user:resetPwd']">重置密码</el-dropdown-item> <el-dropdown-item
<el-dropdown-item command="handleAuthRole" icon="el-icon-circle-check" v-hasPermi="['system:user:edit']">分配角色</el-dropdown-item> command="handleResetPwd"
icon="el-icon-key"
v-hasPermi="['system:user:resetPwd']"
>重置密码</el-dropdown-item
>
<el-dropdown-item
command="handleAuthRole"
icon="el-icon-circle-check"
v-hasPermi="['system:user:edit']"
>分配角色</el-dropdown-item
>
</el-dropdown-menu> </el-dropdown-menu>
</el-dropdown> </el-dropdown>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
<pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize" @pagination="getList" /> <pagination
v-show="total > 0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
</el-col> </el-col>
</pane> </pane>
</splitpanes> </splitpanes>
...@@ -121,37 +311,72 @@ ...@@ -121,37 +311,72 @@
<el-form ref="form" :model="form" :rules="rules" label-width="80px"> <el-form ref="form" :model="form" :rules="rules" label-width="80px">
<el-row> <el-row>
<el-col :span="12"> <el-col :span="12">
<el-form-item label="用户昵称" prop="nickName"> <el-form-item label="姓名" prop="nickName">
<el-input v-model="form.nickName" placeholder="请输入用户昵称" maxlength="30" /> <el-input
v-model="form.nickName"
placeholder="请输入用户昵称"
maxlength="30"
/>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12"> <el-col :span="12">
<el-form-item label="归属部门" prop="deptId"> <el-form-item label="归属部门" prop="deptId">
<treeselect v-model="form.deptId" :options="enabledDeptOptions" :show-count="true" placeholder="请选择归属部门" /> <treeselect
v-model="form.deptId"
:options="enabledDeptOptions"
:show-count="true"
placeholder="请选择归属部门"
/>
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> </el-row>
<el-row> <el-row>
<el-col :span="12"> <el-col :span="12">
<el-form-item label="手机号码" prop="phonenumber"> <el-form-item label="手机号码" prop="phonenumber">
<el-input v-model="form.phonenumber" placeholder="请输入手机号码" maxlength="11" /> <el-input
v-model="form.phonenumber"
placeholder="请输入手机号码"
maxlength="11"
/>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12"> <el-col :span="12">
<el-form-item label="邮箱" prop="email"> <el-form-item label="邮箱" prop="email">
<el-input v-model="form.email" placeholder="请输入邮箱" maxlength="50" /> <el-input
v-model="form.email"
placeholder="请输入邮箱"
maxlength="50"
/>
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> </el-row>
<el-row> <el-row>
<el-col :span="12"> <el-col :span="12">
<el-form-item v-if="form.userId == undefined" label="用户名称" prop="userName"> <el-form-item
<el-input v-model="form.userName" placeholder="请输入用户名称" maxlength="30" /> v-if="form.userId == undefined"
label="账号"
prop="userName"
>
<el-input
v-model="form.userName"
placeholder="请输入用户名称"
maxlength="30"
/>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12"> <el-col :span="12">
<el-form-item v-if="form.userId == undefined" label="用户密码" prop="password"> <el-form-item
<el-input v-model="form.password" placeholder="请输入用户密码" type="password" maxlength="20" show-password /> v-if="form.userId == undefined"
label="用户密码"
prop="password"
>
<el-input
v-model="form.password"
placeholder="请输入用户密码"
type="password"
maxlength="20"
show-password
/>
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> </el-row>
...@@ -159,14 +384,24 @@ ...@@ -159,14 +384,24 @@
<el-col :span="12"> <el-col :span="12">
<el-form-item label="用户性别"> <el-form-item label="用户性别">
<el-select v-model="form.sex" placeholder="请选择性别"> <el-select v-model="form.sex" placeholder="请选择性别">
<el-option v-for="dict in dict.type.sys_user_sex" :key="dict.value" :label="dict.label" :value="dict.value"></el-option> <el-option
v-for="dict in dict.type.sys_user_sex"
:key="dict.value"
:label="dict.label"
:value="dict.value"
></el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12"> <el-col :span="12">
<el-form-item label="状态"> <el-form-item label="状态">
<el-radio-group v-model="form.status"> <el-radio-group v-model="form.status">
<el-radio v-for="dict in dict.type.sys_normal_disable" :key="dict.value" :label="dict.value">{{ dict.label }}</el-radio> <el-radio
v-for="dict in dict.type.sys_normal_disable"
:key="dict.value"
:label="dict.value"
>{{ dict.label }}</el-radio
>
</el-radio-group> </el-radio-group>
</el-form-item> </el-form-item>
</el-col> </el-col>
...@@ -174,15 +409,35 @@ ...@@ -174,15 +409,35 @@
<el-row> <el-row>
<el-col :span="12"> <el-col :span="12">
<el-form-item label="岗位"> <el-form-item label="岗位">
<el-select v-model="form.postIds" multiple placeholder="请选择岗位"> <el-select
<el-option v-for="item in postOptions" :key="item.postId" :label="item.postName" :value="item.postId" :disabled="item.status == 1"></el-option> v-model="form.postIds"
multiple
placeholder="请选择岗位"
>
<el-option
v-for="item in postOptions"
:key="item.postId"
:label="item.postName"
:value="item.postId"
:disabled="item.status == 1"
></el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12"> <el-col :span="12">
<el-form-item label="角色"> <el-form-item label="角色">
<el-select v-model="form.roleIds" multiple placeholder="请选择角色"> <el-select
<el-option v-for="item in roleOptions" :key="item.roleId" :label="item.roleName" :value="item.roleId" :disabled="item.status == 1"></el-option> v-model="form.roleIds"
multiple
placeholder="请选择角色"
>
<el-option
v-for="item in roleOptions"
:key="item.roleId"
:label="item.roleName"
:value="item.roleId"
:disabled="item.status == 1"
></el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
</el-col> </el-col>
...@@ -190,7 +445,11 @@ ...@@ -190,7 +445,11 @@
<el-row> <el-row>
<el-col :span="24"> <el-col :span="24">
<el-form-item label="备注"> <el-form-item label="备注">
<el-input v-model="form.remark" type="textarea" placeholder="请输入内容"></el-input> <el-input
v-model="form.remark"
type="textarea"
placeholder="请输入内容"
></el-input>
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> </el-row>
...@@ -202,7 +461,12 @@ ...@@ -202,7 +461,12 @@
</el-dialog> </el-dialog>
<!-- 用户导入对话框 --> <!-- 用户导入对话框 -->
<el-dialog :title="upload.title" :visible.sync="upload.open" width="400px" append-to-body> <el-dialog
:title="upload.title"
:visible.sync="upload.open"
width="400px"
append-to-body
>
<el-upload <el-upload
ref="upload" ref="upload"
:limit="1" :limit="1"
...@@ -218,9 +482,19 @@ ...@@ -218,9 +482,19 @@
<i class="el-icon-upload"></i> <i class="el-icon-upload"></i>
<div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div> <div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
<div class="el-upload__tip text-center" slot="tip"> <div class="el-upload__tip text-center" slot="tip">
<div class="el-upload__tip" slot="tip"><el-checkbox v-model="upload.updateSupport" />是否更新已经存在的用户数据</div> <div class="el-upload__tip" slot="tip">
<el-checkbox
v-model="upload.updateSupport"
/>是否更新已经存在的用户数据
</div>
<span>仅允许导入xls、xlsx格式文件。</span> <span>仅允许导入xls、xlsx格式文件。</span>
<el-link type="primary" :underline="false" style="font-size: 12px; vertical-align: baseline" @click="importTemplate">下载模板</el-link> <el-link
type="primary"
:underline="false"
style="font-size: 12px; vertical-align: baseline"
@click="importTemplate"
>下载模板</el-link
>
</div> </div>
</el-upload> </el-upload>
<div slot="footer" class="dialog-footer"> <div slot="footer" class="dialog-footer">
...@@ -232,16 +506,25 @@ ...@@ -232,16 +506,25 @@
</template> </template>
<script> <script>
import { listUser, getUser, delUser, addUser, updateUser, resetUserPwd, changeUserStatus, deptTreeSelect } from '@/api/system/user' import {
import { getToken } from '@/utils/auth' listUser,
import Treeselect from '@riophae/vue-treeselect' getUser,
import '@riophae/vue-treeselect/dist/vue-treeselect.css' delUser,
import { Splitpanes, Pane } from 'splitpanes' addUser,
import 'splitpanes/dist/splitpanes.css' updateUser,
resetUserPwd,
changeUserStatus,
deptTreeSelect,
} from "@/api/system/user";
import { getToken } from "@/utils/auth";
import Treeselect from "@riophae/vue-treeselect";
import "@riophae/vue-treeselect/dist/vue-treeselect.css";
import { Splitpanes, Pane } from "splitpanes";
import "splitpanes/dist/splitpanes.css";
export default { export default {
name: 'User', name: "User",
dicts: ['sys_normal_disable', 'sys_user_sex'], dicts: ["sys_normal_disable", "sys_user_sex"],
components: { Treeselect, Splitpanes, Pane }, components: { Treeselect, Splitpanes, Pane },
data() { data() {
return { return {
...@@ -260,7 +543,7 @@ export default { ...@@ -260,7 +543,7 @@ export default {
// 用户表格数据 // 用户表格数据
userList: null, userList: null,
// 弹出层标题 // 弹出层标题
title: '', title: "",
// 所有部门树选项 // 所有部门树选项
deptOptions: undefined, deptOptions: undefined,
// 过滤掉已禁用部门树选项 // 过滤掉已禁用部门树选项
...@@ -280,23 +563,23 @@ export default { ...@@ -280,23 +563,23 @@ export default {
// 表单参数 // 表单参数
form: {}, form: {},
defaultProps: { defaultProps: {
children: 'children', children: "children",
label: 'label', label: "label",
}, },
// 用户导入参数 // 用户导入参数
upload: { upload: {
// 是否显示弹出层(用户导入) // 是否显示弹出层(用户导入)
open: false, open: false,
// 弹出层标题(用户导入) // 弹出层标题(用户导入)
title: '', title: "",
// 是否禁用上传 // 是否禁用上传
isUploading: false, isUploading: false,
// 是否更新已经存在的用户数据 // 是否更新已经存在的用户数据
updateSupport: 0, updateSupport: 0,
// 设置上传的请求头部 // 设置上传的请求头部
headers: { Authorization: 'Bearer ' + getToken() }, headers: { Authorization: "Bearer " + getToken() },
// 上传的地址 // 上传的地址
url: process.env.VUE_APP_BASE_API + '/system/user/importData', url: process.env.VUE_APP_BASE_API + "/system/user/importData",
}, },
// 查询参数 // 查询参数
queryParams: { queryParams: {
...@@ -310,8 +593,8 @@ export default { ...@@ -310,8 +593,8 @@ export default {
// 列信息 // 列信息
columns: [ columns: [
{ key: 0, label: `用户编号`, visible: true }, { key: 0, label: `用户编号`, visible: true },
{ key: 1, label: `用户名称`, visible: true }, { key: 1, label: `账号`, visible: true },
{ key: 2, label: `用户昵称`, visible: true }, { key: 2, label: `姓名`, visible: true },
{ key: 3, label: `部门`, visible: true }, { key: 3, label: `部门`, visible: true },
{ key: 4, label: `手机号码`, visible: true }, { key: 4, label: `手机号码`, visible: true },
{ key: 5, label: `状态`, visible: true }, { key: 5, label: `状态`, visible: true },
...@@ -320,103 +603,123 @@ export default { ...@@ -320,103 +603,123 @@ export default {
// 表单校验 // 表单校验
rules: { rules: {
userName: [ userName: [
{ required: true, message: '用户名称不能为空', trigger: 'blur' }, { required: true, message: "用户名称不能为空", trigger: "blur" },
{ min: 2, max: 20, message: '用户名称长度必须介于 2 和 20 之间', trigger: 'blur' }, {
min: 2,
max: 20,
message: "用户名称长度必须介于 2 和 20 之间",
trigger: "blur",
},
],
nickName: [
{ required: true, message: "用户昵称不能为空", trigger: "blur" },
], ],
nickName: [{ required: true, message: '用户昵称不能为空', trigger: 'blur' }],
password: [ password: [
{ required: true, message: '用户密码不能为空', trigger: 'blur' }, { required: true, message: "用户密码不能为空", trigger: "blur" },
{ min: 5, max: 20, message: '用户密码长度必须介于 5 和 20 之间', trigger: 'blur' }, {
{ pattern: /^[^<>"'|\\]+$/, message: '不能包含非法字符:< > " \' \\ |', trigger: 'blur' }, min: 5,
max: 20,
message: "用户密码长度必须介于 5 和 20 之间",
trigger: "blur",
},
{
pattern: /^[^<>"'|\\]+$/,
message: "不能包含非法字符:< > \" ' \\ |",
trigger: "blur",
},
], ],
email: [ email: [
{ {
type: 'email', type: "email",
message: '请输入正确的邮箱地址', message: "请输入正确的邮箱地址",
trigger: ['blur', 'change'], trigger: ["blur", "change"],
}, },
], ],
phonenumber: [ phonenumber: [
{ {
pattern: /^1[3|4|5|6|7|8|9][0-9]\d{8}$/, pattern: /^1[3|4|5|6|7|8|9][0-9]\d{8}$/,
message: '请输入正确的手机号码', message: "请输入正确的手机号码",
trigger: 'blur', trigger: "blur",
}, },
], ],
}, },
} };
}, },
watch: { watch: {
// 根据名称筛选部门树 // 根据名称筛选部门树
deptName(val) { deptName(val) {
this.$refs.tree.filter(val) this.$refs.tree.filter(val);
}, },
}, },
created() { created() {
this.getList() this.getList();
this.getDeptTree() this.getDeptTree();
this.getConfigKey('sys.user.initPassword').then((response) => { this.getConfigKey("sys.user.initPassword").then((response) => {
this.initPassword = response.msg this.initPassword = response.msg;
}) });
}, },
methods: { methods: {
/** 查询用户列表 */ /** 查询用户列表 */
getList() { getList() {
this.loading = true this.loading = true;
listUser(this.addDateRange(this.queryParams, this.dateRange)).then((response) => { listUser(this.addDateRange(this.queryParams, this.dateRange)).then(
this.userList = response.rows (response) => {
this.total = response.total this.userList = response.rows;
this.loading = false this.total = response.total;
}) this.loading = false;
}
);
}, },
/** 查询部门下拉树结构 */ /** 查询部门下拉树结构 */
getDeptTree() { getDeptTree() {
deptTreeSelect().then((response) => { deptTreeSelect().then((response) => {
this.deptOptions = response.data this.deptOptions = response.data;
this.enabledDeptOptions = this.filterDisabledDept(JSON.parse(JSON.stringify(response.data))) this.enabledDeptOptions = this.filterDisabledDept(
}) JSON.parse(JSON.stringify(response.data))
);
});
}, },
// 过滤禁用的部门 // 过滤禁用的部门
filterDisabledDept(deptList) { filterDisabledDept(deptList) {
return deptList.filter((dept) => { return deptList.filter((dept) => {
if (dept.disabled) { if (dept.disabled) {
return false return false;
} }
if (dept.children && dept.children.length) { if (dept.children && dept.children.length) {
dept.children = this.filterDisabledDept(dept.children) dept.children = this.filterDisabledDept(dept.children);
} }
return true return true;
}) });
}, },
// 筛选节点 // 筛选节点
filterNode(value, data) { filterNode(value, data) {
if (!value) return true if (!value) return true;
return data.label.indexOf(value) !== -1 return data.label.indexOf(value) !== -1;
}, },
// 节点单击事件 // 节点单击事件
handleNodeClick(data) { handleNodeClick(data) {
this.queryParams.deptId = data.id this.queryParams.deptId = data.id;
this.handleQuery() this.handleQuery();
}, },
// 用户状态修改 // 用户状态修改
handleStatusChange(row) { handleStatusChange(row) {
let text = row.status === '0' ? '启用' : '停用' let text = row.status === "0" ? "启用" : "停用";
this.$modal this.$modal
.confirm('确认要"' + text + '""' + row.userName + '"用户吗?') .confirm('确认要"' + text + '""' + row.userName + '"用户吗?')
.then(function () { .then(function () {
return changeUserStatus(row.userId, row.status) return changeUserStatus(row.userId, row.status);
}) })
.then(() => { .then(() => {
this.$modal.msgSuccess(text + '成功') this.$modal.msgSuccess(text + "成功");
}) })
.catch(function () { .catch(function () {
row.status = row.status === '0' ? '1' : '0' row.status = row.status === "0" ? "1" : "0";
}) });
}, },
// 取消按钮 // 取消按钮
cancel() { cancel() {
this.open = false this.open = false;
this.reset() this.reset();
}, },
// 表单重置 // 表单重置
reset() { reset() {
...@@ -429,168 +732,178 @@ export default { ...@@ -429,168 +732,178 @@ export default {
phonenumber: undefined, phonenumber: undefined,
email: undefined, email: undefined,
sex: undefined, sex: undefined,
status: '0', status: "0",
remark: undefined, remark: undefined,
postIds: [], postIds: [],
roleIds: [], roleIds: [],
} };
this.resetForm('form') this.resetForm("form");
}, },
/** 搜索按钮操作 */ /** 搜索按钮操作 */
handleQuery() { handleQuery() {
this.queryParams.pageNum = 1 this.queryParams.pageNum = 1;
this.getList() this.getList();
}, },
/** 重置按钮操作 */ /** 重置按钮操作 */
resetQuery() { resetQuery() {
this.dateRange = [] this.dateRange = [];
this.resetForm('queryForm') this.resetForm("queryForm");
this.queryParams.deptId = undefined this.queryParams.deptId = undefined;
this.$refs.tree.setCurrentKey(null) this.$refs.tree.setCurrentKey(null);
this.handleQuery() this.handleQuery();
}, },
// 多选框选中数据 // 多选框选中数据
handleSelectionChange(selection) { handleSelectionChange(selection) {
this.ids = selection.map((item) => item.userId) this.ids = selection.map((item) => item.userId);
this.single = selection.length != 1 this.single = selection.length != 1;
this.multiple = !selection.length this.multiple = !selection.length;
}, },
// 更多操作触发 // 更多操作触发
handleCommand(command, row) { handleCommand(command, row) {
switch (command) { switch (command) {
case 'handleResetPwd': case "handleResetPwd":
this.handleResetPwd(row) this.handleResetPwd(row);
break break;
case 'handleAuthRole': case "handleAuthRole":
this.handleAuthRole(row) this.handleAuthRole(row);
break break;
default: default:
break break;
} }
}, },
/** 新增按钮操作 */ /** 新增按钮操作 */
handleAdd() { handleAdd() {
this.reset() this.reset();
getUser().then((response) => { getUser().then((response) => {
this.postOptions = response.posts this.postOptions = response.posts;
this.roleOptions = response.roles this.roleOptions = response.roles;
this.open = true this.open = true;
this.title = '添加用户' this.title = "添加用户";
this.form.password = this.initPassword this.form.password = this.initPassword;
}) });
}, },
/** 修改按钮操作 */ /** 修改按钮操作 */
handleUpdate(row) { handleUpdate(row) {
this.reset() this.reset();
const userId = row.userId || this.ids const userId = row.userId || this.ids;
getUser(userId).then((response) => { getUser(userId).then((response) => {
this.form = response.data this.form = response.data;
this.postOptions = response.posts this.postOptions = response.posts;
this.roleOptions = response.roles this.roleOptions = response.roles;
this.$set(this.form, 'postIds', response.postIds) this.$set(this.form, "postIds", response.postIds);
this.$set(this.form, 'roleIds', response.roleIds) this.$set(this.form, "roleIds", response.roleIds);
this.open = true this.open = true;
this.title = '修改用户' this.title = "修改用户";
this.form.password = '' this.form.password = "";
}) });
}, },
/** 重置密码按钮操作 */ /** 重置密码按钮操作 */
handleResetPwd(row) { handleResetPwd(row) {
this.$prompt('请输入"' + row.userName + '"的新密码', '提示', { this.$prompt('请输入"' + row.userName + '"的新密码', "提示", {
confirmButtonText: '确定', confirmButtonText: "确定",
cancelButtonText: '取消', cancelButtonText: "取消",
closeOnClickModal: false, closeOnClickModal: false,
inputPattern: /^.{5,20}$/, inputPattern: /^.{5,20}$/,
inputErrorMessage: '用户密码长度必须介于 5 和 20 之间', inputErrorMessage: "用户密码长度必须介于 5 和 20 之间",
inputValidator: (value) => { inputValidator: (value) => {
if (/<|>|"|'|\||\\/.test(value)) { if (/<|>|"|'|\||\\/.test(value)) {
return '不能包含非法字符:< > " \' \\ |' return "不能包含非法字符:< > \" ' \\ |";
} }
}, },
}) })
.then(({ value }) => { .then(({ value }) => {
resetUserPwd(row.userId, value).then((response) => { resetUserPwd(row.userId, value).then((response) => {
this.$modal.msgSuccess('修改成功,新密码是:' + value) this.$modal.msgSuccess("修改成功,新密码是:" + value);
}) });
}) })
.catch(() => {}) .catch(() => {});
}, },
/** 分配角色操作 */ /** 分配角色操作 */
handleAuthRole: function (row) { handleAuthRole: function (row) {
const userId = row.userId const userId = row.userId;
this.$router.push('/system/user-auth/role/' + userId) this.$router.push("/system/user-auth/role/" + userId);
}, },
/** 提交按钮 */ /** 提交按钮 */
submitForm: function () { submitForm: function () {
this.$refs['form'].validate((valid) => { this.$refs["form"].validate((valid) => {
if (valid) { if (valid) {
if (this.form.userId != undefined) { if (this.form.userId != undefined) {
updateUser(this.form).then((response) => { updateUser(this.form).then((response) => {
this.$modal.msgSuccess('修改成功') this.$modal.msgSuccess("修改成功");
this.open = false this.open = false;
this.getList() this.getList();
}) });
} else { } else {
addUser(this.form).then((response) => { addUser(this.form).then((response) => {
this.$modal.msgSuccess('新增成功') this.$modal.msgSuccess("新增成功");
this.open = false this.open = false;
this.getList() this.getList();
}) });
} }
} }
}) });
}, },
/** 删除按钮操作 */ /** 删除按钮操作 */
handleDelete(row) { handleDelete(row) {
const userIds = row.userId || this.ids const userIds = row.userId || this.ids;
this.$modal this.$modal
.confirm('是否确认删除用户编号为"' + userIds + '"的数据项?') .confirm('是否确认删除用户编号为"' + userIds + '"的数据项?')
.then(function () { .then(function () {
return delUser(userIds) return delUser(userIds);
}) })
.then(() => { .then(() => {
this.getList() this.getList();
this.$modal.msgSuccess('删除成功') this.$modal.msgSuccess("删除成功");
}) })
.catch(() => {}) .catch(() => {});
}, },
/** 导出按钮操作 */ /** 导出按钮操作 */
handleExport() { handleExport() {
this.download( this.download(
'system/user/export', "system/user/export",
{ {
...this.queryParams, ...this.queryParams,
}, },
`user_${new Date().getTime()}.xlsx` `user_${new Date().getTime()}.xlsx`
) );
}, },
/** 导入按钮操作 */ /** 导入按钮操作 */
handleImport() { handleImport() {
this.upload.title = '用户导入' this.upload.title = "用户导入";
this.upload.open = true this.upload.open = true;
}, },
/** 下载模板操作 */ /** 下载模板操作 */
importTemplate() { importTemplate() {
this.download('system/user/importTemplate', {}, `user_template_${new Date().getTime()}.xlsx`) this.download(
"system/user/importTemplate",
{},
`user_template_${new Date().getTime()}.xlsx`
);
}, },
// 文件上传中处理 // 文件上传中处理
handleFileUploadProgress(event, file, fileList) { handleFileUploadProgress(event, file, fileList) {
this.upload.isUploading = true this.upload.isUploading = true;
}, },
// 文件上传成功处理 // 文件上传成功处理
handleFileSuccess(response, file, fileList) { handleFileSuccess(response, file, fileList) {
this.upload.open = false this.upload.open = false;
this.upload.isUploading = false this.upload.isUploading = false;
this.$refs.upload.clearFiles() this.$refs.upload.clearFiles();
this.$alert("<div style='overflow: auto;overflow-x: hidden;max-height: 70vh;padding: 10px 20px 0;'>" + response.msg + '</div>', '导入结果', { this.$alert(
"<div style='overflow: auto;overflow-x: hidden;max-height: 70vh;padding: 10px 20px 0;'>" +
response.msg +
"</div>",
"导入结果",
{
dangerouslyUseHTMLString: true, dangerouslyUseHTMLString: true,
}) }
this.getList() );
this.getList();
}, },
// 提交上传文件 // 提交上传文件
submitFileForm() { submitFileForm() {
this.$refs.upload.submit() this.$refs.upload.submit();
}, },
}, },
} };
</script> </script>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment